PageRenderTime 60ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/core/minishowcase/libraries/cpaint2.inc.php

http://zenekar.googlecode.com/
PHP | 741 lines | 260 code | 91 blank | 390 comment | 36 complexity | 6fd00b746ef6c716a9419448b9548623 MD5 | raw file
Possible License(s): LGPL-2.1
  1. <?php
  2. /**
  3. * CPAINT - Cross-Platform Asynchronous INterface Toolkit
  4. *
  5. * http://cpaint.sourceforge.net
  6. *
  7. * released under the terms of the LGPL
  8. * see http://www.fsf.org/licensing/licenses/lgpl.txt for details
  9. *
  10. * $Id$
  11. * $Log$
  12. * Revision 1.25 2005/08/17 17:48:00 wiley14
  13. * Changed comment about version number.
  14. *
  15. * Revision 1.24 2005/08/17 15:52:53 saloon12yrd
  16. * cleaner approach to ?api_query
  17. *
  18. * Revision 1.20 2005/08/08 15:20:18 wiley14
  19. * Added replacement character for greater than sign in cpaint_transformer
  20. *
  21. * Revision 1.9 2005/07/17 18:02:15 wiley14
  22. * Fixed problem in get_name function (diff to see changes)
  23. *
  24. * Revision 1.8 2005/07/17 17:31:23 wiley14
  25. * Fixed problem in set_name function (diff to see changes)
  26. *
  27. * Revision 1.7 2005/07/14 17:14:21 saloon12yrd
  28. * added support for arbitrary XML attributes
  29. *
  30. * Revision 1.3 2005/07/10 22:18:03 wiley14
  31. * Added id setter function for compatibility with ASP
  32. *
  33. * Revision 1.2 2005/07/10 00:49:30 wiley14
  34. * no message
  35. *
  36. * @package CPAINT
  37. * @author Paul Sullivan <wiley14@gmail.com>
  38. * @author Dominique Stender <dstender@st-webdevelopment.de>
  39. * @copyright Copyright (c) 2005 Paul Sullivan, Dominique Stender - http://cpaint.sourceforge.net
  40. */
  41. /**
  42. * cpaint base class.
  43. *
  44. * @package CPAINT
  45. * @access public
  46. * @author Paul Sullivan <wiley14@gmail.com>
  47. * @author Dominique Stender <dstender@st-webdevelopment.de>
  48. * @copyright Copyright (c) 2005 Paul Sullivan, Dominique Stender - http://cpaint.sourceforge.net
  49. * @version 2.0.0
  50. */
  51. class cpaint {
  52. /**
  53. * version number
  54. *
  55. * @access private
  56. * @var string $version
  57. */
  58. var $version = '2.0.0';
  59. /**
  60. * response type.
  61. *
  62. * @access protected
  63. * @var string $response_type
  64. */
  65. var $response_type;
  66. /**
  67. * the basenode ajaxResponse.
  68. *
  69. * @access protected
  70. * @var object $basenode
  71. */
  72. var $basenode;
  73. /**
  74. * list of registered methods available through the CPAINT API
  75. *
  76. * @access protected
  77. * @var array $api_functions
  78. */
  79. var $api_functions;
  80. /**
  81. * PHP4 constructor.
  82. *
  83. * @access public
  84. * @return void
  85. */
  86. function cpaint() {
  87. $this->__construct();
  88. }
  89. /**
  90. * PHP 5 constructor.
  91. *
  92. * @access public
  93. * @return void
  94. */
  95. function __construct() {
  96. // initialize properties
  97. $this->basenode = new cpaint_node();
  98. $this->basenode->set_name('ajaxResponse');
  99. $this->basenode->set_attribute('id', '');
  100. $this->basenode->set_encoding('UTF-8');
  101. $this->response_type = 'TEXT';
  102. $this->api_functions = array();
  103. // open output buffer so no output is sent back to the client
  104. ob_start();
  105. // determine response type
  106. if (isset($_GET['cpaint_response_type'])) {
  107. $this->response_type = (string) $_GET['cpaint_response_type'];
  108. } elseif (isset($_POST['cpaint_response_type'])) {
  109. $this->response_type = (string) $_POST['cpaint_response_type'];
  110. }
  111. }
  112. /**
  113. * calls the user function responsible for this specific call.
  114. *
  115. * @access public
  116. * @param string $input_encoding input data character encoding, default is UTF-8
  117. * @return void
  118. */
  119. function start($input_encoding = 'UTF-8') {
  120. $user_function = '';
  121. $arguments = array();
  122. // work only if there is no API version request
  123. if (!isset($_GET['api_query']) && !isset($_POST['api_query'])) {
  124. $this->basenode->set_encoding($input_encoding);
  125. if ($_GET['cpaint_function'] != '') {
  126. $user_function = $_GET['cpaint_function'];
  127. $arguments = $_GET['cpaint_argument'];
  128. } elseif ($_POST['cpaint_function'] != '') {
  129. $user_function = $_POST['cpaint_function'];
  130. $arguments = $_POST['cpaint_argument'];
  131. }
  132. // perform character conversion on every argument
  133. $arguments = cpaint_transformer::decode_array($arguments, $this->basenode->get_encoding());
  134. if (function_exists($user_function)
  135. && is_array($this->api_functions[$user_function])) {
  136. // a valid API function is to be called
  137. call_user_func_array($this->api_functions[$user_function]['call'], $arguments);
  138. } else {
  139. // desired function is not registered as API function
  140. // @todo -o"Dominique Stender" -ccpaint implement a better debugging
  141. $this->basenode->set_data('A function name was passed that is not allowed to execute on this server.');
  142. }
  143. } // end: if
  144. }
  145. /**
  146. * generates and prints the response based on response type supplied by the frontend.
  147. *
  148. * @access public
  149. * @return void
  150. */
  151. function return_data() {
  152. // delete output buffer
  153. ob_end_clean();
  154. // send appropriate headers to avoid caching
  155. header ('Expires: Fri, 14 Mar 1980 20:53:00 GMT');
  156. header ('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT');
  157. header ('Cache-Control: no-cache, must-revalidate');
  158. header ('Pragma: no-cache');
  159. // work only if there is no API version request
  160. if (!isset($_GET['api_query']) && !isset($_POST['api_query'])) {
  161. // trigger generation of response
  162. switch (trim(strtoupper($this->response_type))) {
  163. case 'TEXT':
  164. header('Content-type: text/plain; charset=' . cpaint_transformer::find_output_charset($this->basenode->get_encoding()));
  165. echo cpaint_transformer::toString($this->basenode);
  166. break;
  167. case 'OBJECT':
  168. case 'XML':
  169. header('Content-type: text/xml; charset=' . cpaint_transformer::find_output_charset($this->basenode->get_encoding()));
  170. echo '<?xml version="1.0" encoding="' . cpaint_transformer::find_output_charset($this->basenode->get_encoding()) . '"?>'
  171. . cpaint_transformer::toXML($this->basenode);
  172. break;
  173. default:
  174. echo 'ERROR: invalid response type \'' . $this->response_type . '\'';
  175. } // end: switch
  176. } else {
  177. // API version request
  178. header('Content-type: text/plain; charset=ISO-8859-1');
  179. echo 'CPAINT v' . $this->version . '/PHP v' . phpversion();
  180. } // end: if
  181. }
  182. /**
  183. * registers a new function or method as part of the CPAINT API
  184. *
  185. * @access public
  186. * @param mixed $func function name or array(&$object, 'function_name')
  187. * @param array $input function input parameters (not yet used by CPAINT and subject to change)
  188. * @param array $output function output format (not yed used by CPAINT and subject to change)
  189. * @return boolean
  190. */
  191. function register($func, $input = array(), $output = array()) {
  192. $return_value = false;
  193. $input = (array) $input;
  194. $output = (array) $output;
  195. if (is_array($func)
  196. && is_object($func[0])
  197. && is_string($func[1])
  198. && method_exists($func[0], $func[1])) {
  199. // calling a method of an object
  200. $this->api_functions[$func[1]] = array(
  201. 'call' => $func,
  202. 'input' => $input,
  203. 'output' => $output,
  204. );
  205. $return_value = true;
  206. } elseif (is_string($func)) {
  207. // calling a standalone function
  208. $this->api_functions[$func] = array(
  209. 'call' => $func,
  210. 'input' => $input,
  211. 'output' => $output,
  212. );
  213. $return_value = true;
  214. } // end: if
  215. return $return_value;
  216. }
  217. /**
  218. * adds a new subnode to the basenode.
  219. *
  220. * will return a reference to it for further processing.
  221. *
  222. * @access public
  223. * @param string $nodename name of the new node
  224. * @param string $id id of the new node
  225. * @return object
  226. */
  227. function &add_node($nodename, $id = '') {
  228. return $this->basenode->add_node($nodename, $id);
  229. }
  230. /**
  231. * assigns textual data to the basenode.
  232. *
  233. * @access public
  234. * @param string $data data to assign to this node
  235. * @return void
  236. */
  237. function set_data($data) {
  238. $this->basenode->set_data($data);
  239. }
  240. /**
  241. * returns the data assigned to the basenode.
  242. *
  243. * @access public
  244. * @return string
  245. */
  246. function get_data() {
  247. return $this->basenode->get_data();
  248. }
  249. /**
  250. * sets the id property of the basenode.
  251. *
  252. * @deprecated deprecated since version 2.0.0
  253. * @access public
  254. * @param string $id the id
  255. * @return void
  256. */
  257. function set_id($id) {
  258. $this->basenode->set_attribute('id', $id);
  259. }
  260. /**
  261. * gets the id property of the basenode.
  262. *
  263. * @deprecated deprecated since version 2.0.0
  264. * @access public
  265. * @return string
  266. */
  267. function get_id() {
  268. return $this->basenode->get_attribute('id');
  269. }
  270. /**
  271. * adds a new attribute to the basenode.
  272. *
  273. * @access public
  274. * @param string $name attribute name
  275. * @param mixed $value attribute value
  276. * @return void
  277. */
  278. function set_attribute($name, $value) {
  279. $this->basenode->set_attribute($name, $value);
  280. }
  281. /**
  282. * retrieves an attribute of the basenode by name.
  283. *
  284. * @access public
  285. * @param string $name attribute name
  286. * @return string
  287. */
  288. function get_attribute($name) {
  289. return $this->basenode->get_attributes($name);
  290. }
  291. /**
  292. * set name property of the basenode.
  293. *
  294. * @access public
  295. * @param string $name the name
  296. * @return void
  297. */
  298. function set_name($name) {
  299. $this->basenode->set_name($name);
  300. }
  301. /**
  302. * get name property of the basenode.
  303. *
  304. * @access public
  305. * @return string
  306. */
  307. function get_name() {
  308. return $this->basenode->get_name();
  309. }
  310. }
  311. /**
  312. * a cpaint data node. Data nodes are used to build up the response.
  313. *
  314. * @package CPAINT
  315. * @access public
  316. * @author Dominique Stender <dstender@st-webdevelopment.de>
  317. * @copyright 2005 (Dominique Stender); All rights reserved
  318. * @version 2.0.0
  319. */
  320. class cpaint_node {
  321. /**
  322. * array of subnodes.
  323. *
  324. * @access public
  325. * @var array $composites
  326. */
  327. var $composites;
  328. /**
  329. * node attributes.
  330. *
  331. * @access public
  332. * @var array $attributes
  333. */
  334. var $attributes;
  335. /**
  336. * name of this node.
  337. *
  338. * @access public
  339. * @var string $nodename
  340. */
  341. var $nodename;
  342. /**
  343. * textual data of this node.
  344. *
  345. * @access public
  346. * @var string $data
  347. */
  348. var $data;
  349. /**
  350. * character encoding for input data
  351. *
  352. * @access private
  353. * @var $input_encoding
  354. */
  355. var $input_encoding;
  356. /**
  357. * PHP4 constructor.
  358. *
  359. * @package CPAINT
  360. * @access public
  361. * @return void
  362. */
  363. function cpaint_node() {
  364. $this->__construct();
  365. }
  366. /**
  367. * PHP 5 constructor.
  368. *
  369. * @access public
  370. * @return void
  371. */
  372. function __construct() {
  373. // initialize properties
  374. $this->composites = array();
  375. $this->attributes = array();
  376. $this->data = '';
  377. $this->set_encoding('UTF-8');
  378. $this->set_name('');
  379. $this->set_attribute('id', '');
  380. }
  381. /**
  382. * adds a new subnode to this node.
  383. *
  384. * will return a reference to it for further processing.
  385. *
  386. * @access public
  387. * @param string $nodename name of the new node
  388. * @param string $id id of the new node
  389. * @return object
  390. */
  391. function &add_node($nodename, $id = '') {
  392. $composites = count($this->composites);
  393. // create new node
  394. $this->composites[$composites] =& new cpaint_node();
  395. $this->composites[$composites]->set_name($nodename);
  396. $this->composites[$composites]->set_attribute('id', $id);
  397. $this->composites[$composites]->set_encoding($this->input_encoding);
  398. return $this->composites[$composites];
  399. }
  400. /**
  401. * assigns textual data to this node.
  402. *
  403. * @access public
  404. * @param string $data data to assign to this node
  405. * @return void
  406. */
  407. function set_data($data) {
  408. $this->data = (string) $data;
  409. }
  410. /**
  411. * returns the textual data assigned to this node.
  412. *
  413. * @access public
  414. * @return string
  415. */
  416. function get_data() {
  417. return $this->data;
  418. }
  419. /**
  420. * sets the id property of this node.
  421. *
  422. * @deprecated deprecated since version 2.0.0
  423. * @access public
  424. * @param string id the id
  425. * @return void
  426. */
  427. function set_id($id) {
  428. if ($id != '') {
  429. $this->set_attribute('id', $id);
  430. } // end: if
  431. }
  432. /**
  433. * returns the id property if this node.
  434. *
  435. * @deprecated deprecated since version 2.0.0
  436. * @access public
  437. * @return string
  438. */
  439. function get_id() {
  440. return $this->get_attribute('id');
  441. }
  442. /**
  443. * adds a new attribute to this node.
  444. *
  445. * @access public
  446. * @param string $name attribute name
  447. * @param mixed $value attribute value
  448. * @return void
  449. */
  450. function set_attribute($name, $value) {
  451. $this->attributes[$name] = (string) $value;
  452. }
  453. /**
  454. * retrieves an attribute by name.
  455. *
  456. * @access public
  457. * @param string $name attribute name
  458. * @return string
  459. */
  460. function get_attribute($name) {
  461. return $this->attributes[$name];
  462. }
  463. /**
  464. * set name property.
  465. *
  466. * @access public
  467. * @param string $name the name
  468. * @return void
  469. */
  470. function set_name($name) {
  471. $this->nodename = (string) $name;
  472. }
  473. /**
  474. * get name property.
  475. *
  476. * @access public
  477. * @return string
  478. */
  479. function get_name() {
  480. return $this->nodename;
  481. }
  482. /**
  483. * sets the character encoding for this node
  484. *
  485. * @access public
  486. * @param string $encoding character encoding
  487. * @return void
  488. */
  489. function set_encoding($encoding) {
  490. $this->input_encoding = strtoupper((string) $encoding);
  491. }
  492. /**
  493. * returns the character encoding for this node
  494. *
  495. * @access public
  496. * @return string
  497. */
  498. function get_encoding() {
  499. return $this->input_encoding;
  500. }
  501. }
  502. /**
  503. * static class of output transformers.
  504. *
  505. * @package CPAINT
  506. * @access public
  507. * @author Dominique Stender <dstender@st-webdevelopment.de>
  508. * @copyright 2002-2005 (Dominique Stender); All rights reserved
  509. * @version 2.0.0
  510. */
  511. class cpaint_transformer {
  512. /**
  513. * toString method, used to generate response of type TEXT.
  514. * will perform character transformation according to parameters.
  515. *
  516. * @access public
  517. * @param object $node a cpaint_node object
  518. * @return string
  519. */
  520. function toString(&$node) {
  521. $return_value = '';
  522. foreach ($node->composites as $composite) {
  523. $return_value .= cpaint_transformer::toString($composite);
  524. }
  525. $return_value .= cpaint_transformer::encode($node->get_data(), $node->get_encoding());
  526. return $return_value;
  527. }
  528. /**
  529. * XML response generator.
  530. * will perform character transformation according to parameters.
  531. *
  532. * @access public
  533. * @param object $node a cpaint_node object
  534. * @return string
  535. */
  536. function toXML(&$node) {
  537. $return_value = '<' . cpaint_transformer::encode($node->get_name(), $node->get_encoding());
  538. // handle attributes
  539. foreach ($node->attributes as $name => $value) {
  540. if ($value != '') {
  541. $return_value .= ' '
  542. . cpaint_transformer::encode($name, $node->get_encoding())
  543. . '="'
  544. . cpaint_transformer::encode($node->get_attribute($name), $node->get_encoding())
  545. . '"';
  546. }
  547. } // end: foreach
  548. $return_value .= '>';
  549. foreach ($node->composites as $composite) {
  550. $return_value .= cpaint_transformer::toXML($composite);
  551. }
  552. $return_value .= cpaint_transformer::encode($node->get_data(), $node->get_encoding())
  553. . '</'
  554. . cpaint_transformer::encode($node->get_name(), $node->get_encoding())
  555. . '>';
  556. return $return_value;
  557. }
  558. /**
  559. * performs conversion to JavaScript-safe UTF-8 characters
  560. *
  561. * @access public
  562. * @param string $data data to convert
  563. * @param string $encoding character encoding
  564. * @return string
  565. */
  566. function encode($data, $encoding) {
  567. // convert string
  568. if (function_exists('iconv')) {
  569. // iconv is by far the most flexible approach, try this first
  570. $return_value = iconv($encoding, 'UTF-8', $data);
  571. } elseif ($encoding == 'ISO-8859-1') {
  572. // for ISO-8859-1 we can use utf8-encode()
  573. $return_value = utf8_encode($data);
  574. } else {
  575. // give up. if UTF-8 data was supplied everything is fine!
  576. $return_value = $data;
  577. } /* end: if */
  578. // now encode non-printable characters
  579. for ($i = 0; $i < 32; $i++) {
  580. $return_value = str_replace(chr($i), '\u00' . sprintf('%02x', $i), $return_value);
  581. } // end: for
  582. // encode <, >, and & respectively for XML sanity
  583. $return_value = str_replace(chr(0x26), '\u0026', $return_value);
  584. $return_value = str_replace(chr(0x3c), '\u003c', $return_value);
  585. $return_value = str_replace(chr(0x3e), '\u003e', $return_value);
  586. return $return_value;
  587. }
  588. /**
  589. * performs conversion from JavaScript encodeURIComponent() string (UTF-8) to
  590. * the charset in use.
  591. *
  592. * @access public
  593. * @param string $data data to convert
  594. * @param string $encoding character encoding
  595. * @return string
  596. */
  597. function decode($data, $encoding) {
  598. // convert string
  599. if (function_exists('iconv')) {
  600. // iconv is by far the most flexible approach, try this first
  601. $return_value = iconv('UTF-8', $encoding, $data);
  602. } elseif ($encoding == 'ISO-8859-1') {
  603. // for ISO-8859-1 we can use utf8-decode()
  604. $return_value = utf8_decode($data);
  605. } else {
  606. // give up. if data was supplied in the correct format everything is fine!
  607. $return_value = $data;
  608. } /* end: if */
  609. return $return_value;
  610. }
  611. /**
  612. * decodes a (nested) array of data from UTF-8 into the configured character set
  613. *
  614. * @access public
  615. * @param array $data data to convert
  616. * @param string $encoding character encoding
  617. * @return array
  618. */
  619. function decode_array($data, $encoding) {
  620. $return_value = array();
  621. foreach ($data as $key => $value) {
  622. if (!is_array($value)) {
  623. $return_value[$key] = cpaint_transformer::decode($value, $encoding);
  624. } else {
  625. $return_value[$key] = cpaint_transformer::decode_array($value, $encoding);
  626. }
  627. }
  628. return $return_value;
  629. }
  630. /**
  631. * determines the output character set
  632. * based on input character set
  633. *
  634. * @access public
  635. * @param string $encoding character encoding
  636. * @return string
  637. */
  638. function find_output_charset($encoding) {
  639. $return_value = 'UTF-8';
  640. if (function_exists('iconv')
  641. || $encoding == 'UTF-8'
  642. || $encoding == 'ISO-8859-1') {
  643. $return_value = 'UTF-8';
  644. } else {
  645. $return_value = $encoding;
  646. } /* end: if */
  647. return $return_value;
  648. }
  649. }
  650. ?>