CPAINT
[ class tree: CPAINT ] [ index: CPAINT ] [ all elements ]

Source for file cpaint2.inc.php

Documentation is available at cpaint2.inc.php

  1. <?
  2. /**
  3.  * CPAINT - Cross-Platform Asynchronous INterface Toolkit
  4.  *
  5.  * http://sf.net/projects/cpaint
  6.  *
  7.  * released under the terms of the LGPL
  8.  * see http://www.fsf.org/licensing/licenses/lgpl.txt for details
  9.  *
  10.  * @package    CPAINT
  11.  * @author     Paul Sullivan <wiley14@gmail.com>
  12.  * @author     Dominique Stender <dstender@st-webdevelopment.de>
  13.  * @copyright  Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint
  14.  * @version    $Id: cpaint2.inc.php 311 2006-09-30 08:21:25Z saloon12yrd $
  15.  */
  16.  
  17. //---- includes ----------------------------------------------------------------
  18. /**
  19.  * @include JSON
  20.  */
  21. require_once(dirname(__FILE__'/json.php');
  22.  
  23. //---- variables ---------------------------------------------------------------
  24. $GLOBALS['__cpaint_json'new JSON();
  25.  
  26. //---- error reporting ---------------------------------------------------------
  27. error_reporting(E_ALL E_NOTICE E_WARNING);
  28.  
  29. //---- classes -----------------------------------------------------------------
  30. /**
  31.  * cpaint base class.
  32.  *
  33.  * @package    CPAINT
  34.  * @access     public
  35.  * @author     Paul Sullivan <wiley14@gmail.com>
  36.  * @author     Dominique Stender <dstender@st-webdevelopment.de>
  37.  * @copyright  Copyright (c) 2005-2006 Paul Sullivan, Dominique Stender - http://sf.net/projects/cpaint
  38.  * @version    2.1.0
  39.  */
  40. class cpaint {
  41.     /**
  42.      * version number
  43.      *
  44.      * @access private
  45.      * @var    string $version 
  46.      */
  47.     var $version '2.1.0';
  48.  
  49.     /**
  50.      * response type.
  51.      *
  52.      * @access   protected
  53.      * @var      string    $response_type 
  54.      */
  55.     var $response_type;
  56.  
  57.     /**
  58.      * the basenode ajaxResponse.
  59.      *
  60.      * @access   protected
  61.      * @var      object    $basenode 
  62.      */
  63.     var $basenode;
  64.  
  65.     /**
  66.      * list of registered methods available through the CPAINT API
  67.      *
  68.      * @access   protected
  69.      * @var      array     $api_functions 
  70.      */
  71.     var $api_functions;
  72.  
  73.     /**
  74.      * list of registered complex types used in the CPAINT API
  75.      *
  76.      * @access protected
  77.      * @var    array $api_datatypes 
  78.      */
  79.     var $api_datatypes;
  80.  
  81.     /**
  82.      * whether or not the CPAINT API generates a WSDL when called with ?wsdl querystring
  83.      *
  84.      * @access private
  85.      * @var    boolean $use_wsdl 
  86.      */
  87.     var $use_wsdl;
  88.  
  89.     /**
  90.      * PHP4 constructor.
  91.      *
  92.      * @access   public
  93.      * @return   void 
  94.      */
  95.     function cpaint({
  96.         $this->__construct();
  97.     }
  98.  
  99.     /**
  100.      * PHP 5 constructor.
  101.      *
  102.      * @access   public
  103.      * @return   void 
  104.      * @todo -o"Dominique Stender" -ccpaint implement a better debugging
  105.      */
  106.     function __construct({
  107.         // initialize properties
  108.         $this->basenode       = new cpaint_node();
  109.         $this->basenode->set_name('ajaxResponse');
  110.         $this->basenode->set_attribute('id''');
  111.         $this->basenode->set_encoding('UTF-8');
  112.  
  113.         $this->response_type  = 'TEXT';
  114.         $this->api_functions  = array();
  115.         $this->api_datatypes  = array();
  116.       /* $this->use_wsdl       = true;
  117.  
  118.       $this->complex_type(array(
  119.           'name'      => 'cpaintResponseType',
  120.           'type'      => 'restriction',   // (restriction|complex|list)
  121.           'base_type' => 'string',        // scalar type of all values, e.g. 'string', for type = (restriction|list) only
  122.           'values'    => array(           // for type = 'restriction' only: list of allowed values
  123.             'XML', 'TEXT', 'OBJECT', 'E4X', 'JSON',
  124.           ),
  125.         )
  126.       );
  127.       $this->complex_type(array(
  128.           'name'      => 'cpaintDebugLevel',
  129.           'type'      => 'restriction',
  130.           'base_type' => 'long',
  131.           'values'    => array(
  132.             -1, 0, 1, 2
  133.           ),
  134.         )
  135.       );
  136.       $this->complex_type(array(
  137.           'name'      => 'cpaintDebugMessage',
  138.           'type'      => 'list',
  139.           'base_type' => 'string',
  140.         )
  141.       );
  142.  
  143.       $this->complex_type(array(
  144.           'name'      => 'cpaintRequestHead',
  145.           'type'      => 'complex',
  146.           'struct'    => array(
  147.             0 => array('name' => 'functionName',  'type' => 'string'),
  148.             1 => array('name' => 'responseType',  'type' => 'cpaintResponseType'),
  149.             2 => array('name' => 'debugLevel',    'type' => 'cpaintDebugLevel'),
  150.           ),
  151.         )
  152.       );
  153.  
  154.       // $this->complex_type(array(
  155.           'name'      => 'cpaintResponseHead',
  156.           'type'      => 'complex',
  157.           'struct'    => array(
  158.             0 => array('name' => 'success',  'type' => 'boolean'),
  159.             1 => array('name' => 'debugger', 'type' => 'cpaintDebugMessage'),
  160.           ),
  161.         )
  162.       );
  163.       */
  164.         // determine response type
  165.         if (isset($_REQUEST['cpaint_response_type'])) {
  166.             $this->response_type = htmlentities(strip_tags(strtoupper((string) $_REQUEST['cpaint_response_type'])));
  167.         // end: if
  168.     }
  169.  
  170.     /**
  171.      * calls the user function responsible for this specific call.
  172.      *
  173.      * @access   public
  174.      * @param    string      $input_encoding         input data character encoding, default is UTF-8
  175.      * @return   void 
  176.      */
  177.     function start($input_encoding 'UTF-8'{
  178.         $user_function  '';
  179.         $arguments      array();
  180.  
  181.         // work only if there is no API version request
  182.         if (!isset($_REQUEST['api_query'])
  183.             && !isset($_REQUEST['wsdl'])) {
  184.             $this->basenode->set_encoding($input_encoding);
  185.  
  186.             if ($_REQUEST['cpaint_function'!= ''{
  187.                 $user_function  $_REQUEST['cpaint_function'];
  188.                 if (isset($_REQUEST['cpaint_argument'])) {
  189.                     $arguments      $_REQUEST['cpaint_argument'];
  190.                 }
  191.             }
  192.  
  193.             // perform character conversion on every argument
  194.             foreach ($arguments as $key => $value{
  195.                 if (get_magic_quotes_gpc(== true{
  196.                     $value stripslashes($value);
  197.                 // end: if
  198.  
  199.                 // convert from JSON string if it is an object or an array
  200.                 if (preg_match('/^(\[|\{).*(\]|\})$/'$value)) {
  201.                     $arguments[$key$GLOBALS['__cpaint_json']->parse($value);
  202.                 // end: if
  203.             // end: foreach
  204.  
  205.             $arguments cpaint_transformer::decode_array($arguments$this->basenode->get_encoding());
  206.  
  207.             if (is_array($this->api_functions[$user_function])
  208.                 && is_callable($this->api_functions[$user_function]['call'])) {
  209.             // a valid API function is to be called
  210.                 call_user_func_array($this->api_functions[$user_function]['call']$arguments);
  211.  
  212.             else if ($user_function != ''{
  213.                 // desired function is not registered as API function
  214.                     $this->basenode->set_data('[CPAINT] A function name was passed that is not allowed to execute on this server.');
  215.                 }
  216.         // end: if
  217.     }
  218.  
  219.     /**
  220.      * generates and prints the response based on response type supplied by the frontend.
  221.      *
  222.      * @access  public
  223.      * @return  void 
  224.      */
  225.     function return_data({
  226.     // send appropriate headers to avoid caching
  227.         header('Expires: Fri, 14 Mar 1980 20:53:00 GMT');
  228.         header('Last-Modified: ' gmdate('D, d M Y H:i:s'' GMT');
  229.         header('Cache-Control: no-cache, must-revalidate');
  230.         header('Pragma: no-cache');
  231.         header('X-Powered-By: CPAINT v' $this->version '/PHP v' phpversion());
  232.  
  233.         // work only if there is no API version request
  234.  
  235.         if (!isset($_REQUEST['api_query'])
  236.         /* && !isset($_REQUEST['wsdl']) */{
  237.         // trigger generation of response
  238.             switch (trim($this->response_type)) {
  239.  
  240.                 case 'TEXT':
  241.                     header('Content-type: text/plain; charset=' cpaint_transformer::find_output_charset($this->basenode->get_encoding()));
  242.                     echo cpaint_transformer::toString($this->basenode);
  243.                     break;
  244.  
  245.                 case 'JSON':
  246.                     header('Content-type: text/plain; charset=' cpaint_transformer::find_output_charset($this->basenode->get_encoding()));
  247.                     echo cpaint_transformer::toJSON($this->basenode);
  248.                     break;
  249.  
  250.                 case 'OBJECT':
  251.                 case 'E4X':
  252.                 case 'XML':
  253.                     header('Content-type:  text/xml; charset=' cpaint_transformer::find_output_charset($this->basenode->get_encoding()));
  254.                     echo '<?xml version="1.0" encoding="' cpaint_transformer::find_output_charset($this->basenode->get_encoding()) '"?>'
  255.                         . cpaint_transformer::toXML($this->basenode);
  256.                     break;
  257.  
  258.                 default:
  259.                     echo 'ERROR: invalid response type \'' $this->response_type . '\'';
  260.             // end: switch
  261.  
  262.         elseif (isset($_REQUEST['api_query'])) {
  263.         // API version request
  264.             header('Content-type: text/plain; charset=ISO-8859-1');
  265.             echo 'CPAINT v' $this->version '/PHP v' phpversion();
  266. /*
  267.       } elseif ($this->use_wsdl == true
  268.         && isset($_REQUEST['wsdl'])) {
  269.  
  270.         if (is_file(dirname(__FILE__) . '/cpaint2.wsdl.php')
  271.           && is_readable(dirname(__FILE__) . '/cpaint2.wsdl.php')) {
  272.  
  273.           require_once(dirname(__FILE__) . '/cpaint2.wsdl.php');
  274.  
  275.           if (class_exists('cpaint_wsdl')) {
  276.             // create new instance of WSDL library
  277.             $wsdl = new cpaint_wsdl();
  278.  
  279.             // build WSDL info
  280.             header('Content-type: text/xml; charset=UTF-8');
  281.             echo $wsdl->generate($this->api_functions, $this->api_datatypes);
  282.  
  283.           } else {
  284.             header('Content-type: text/plain; charset=ISO-8859-1');
  285.             echo 'WSDL generator is unavailable';
  286.           } // end: if
  287.  
  288.         } else {
  289.           header('Content-type: text/plain; charset=ISO-8859-1');
  290.           echo 'WSDL generator is unavailable';
  291.         } // end: if
  292. */
  293.         // end: if
  294.     }
  295.  
  296.     /**
  297.      * registers a new function or method as part of the CPAINT API
  298.      *
  299.      * @access     public
  300.      * @param      mixed     $func     function name, array(&$object, 'function_name') or array('class', 'function_name')
  301.      * @param      string    $alias    alias name for the function. Will be used by the frontend.
  302.      * @param      array     $input    function input parameters (not yet used by CPAINT and subject to change)
  303.      * @param      array     $output   function output format (not yed used by CPAINT and subject to change)
  304.      * @param      string    $comment  description of the functionality
  305.      * @return     boolean 
  306.      * @version    1.0.1     16.09.2006 23:07:44    [dstender]  Added alias functionality.
  307.      */
  308.     function register($func$alias ''$input array()$output array()$comment ''{
  309.         $return_value false;
  310.         $alias        = (string)  $alias;
  311.         $input        = (array)   $input;
  312.         $output       = (array)   $output;
  313.         $comment      = (string)  $comment;
  314.         $callable     '';
  315.  
  316.         if (is_array($func)
  317.             && (is_object($func[0]|| is_string($func[0]))
  318.             && is_string($func[1])
  319.             && is_callable($func)) {
  320.  
  321.         // set correct function name if alias is used.
  322.             if ($alias != ''{
  323.                 $callable $alias;
  324.  
  325.             else {
  326.                 $callable $func[1];
  327.             // end: if
  328.  
  329.             // calling a method of an object
  330.             $this->api_functions[$callablearray(
  331.                 'call'    => $func,
  332.                 'input'   => $input,
  333.                 'output'  => $output,
  334.                 'comment' => $comment,
  335.             );
  336.             $return_value true;
  337.  
  338.         elseif (is_string($func)) {
  339.  
  340.         // set correct function name if alias is used.
  341.             if ($alias != ''{
  342.                 $callable $alias;
  343.  
  344.             else {
  345.                 $callable $func;
  346.             // end: if
  347.  
  348.             // calling a standalone function
  349.             $this->api_functions[$callablearray(
  350.                 'call'    => $func,
  351.                 'input'   => $input,
  352.                 'output'  => $output,
  353.                 'comment' => $comment,
  354.             );
  355.             $return_value true;
  356.         // end: if
  357.  
  358.         return $return_value;
  359.     }
  360.  
  361.  
  362.  
  363.     /**
  364.      * unregisters a function that is currently part of the CPAINT API.
  365.      *
  366.      * proves useful when the same set of functions is to be used in the
  367.      * frontend and in some kind of administration environment. you might
  368.      * want to unregister a few (admin) functions for the frontend in this
  369.      * case.
  370.      *
  371.      * Note that if you supplied an alias when registering a method, you must
  372.      * use the alias to unregister the function / method.
  373.      *
  374.      * @access     public
  375.      * @param      string     $func     function name
  376.      * @return     boolean 
  377.      * @see        cpaint:register()
  378.      * @version    1.0.1    16.09.2006 23:10:58    [dstender]  Extended PHPDoc for use of aliases.
  379.      */
  380.     function unregister($func{
  381.         $retval false;
  382.  
  383.         if (is_array($this->api_functions[$func])) {
  384.             unset($this->api_functions[$func]);
  385.         // end: if
  386.  
  387.         return $retval;
  388.     }
  389.  
  390.  
  391.  
  392.     /**
  393.      * registers a complex data type
  394.      *
  395.      * @access public
  396.      * @param  array     $schema     schema definition for the complex type
  397.      * @return boolean 
  398.  
  399.      function complex_type($schema) {
  400.      $return_value = false;
  401.      $schema       = (array)   $schema;
  402.  
  403.      if ($schema['name'] != ''
  404.      && in_array($schema['type'], array('restriction', 'complex', 'list'))) {
  405.  
  406.      $this->api_datatypes[] = $schema;
  407.      $return_value          = true;
  408.      } // end: if
  409.  
  410.      return $return_value;
  411.      }
  412.      */
  413.     /**
  414.      * switches the generation of WSDL on/off. default is on
  415.      *
  416.      * @access public
  417.      * @param  boolean   $state      state of WSDL generation
  418.      * @return void 
  419.  
  420.      function use_wsdl($state) {
  421.      $this->use_wsdl = (boolean) $state;
  422.      }
  423.      */
  424.     /**
  425.      * adds a new subnode to the basenode.
  426.      *
  427.      * will return a reference to it for further processing.
  428.      *
  429.      * @access   public
  430.      * @param    string    $nodename     name of the new node
  431.      * @param    string    $id           id of the new node
  432.      * @return   object 
  433.      */
  434.     function &add_node($nodename$id ''{
  435.         return $this->basenode->add_node($nodename$id);
  436.     }
  437.  
  438.     /**
  439.      * assigns textual data to the basenode.
  440.      *
  441.      * @access   public
  442.      * @param    mixed    $data    data to assign to this node
  443.      * @return   void 
  444.      */
  445.     function set_data($data{
  446.         $this->basenode->set_data($data);
  447.     }
  448.  
  449.     /**
  450.      * returns the data assigned to the basenode.
  451.      *
  452.      * @access   public
  453.      * @return   mixed 
  454.      */
  455.     function get_data({
  456.         return $this->basenode->get_data();
  457.     }
  458.  
  459.     /**
  460.      * sets the id property of the basenode.
  461.      *
  462.      * @deprecated   deprecated since version 2.0.0
  463.      * @access       public
  464.      * @param        string    $id      the id
  465.      * @return       void 
  466.      */
  467.     function set_id($id{
  468.         $this->basenode->set_attribute('id'$id);
  469.     }
  470.  
  471.     /**
  472.      * gets the id property of the basenode.
  473.      *
  474.      * @deprecated   deprecated since version 2.0.0
  475.      * @access       public
  476.      * @return       string 
  477.      */
  478.     function get_id({
  479.         return $this->basenode->get_attribute('id');
  480.     }
  481.  
  482.     /**
  483.      * adds a new attribute to the basenode.
  484.      *
  485.      * @access   public
  486.      * @param    string    $name       attribute name
  487.      * @param    mixed     $value      attribute value
  488.      * @return   void 
  489.      */
  490.     function set_attribute($name$value{
  491.         $this->basenode->set_attribute($name$value);
  492.     }
  493.  
  494.     /**
  495.      * retrieves an attribute of the basenode by name.
  496.      *
  497.      * @access   public
  498.      * @param    string    $name       attribute name
  499.      * @return   string 
  500.      */
  501.     function get_attribute($name{
  502.         return $this->basenode->get_attributes($name);
  503.     }
  504.  
  505.     /**
  506.      * set name property of the basenode.
  507.      *
  508.      * @access   public
  509.      * @param    string    $name   the name
  510.      * @return   void 
  511.      */
  512.     function set_name($name{
  513.         $this->basenode->set_name($name);
  514.     }
  515.  
  516.     /**
  517.      * get name property of the basenode.
  518.      *
  519.      * @access   public
  520.      * @return   string 
  521.      */
  522.     function get_name({
  523.         return $this->basenode->get_name();
  524.     }
  525.  
  526.  
  527.  
  528.     /**
  529.      * returns the response type as requested by the client
  530.      *
  531.      * @access public
  532.      * @return string 
  533.      */
  534.     function get_response_type({
  535.         return $this->response_type;
  536.     }
  537.  
  538. }
  539.  
  540. /**
  541.  * a cpaint data node. Data nodes are used to build up the response.
  542.  *
  543.  * @package   CPAINT
  544.  * @access    public
  545.  * @author    Dominique Stender <dstender@st-webdevelopment.de>
  546.  * @copyright 2005-2006 (Dominique Stender); All rights reserved
  547.  * @version   2.1.0
  548.  */
  549. class cpaint_node {
  550. /**
  551.  * array of subnodes.
  552.  *
  553.  * @access   public
  554.  * @var      array     $composites 
  555.  */
  556.     var $composites;
  557.  
  558.     /**
  559.      * node attributes.
  560.      *
  561.      * @access   public
  562.      * @var      array     $attributes 
  563.      */
  564.     var $attributes;
  565.  
  566.     /**
  567.      * name of this node.
  568.      *
  569.      * @access   public
  570.      * @var      string    $nodename 
  571.      */
  572.     var $nodename;
  573.  
  574.     /**
  575.      * textual data of this node.
  576.      *
  577.      * @access   public
  578.      * @var      string    $data 
  579.      */
  580.     var $data;
  581.  
  582.     /**
  583.      * character encoding for input data
  584.      *
  585.      * @access   private
  586.      * @var      $input_encoding 
  587.      */
  588.     var $input_encoding;
  589.  
  590.     /**
  591.      * PHP4 constructor.
  592.      *
  593.      * @package  CPAINT
  594.      * @access   public
  595.      * @return   void 
  596.      */
  597.     function cpaint_node({
  598.         $this->__construct();
  599.     }
  600.  
  601.     /**
  602.      * PHP 5 constructor.
  603.      *
  604.      * @access   public
  605.      * @return   void 
  606.      */
  607.     function __construct({
  608.     // initialize properties
  609.         $this->composites     = array();
  610.         $this->attributes     = array();
  611.         $this->data           = '';
  612.  
  613.         $this->set_encoding('UTF-8');
  614.         $this->set_name('');
  615.         $this->set_attribute('id''');
  616.     }
  617.  
  618.     /**
  619.      * adds a new subnode to this node.
  620.      *
  621.      * will return a reference to it for further processing.
  622.      *
  623.      * @access   public
  624.      * @param    string    $nodename     name of the new node
  625.      * @param    string    $id           id of the new node
  626.      * @return   object 
  627.      */
  628.     function &add_node($nodename$id ''{
  629.         $composites count($this->composites);
  630.  
  631.         // create new node
  632.         $this->composites[$composites=new cpaint_node();
  633.         $this->composites[$composites]->set_name($nodename);
  634.         $this->composites[$composites]->set_attribute('id'$id);
  635.         $this->composites[$composites]->set_encoding($this->input_encoding);
  636.  
  637.         return $this->composites[$composites];
  638.     }
  639.  
  640.     /**
  641.      * assigns textual data to this node.
  642.      *
  643.      * @access   public
  644.      * @param    mixed    $data    data to assign to this node
  645.      * @return   void 
  646.      */
  647.     function set_data($data{
  648.         $this->data = $data;
  649.     }
  650.  
  651.     /**
  652.      * returns the textual data assigned to this node.
  653.      *
  654.      * @access   public
  655.      * @return   mixed 
  656.      */
  657.     function get_data({
  658.         return $this->data;
  659.     }
  660.  
  661.     /**
  662.      * sets the id property of this node.
  663.      *
  664.      * @deprecated   deprecated since version 2.0.0
  665.      * @access       public
  666.      * @param        string    id      the id
  667.      * @return       void 
  668.      */
  669.     function set_id($id{
  670.         if ($id != ''{
  671.             $this->set_attribute('id'$id);
  672.         // end: if
  673.     }
  674.  
  675.     /**
  676.      * returns the id property if this node.
  677.      *
  678.      * @deprecated   deprecated since version 2.0.0
  679.      * @access       public
  680.      * @return       string 
  681.      */
  682.     function get_id({
  683.         return $this->get_attribute('id');
  684.     }
  685.  
  686.     /**
  687.      * adds a new attribute to this node.
  688.      *
  689.      * @access   public
  690.      * @param    string    $name       attribute name
  691.      * @param    mixed     $value      attribute value
  692.      * @return   void 
  693.      */
  694.     function set_attribute($name$value{
  695.         $this->attributes[$name= (string) $value;
  696.     }
  697.  
  698.     /**
  699.      * retrieves an attribute by name.
  700.      *
  701.      * @access   public
  702.      * @param    string    $name       attribute name
  703.      * @return   string 
  704.      */
  705.     function get_attribute($name{
  706.         return $this->attributes[$name];
  707.     }
  708.  
  709.     /**
  710.      * set name property.
  711.      *
  712.      * @access   public
  713.      * @param    string    $name   the name
  714.      * @return   void 
  715.      */
  716.     function set_name($name{
  717.         $this->nodename = (string) $name;
  718.     }
  719.  
  720.     /**
  721.      * get name property.
  722.      *
  723.      * @access   public
  724.      * @return   string 
  725.      */
  726.     function get_name({
  727.         return $this->nodename;
  728.     }
  729.  
  730.     /**
  731.      * sets the character encoding for this node
  732.      *
  733.      * @access   public
  734.      * @param    string      $encoding     character encoding
  735.      * @return   void 
  736.      */
  737.     function set_encoding($encoding{
  738.         $this->input_encoding strtoupper((string) $encoding);
  739.     }
  740.  
  741.     /**
  742.      * returns the character encoding for this node
  743.      *
  744.      * @access   public
  745.      * @return   string 
  746.      */
  747.     function get_encoding({
  748.         return $this->input_encoding;
  749.     }
  750. }
  751.  
  752. /**
  753.  * static class of output transformers.
  754.  *
  755.  * @package   CPAINT
  756.  * @access    public
  757.  * @author    Dominique Stender <dstender@st-webdevelopment.de>
  758.  * @copyright 2003-2006 (Dominique Stender); All rights reserved
  759.  * @version   2.1.0
  760.  */
  761. /**
  762.  * toString method, used to generate response of type TEXT.
  763.  * will perform character transformation according to parameters.
  764.  *
  765.  * @access   public
  766.  * @param    object    $node               a cpaint_node object
  767.  * @return   string 
  768.  */
  769.     function toString(&$node{
  770.         $return_value '';
  771.  
  772.         foreach ($node->composites as $composite{
  773.             $return_value .= cpaint_transformer::toString($composite);
  774.         }
  775.  
  776.         $return_value .= cpaint_transformer::encode($node->get_data()$node->get_encoding());
  777.  
  778.         return $return_value;
  779.     }
  780.  
  781.     /**
  782.      * XML response generator.
  783.      * will perform character transformation according to parameters.
  784.      *
  785.      * @access   public
  786.      * @param    object    $node               a cpaint_node object
  787.      * @return   string 
  788.      */
  789.     function toXML(&$node{
  790.         $return_value '<' $node->get_name();
  791.  
  792.         // handle attributes
  793.         foreach ($node->attributes as $name => $value{
  794.             if ($value != ''{
  795.                 $return_value .= ' ' $name '="' $node->get_attribute($name'"';
  796.             }
  797.         // end: foreach
  798.  
  799.         $return_value .= '>';
  800.  
  801.         // handle subnodes
  802.         foreach ($node->composites as $composite{
  803.             $return_value .= cpaint_transformer::toXML($composite);
  804.         }
  805.  
  806.         $return_value .= cpaint_transformer::encode($node->get_data()$node->get_encoding())
  807.             . '</' $node->get_name('>';
  808.  
  809.         return $return_value;
  810.     }
  811.  
  812.     /**
  813.      * JSON response generator.
  814.      * will perform character transformation according to parameters.
  815.      *
  816.      * @access   public
  817.      * @param    object    $node               a cpaint_node object
  818.      * @return   string 
  819.      */
  820.     function toJSON($node{
  821.         $return_value '';
  822.         $JSON_node    new stdClass();
  823.  
  824.         // handle attributes
  825.         $JSON_node->attributes $node->attributes;
  826.  
  827.         // handle subnodes
  828.         foreach ($node->composites as $composite{
  829.  
  830.             if (!is_array($JSON_node->{$composite->nodename})) {
  831.                 $JSON_node->{$composite->nodenamearray();
  832.             // end: if
  833.  
  834.             // we need to parse the JSON object again to avoid multiple encoding
  835.             $JSON_node->{$composite->nodename}[$GLOBALS['__cpaint_json']->parse(cpaint_transformer::toJSON($composite));
  836.         }
  837.  
  838.         // handle data
  839.         $JSON_node->data $node->data;
  840.  
  841.         return $GLOBALS['__cpaint_json']->stringify($JSON_node);
  842.     }
  843.  
  844.     /**
  845.      * performs conversion to JavaScript-safe UTF-8 characters
  846.      *
  847.      * @access   public
  848.      * @param    string    $data         data to convert
  849.      * @param    string    $encoding     character encoding
  850.      * @return   string 
  851.      */
  852.     function encode($data$encoding{
  853.     // convert string
  854.         if (function_exists('iconv')) {
  855.         // iconv is by far the most flexible approach, try this first
  856.             $return_value iconv($encoding'UTF-8'$data);
  857.  
  858.         elseif ($encoding == 'ISO-8859-1'{
  859.         // for ISO-8859-1 we can use utf8-encode()
  860.             $return_value utf8_encode($data);
  861.  
  862.         else {
  863.         // give up. if UTF-8 data was supplied everything is fine!
  864.             $return_value $data;
  865.         /* end: if */
  866.  
  867.         // now encode non-printable characters
  868.         for ($i 0$i 32$i++{
  869.             $return_value str_replace(chr($i)'\u00' sprintf('%02x'$i)$return_value);
  870.         // end: for
  871.  
  872.         // encode <, >, and & respectively for XML sanity
  873.         $return_value str_replace(chr(0x26)'\u0026'$return_value);
  874.         $return_value str_replace(chr(0x3c)'\u003c'$return_value);
  875.         $return_value str_replace(chr(0x3e)'\u003e'$return_value);
  876.  
  877.         return $return_value;
  878.     }
  879.  
  880.     /**
  881.      * performs conversion from JavaScript encodeURIComponent() string (UTF-8) to
  882.      * the charset in use.
  883.      *
  884.      * @access   public
  885.      * @param    string    $data         data to convert
  886.      * @param    string    $encoding     character encoding
  887.      * @return   string 
  888.      */
  889.     function decode($data$encoding{
  890.     // convert string
  891.  
  892.         if (is_string($data)) {
  893.             if (function_exists('iconv')) {
  894.             // iconv is by far the most flexible approach, try this first
  895.                 $return_value iconv('UTF-8'$encoding$data);
  896.  
  897.             elseif ($encoding == 'ISO-8859-1'{
  898.             // for ISO-8859-1 we can use utf8-decode()
  899.                 $return_value utf8_decode($data);
  900.  
  901.             else {
  902.             // give up. if data was supplied in the correct format everything is fine!
  903.                 $return_value $data;
  904.             // end: if
  905.  
  906.         else {
  907.         // non-string value
  908.             $return_value $data;
  909.         // end: if
  910.  
  911.         return $return_value;
  912.     }
  913.  
  914.     /**
  915.      * decodes a (nested) array of data from UTF-8 into the configured character set
  916.      *
  917.      * @access   public
  918.      * @param    array     $data         data to convert
  919.      * @param    string    $encoding     character encoding
  920.      * @return   array 
  921.      */
  922.     function decode_array($data$encoding{
  923.         $return_value array();
  924.  
  925.         foreach ($data as $key => $value{
  926.  
  927.             if (!is_array($value)) {
  928.                 $return_value[$keycpaint_transformer::decode($value$encoding);
  929.  
  930.             else {
  931.                 $return_value[$keycpaint_transformer::decode_array($value$encoding);
  932.             }
  933.         }
  934.  
  935.         return $return_value;
  936.     }
  937.  
  938.     /**
  939.      * determines the output character set
  940.      * based on input character set
  941.      *
  942.      * @access   public
  943.      * @param    string    $encoding     character encoding
  944.      * @return   string 
  945.      */
  946.     function find_output_charset($encoding{
  947.         $return_value 'UTF-8';
  948.  
  949.         if (function_exists('iconv')
  950.             || $encoding == 'UTF-8'
  951.             || $encoding == 'ISO-8859-1'{
  952.  
  953.             $return_value 'UTF-8';
  954.  
  955.         else {
  956.             $return_value $encoding;
  957.         // end: if
  958.  
  959.         return $return_value;
  960.     }
  961. }

Documentation generated on Mon, 03 Aug 2009 21:33:11 +0200 by phpDocumentor 1.4.2