home *** CD-ROM | disk | FTP | other *** search
/ Cricao de Sites - 650 Layouts Prontos / WebMasters.iso / Servidores / xampp-win32-1.6.7-installer.exe / php / PEAR / XML / RPC2 / Server / Method.php < prev   
Encoding:
PHP Script  |  2008-07-02  |  12.7 KB  |  391 lines

  1. <?php
  2.  
  3. /* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4 foldmethod=marker: */
  4.  
  5. // LICENSE AGREEMENT. If folded, press za here to unfold and read license {{{ 
  6.  
  7. /**
  8. * +-----------------------------------------------------------------------------+
  9. * | Copyright (c) 2004-2006 Sergio Gonalves Carvalho                                |
  10. * +-----------------------------------------------------------------------------+
  11. * | This file is part of XML_RPC2.                                              |
  12. * |                                                                             |
  13. * | XML_RPC2 is free software; you can redistribute it and/or modify            |
  14. * | it under the terms of the GNU Lesser General Public License as published by |
  15. * | the Free Software Foundation; either version 2.1 of the License, or         |
  16. * | (at your option) any later version.                                         |
  17. * |                                                                             |
  18. * | XML_RPC2 is distributed in the hope that it will be useful,                 |
  19. * | but WITHOUT ANY WARRANTY; without even the implied warranty of              |
  20. * | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               |
  21. * | GNU Lesser General Public License for more details.                         |
  22. * |                                                                             |
  23. * | You should have received a copy of the GNU Lesser General Public License    |
  24. * | along with XML_RPC2; if not, write to the Free Software                     |
  25. * | Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA                    |
  26. * | 02111-1307 USA                                                              |
  27. * +-----------------------------------------------------------------------------+
  28. * | Author: Sergio Carvalho <sergio.carvalho@portugalmail.com>                  |
  29. * +-----------------------------------------------------------------------------+
  30. *
  31. * @category   XML
  32. * @package    XML_RPC2
  33. * @author     Sergio Carvalho <sergio.carvalho@portugalmail.com>  
  34. * @copyright  2004-2006 Sergio Carvalho
  35. * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  36. * @version    CVS: $Id: Method.php,v 1.12 2006/12/02 18:09:49 sergiosgc Exp $
  37. * @link       http://pear.php.net/package/XML_RPC2
  38. */
  39.  
  40. // }}}
  41.  
  42. // dependencies {{{
  43. require_once 'XML/RPC2/Exception.php';
  44. // }}}
  45.  
  46. /**
  47.  * Class representing an XML-RPC exported method. 
  48.  *
  49.  * This class is used internally by XML_RPC2_Server. External users of the 
  50.  * package should not need to ever instantiate XML_RPC2_Server_Method
  51.  *
  52.  * @category   XML
  53.  * @package    XML_RPC2
  54.  * @author     Sergio Carvalho <sergio.carvalho@portugalmail.com>  
  55.  * @copyright  2004-2006 Sergio Carvalho
  56.  * @license    http://www.gnu.org/copyleft/lesser.html  LGPL License 2.1
  57.  * @link       http://pear.php.net/package/XML_RPC2
  58.  */
  59. class XML_RPC2_Server_Method
  60. {
  61.     // {{{ properties
  62.     
  63.     /** 
  64.      * Method signature parameters 
  65.      *
  66.      * @var array
  67.      */
  68.     private $_parameters;
  69.     
  70.     /**
  71.      * Method signature return type 
  72.      *
  73.      * @var string
  74.      */
  75.     private $_returns ;
  76.     
  77.     /** 
  78.      * Method help, for introspection 
  79.      * 
  80.      * @var string
  81.      */
  82.     private $_help;
  83.     
  84.     /**
  85.      * internalMethod field : method name in PHP-land
  86.      *
  87.      * @var string
  88.      */
  89.     private $_internalMethod;
  90.     
  91.     /**
  92.      * hidden field : true if the method is hidden 
  93.      *
  94.      * @var boolean
  95.      */
  96.     private $_hidden;
  97.     
  98.     /**
  99.      * name Field : external method name
  100.      *
  101.      * @var string 
  102.      */
  103.     private $_name;
  104.     
  105.     /**
  106.      * Number of required parameters
  107.      *
  108.      * @var int
  109.      */
  110.     private $_numberOfRequiredParameters;
  111.     
  112.     // }}}
  113.     // {{{ getInternalMethod()
  114.     
  115.     /** 
  116.      * internalMethod getter 
  117.      * 
  118.      * @return string internalMethod
  119.      */
  120.     public function getInternalMethod() 
  121.     {
  122.         return $this->_internalMethod;
  123.     }
  124.         
  125.     // }}}
  126.     // {{{ isHidden()
  127.     
  128.     /** 
  129.      * hidden getter
  130.      * 
  131.      * @return boolean hidden value
  132.      */
  133.     public function isHidden() 
  134.     {
  135.         return $this->_hidden;
  136.     }
  137.         
  138.     // }}}
  139.     // {{{ getName()
  140.     
  141.     /**
  142.      * name getter
  143.      *
  144.      * @return string name
  145.      */
  146.     public function getName() 
  147.     {
  148.         return $this->_name;
  149.     }
  150.         
  151.     // }}}
  152.     // {{{ constructor
  153.     
  154.     /**
  155.      * Create a new XML-RPC method by introspecting a PHP method
  156.      *
  157.      * @param ReflectionMethod The PHP method to introspect
  158.      * @param string default prefix
  159.      */
  160.     public function __construct(ReflectionMethod $method, $defaultPrefix)
  161.     {
  162.         $hidden = false;
  163.         $docs = $method->getDocComment();
  164.         if (!$docs) {
  165.             $hidden = true;
  166.         }
  167.         $docs = explode("\n", $docs);
  168.  
  169.         $parameters = array();
  170.         $methodname = null;
  171.         $returns = 'mixed';
  172.         $shortdesc = '';
  173.         $paramcount = -1;
  174.         $prefix = $defaultPrefix;
  175.  
  176.         // Extract info from Docblock
  177.         $paramDocs = array();
  178.         foreach ($docs as $i => $doc) {
  179.             $doc = trim($doc, " \r\t/*");
  180.             if (strlen($doc) && strpos($doc, '@') !== 0) {
  181.                 if ($shortdesc) {
  182.                     $shortdesc .= "\n";
  183.                 }
  184.                 $shortdesc .= $doc;
  185.                 continue;
  186.             }
  187.             if (strpos($doc, '@xmlrpc.hidden') === 0) {
  188.                 $hidden = true;
  189.             }
  190.             if ((strpos($doc, '@xmlrpc.prefix') === 0) && preg_match('/@xmlrpc.prefix( )*(.*)/', $doc, $matches)) {
  191.                 $prefix = $matches[2];
  192.             }
  193.             if ((strpos($doc, '@xmlrpc.methodname') === 0) && preg_match('/@xmlrpc.methodname( )*(.*)/', $doc, $matches)) {
  194.                 $methodname = $matches[2];
  195.             }
  196.             if (strpos($doc, '@param') === 0) { // Save doctag for usage later when filling parameters
  197.                 $paramDocs[] = $doc;
  198.             }
  199.  
  200.             if (strpos($doc, '@return') === 0) {
  201.                 $param = preg_split("/\s+/", $doc);
  202.                 if (isset($param[1])) {
  203.                     $param = $param[1];
  204.                     $returns = $param;
  205.                 }
  206.             }
  207.         }
  208.         $this->_numberOfRequiredParameters = $method->getNumberOfRequiredParameters(); // we don't use isOptional() because of bugs in the reflection API
  209.         // Fill in info for each method parameter
  210.         foreach ($method->getParameters() as $parameterIndex => $parameter) {
  211.             // Parameter defaults
  212.             $newParameter = array('type' => 'mixed');
  213.  
  214.             // Attempt to extract type and doc from docblock
  215.             if (array_key_exists($parameterIndex, $paramDocs) &&
  216.                 preg_match('/@param\s+(\S+)(\s+(.+))/', $paramDocs[$parameterIndex], $matches)) {
  217.                 if (strpos($matches[1], '|')) {
  218.                     $newParameter['type'] = XML_RPC2_Server_Method::_limitPHPType(explode('|', $matches[1]));
  219.                 } else {
  220.                     $newParameter['type'] = XML_RPC2_Server_Method::_limitPHPType($matches[1]);
  221.                 }
  222.                 $tmp = '$' . $parameter->getName() . ' ';
  223.                 if (strpos($matches[2], '$' . $tmp) === 0) {
  224.                     $newParameter['doc'] = $matches[2];
  225.                 } else {
  226.                     // The phpdoc comment is something like "@param string $param description of param"    
  227.                     // Let's keep only "description of param" as documentation (remove $param)
  228.                     $newParameter['doc'] = substr($matches[2], strlen($tmp));
  229.                 }
  230.             }
  231.  
  232.             $parameters[$parameter->getName()] = $newParameter;
  233.         }
  234.  
  235.         if (is_null($methodname)) {
  236.             $methodname = $prefix . $method->getName();
  237.         }
  238.  
  239.         $this->_internalMethod = $method->getName();
  240.         $this->_parameters = $parameters;
  241.         $this->_returns  = $returns;
  242.         $this->_help = $shortdesc;
  243.         $this->_name = $methodname;
  244.         $this->_hidden = $hidden;
  245.     }
  246.     
  247.     // }}}
  248.     // {{{ matchesSignature()
  249.     
  250.     /** 
  251.      * Check if method matches provided call signature 
  252.      * 
  253.      * Compare the provided call signature with this methods' signature and
  254.      * return true iff they match.
  255.      *
  256.      * @param  string Signature to compare method name
  257.      * @param  array  Array of parameter values for method call.
  258.      * @return boolean True if call matches signature, false otherwise
  259.      */
  260.     public function matchesSignature($methodName, $callParams)
  261.     {
  262.         if ($methodName != $this->_name) return false;
  263.         if (count($callParams) < $this->_numberOfRequiredParameters) return false;
  264.         if (count($callParams) > $this->_parameters) return false;
  265.         $paramIndex = 0;
  266.         foreach($this->_parameters as $param) {
  267.             $paramIndex++;
  268.             if ($paramIndex <= $this->_numberOfRequiredParameters) {
  269.                 // the parameter is not optional
  270.                 $callParamType = XML_RPC2_Server_Method::_limitPHPType(gettype($callParams[$paramIndex-1]));
  271.                 if ((!($param['type'] == 'mixed')) and ($param['type'] != $callParamType)) {
  272.                     return false;
  273.                 }
  274.             }
  275.         }
  276.         return true;
  277.     }
  278.     
  279.     // }}}
  280.     // {{{ getHTMLSignature()
  281.     
  282.     /**
  283.      * Return a HTML signature of the method
  284.      * 
  285.      * @return string HTML signature
  286.      */
  287.     public function getHTMLSignature() 
  288.     {
  289.         $name = $this->_name;
  290.         $returnType = $this->_returns;
  291.         $result  = "<span class=\"type\">($returnType)</span> ";
  292.         $result .= "<span class=\"name\">$name</span>";
  293.         $result  .= "<span class=\"other\">(</span>";
  294.         $first = true;
  295.         $nbr = 0;
  296.         while (list($name, $parameter) = each($this->_parameters)) {
  297.             $nbr++;
  298.             if ($nbr == $this->_numberOfRequiredParameters + 1) {
  299.                 $result .= "<span class=\"other\"> [ </span>";
  300.             }
  301.             if ($first) {
  302.                 $first = false;
  303.             } else {
  304.                 $result .= ', ';
  305.             }
  306.             $type = $parameter['type'];
  307.             $result .= "<span class=\"paratype\">($type) </span>";
  308.             $result .= "<span class=\"paraname\">$name</span>";
  309.         }
  310.         reset($this->_parameters);
  311.         if ($nbr > $this->_numberOfRequiredParameters) {
  312.             $result .= "<span class=\"other\"> ] </span>";
  313.         }
  314.         $result .= "<span class=\"other\">)</span>";
  315.         return $result;
  316.     }
  317.     
  318.     // }}}
  319.     // {{{ autoDocument()
  320.     /**
  321.      * Print a complete HTML description of the method
  322.      */
  323.     public function autoDocument() 
  324.     {
  325.         $name = $this->getName();
  326.         $signature = $this->getHTMLSignature();
  327.         $id = md5($name);
  328.         $help = nl2br(htmlentities($this->_help));
  329.         print "      <h3><a name=\"$id\">$signature</a></h3>\n";
  330.         print "      <p><b>Description :</b></p>\n";
  331.         print "      <div class=\"description\">\n";
  332.         print "        $help\n";
  333.         print "      </div>\n";
  334.         if (count($this->_parameters)>0) {
  335.             print "      <p><b>Parameters : </b></p>\n";
  336.             if (count($this->_parameters)>0) {
  337.                 print "      <table>\n";
  338.                 print "        <tr><td><b>Type</b></td><td><b>Name</b></td><td><b>Documentation</b></td></tr>\n";
  339.                 while (list($name, $parameter) = each($this->_parameters)) {
  340.                     $type = $parameter['type'];
  341.                     $doc = htmlentities($parameter['doc']);
  342.                     print "        <tr><td>$type</td><td>$name</td><td>$doc</td></tr>\n";
  343.                 }
  344.                 reset($this->_parameters);
  345.                 print "      </table>\n";
  346.             }
  347.         }
  348.     }
  349.     
  350.     // }}}
  351.     // {{{ _limitPHPType()
  352.     /**
  353.      * standardise type names between gettype php function and phpdoc comments (and limit to xmlrpc available types)
  354.      * 
  355.      * @var string $type
  356.      * @return string standardised type
  357.      */
  358.     private static function _limitPHPType($type)
  359.     {
  360.         $tmp = strtolower($type);
  361.         $convertArray = array(
  362.             'int' => 'integer',
  363.             'i4' => 'integer',
  364.             'integer' => 'integer',
  365.             'string' => 'string',
  366.             'str' => 'string',
  367.             'char' => 'string',
  368.             'bool' => 'boolean',
  369.             'boolean' => 'boolean',
  370.             'array' => 'array',
  371.             'float' => 'double',
  372.             'double' => 'double',
  373.             'array' => 'array',
  374.             'struct' => 'array',
  375.             'assoc' => 'array',
  376.             'structure' => 'array',
  377.             'datetime' => 'mixed',
  378.             'datetime.iso8601' => 'mixed',
  379.             'iso8601' => 'mixed',
  380.             'base64' => 'string'
  381.         );    
  382.         if (isset($convertArray[$tmp])) {
  383.             return $convertArray[$tmp];    
  384.         }
  385.         return 'mixed';    
  386.     }
  387.     
  388. }
  389.  
  390. ?>
  391.