Moodle  2.2.1
http://www.collinsharper.com
C:/xampp/htdocs/moodle/lib/zend/Zend/Server/Reflection/Function/Abstract.php
Go to the documentation of this file.
00001 <?php
00024 require_once 'Zend/Server/Reflection/Node.php';
00025 
00029 require_once 'Zend/Server/Reflection/Parameter.php';
00030 
00034 require_once 'Zend/Server/Reflection/Prototype.php';
00035 
00053 abstract class Zend_Server_Reflection_Function_Abstract
00054 {
00058     protected $_reflection;
00059 
00064     protected $_argv = array();
00065 
00073     protected $_config = array();
00074 
00079     protected $_class;
00080 
00085     protected $_description = '';
00086 
00091     protected $_namespace;
00092 
00097     protected $_prototypes = array();
00098 
00099     private $_return;
00100     private $_returnDesc;
00101     private $_paramDesc;
00102     private $_sigParams;
00103     private $_sigParamsDepth;
00104 
00110     public function __construct(Reflector $r, $namespace = null, $argv = array())
00111     {
00112         // In PHP 5.1.x, ReflectionMethod extends ReflectionFunction. In 5.2.x,
00113         // both extend ReflectionFunctionAbstract. So, we can't do normal type
00114         // hinting in the prototype, but instead need to do some explicit
00115         // testing here.
00116         if ((!$r instanceof ReflectionFunction)
00117             && (!$r instanceof ReflectionMethod)) {
00118             require_once 'Zend/Server/Reflection/Exception.php';
00119             throw new Zend_Server_Reflection_Exception('Invalid reflection class');
00120         }
00121         $this->_reflection = $r;
00122 
00123         // Determine namespace
00124         if (null !== $namespace){
00125             $this->setNamespace($namespace);
00126         }
00127 
00128         // Determine arguments
00129         if (is_array($argv)) {
00130             $this->_argv = $argv;
00131         }
00132 
00133         // If method call, need to store some info on the class
00134         if ($r instanceof ReflectionMethod) {
00135             $this->_class = $r->getDeclaringClass()->getName();
00136         }
00137 
00138         // Perform some introspection
00139         $this->_reflect();
00140     }
00141 
00153     protected function _addTree(Zend_Server_Reflection_Node $parent, $level = 0)
00154     {
00155         if ($level >= $this->_sigParamsDepth) {
00156             return;
00157         }
00158 
00159         foreach ($this->_sigParams[$level] as $value) {
00160             $node = new Zend_Server_Reflection_Node($value, $parent);
00161             if ((null !== $value) && ($this->_sigParamsDepth > $level + 1)) {
00162                 $this->_addTree($node, $level + 1);
00163             }
00164         }
00165     }
00166 
00176     protected function _buildTree()
00177     {
00178         $returnTree = array();
00179         foreach ((array) $this->_return as $value) {
00180             $node = new Zend_Server_Reflection_Node($value);
00181             $this->_addTree($node);
00182             $returnTree[] = $node;
00183         }
00184 
00185         return $returnTree;
00186     }
00187 
00200     protected function _buildSignatures($return, $returnDesc, $paramTypes, $paramDesc)
00201     {
00202         $this->_return         = $return;
00203         $this->_returnDesc     = $returnDesc;
00204         $this->_paramDesc      = $paramDesc;
00205         $this->_sigParams      = $paramTypes;
00206         $this->_sigParamsDepth = count($paramTypes);
00207         $signatureTrees        = $this->_buildTree();
00208         $signatures            = array();
00209 
00210         $endPoints = array();
00211         foreach ($signatureTrees as $root) {
00212             $tmp = $root->getEndPoints();
00213             if (empty($tmp)) {
00214                 $endPoints = array_merge($endPoints, array($root));
00215             } else {
00216                 $endPoints = array_merge($endPoints, $tmp);
00217             }
00218         }
00219 
00220         foreach ($endPoints as $node) {
00221             if (!$node instanceof Zend_Server_Reflection_Node) {
00222                 continue;
00223             }
00224 
00225             $signature = array();
00226             do {
00227                 array_unshift($signature, $node->getValue());
00228                 $node = $node->getParent();
00229             } while ($node instanceof Zend_Server_Reflection_Node);
00230 
00231             $signatures[] = $signature;
00232         }
00233 
00234         // Build prototypes
00235         $params = $this->_reflection->getParameters();
00236         foreach ($signatures as $signature) {
00237             $return = new Zend_Server_Reflection_ReturnValue(array_shift($signature), $this->_returnDesc);
00238             $tmp    = array();
00239             foreach ($signature as $key => $type) {
00240                 $param = new Zend_Server_Reflection_Parameter($params[$key], $type, (isset($this->_paramDesc[$key]) ? $this->_paramDesc[$key] : null));
00241                 $param->setPosition($key);
00242                 $tmp[] = $param;
00243             }
00244 
00245             $this->_prototypes[] = new Zend_Server_Reflection_Prototype($return, $tmp);
00246         }
00247     }
00248 
00259     protected function _reflect()
00260     {
00261         $function           = $this->_reflection;
00262         $helpText           = '';
00263         $signatures         = array();
00264         $returnDesc         = '';
00265         $paramCount         = $function->getNumberOfParameters();
00266         $paramCountRequired = $function->getNumberOfRequiredParameters();
00267         $parameters         = $function->getParameters();
00268         $docBlock           = $function->getDocComment();
00269 
00270         if (!empty($docBlock)) {
00271             // Get help text
00272             if (preg_match(':/\*\*\s*\r?\n\s*\*\s(.*?)\r?\n\s*\*(\s@|/):s', $docBlock, $matches))
00273             {
00274                 $helpText = $matches[1];
00275                 $helpText = preg_replace('/(^\s*\*\s)/m', '', $helpText);
00276                 $helpText = preg_replace('/\r?\n\s*\*\s*(\r?\n)*/s', "\n", $helpText);
00277                 $helpText = trim($helpText);
00278             }
00279 
00280             // Get return type(s) and description
00281             $return     = 'void';
00282             if (preg_match('/@return\s+(\S+)/', $docBlock, $matches)) {
00283                 $return = explode('|', $matches[1]);
00284                 if (preg_match('/@return\s+\S+\s+(.*?)(@|\*\/)/s', $docBlock, $matches))
00285                 {
00286                     $value = $matches[1];
00287                     $value = preg_replace('/\s?\*\s/m', '', $value);
00288                     $value = preg_replace('/\s{2,}/', ' ', $value);
00289                     $returnDesc = trim($value);
00290                 }
00291             }
00292 
00293             // Get param types and description
00294             if (preg_match_all('/@param\s+([^\s]+)/m', $docBlock, $matches)) {
00295                 $paramTypesTmp = $matches[1];
00296                 if (preg_match_all('/@param\s+\S+\s+(\$\S+)\s+(.*?)(@|\*\/)/s', $docBlock, $matches))
00297                 {
00298                     $paramDesc = $matches[2];
00299                     foreach ($paramDesc as $key => $value) {
00300                         $value = preg_replace('/\s?\*\s/m', '', $value);
00301                         $value = preg_replace('/\s{2,}/', ' ', $value);
00302                         $paramDesc[$key] = trim($value);
00303                     }
00304                 }
00305             }
00306         } else {
00307             $helpText = $function->getName();
00308             $return   = 'void';
00309         }
00310 
00311         // Set method description
00312         $this->setDescription($helpText);
00313 
00314         // Get all param types as arrays
00315         if (!isset($paramTypesTmp) && (0 < $paramCount)) {
00316             $paramTypesTmp = array_fill(0, $paramCount, 'mixed');
00317         } elseif (!isset($paramTypesTmp)) {
00318             $paramTypesTmp = array();
00319         } elseif (count($paramTypesTmp) < $paramCount) {
00320             $start = $paramCount - count($paramTypesTmp);
00321             for ($i = $start; $i < $paramCount; ++$i) {
00322                 $paramTypesTmp[$i] = 'mixed';
00323             }
00324         }
00325 
00326         // Get all param descriptions as arrays
00327         if (!isset($paramDesc) && (0 < $paramCount)) {
00328             $paramDesc = array_fill(0, $paramCount, '');
00329         } elseif (!isset($paramDesc)) {
00330             $paramDesc = array();
00331         } elseif (count($paramDesc) < $paramCount) {
00332             $start = $paramCount - count($paramDesc);
00333             for ($i = $start; $i < $paramCount; ++$i) {
00334                 $paramDesc[$i] = '';
00335             }
00336         }
00337 
00338         if (count($paramTypesTmp) != $paramCount) {
00339             require_once 'Zend/Server/Reflection/Exception.php';
00340             throw new Zend_Server_Reflection_Exception(
00341                'Variable number of arguments is not supported for services (except optional parameters). '
00342              . 'Number of function arguments must correspond to actual number of arguments described in a docblock '
00343              . '(function was ' . $function->getName() . ')');
00344         }
00345 
00346         $paramTypes = array();
00347         foreach ($paramTypesTmp as $i => $param) {
00348             $tmp = explode('|', $param);
00349             if ($parameters[$i]->isOptional()) {
00350                 array_unshift($tmp, null);
00351             }
00352             $paramTypes[] = $tmp;
00353         }
00354 
00355         $this->_buildSignatures($return, $returnDesc, $paramTypes, $paramDesc);
00356     }
00357 
00358 
00366     public function __call($method, $args)
00367     {
00368         if (method_exists($this->_reflection, $method)) {
00369             return call_user_func_array(array($this->_reflection, $method), $args);
00370         }
00371 
00372         require_once 'Zend/Server/Reflection/Exception.php';
00373         throw new Zend_Server_Reflection_Exception('Invalid reflection method ("' .$method. '")');
00374     }
00375 
00385     public function __get($key)
00386     {
00387         if (isset($this->_config[$key])) {
00388             return $this->_config[$key];
00389         }
00390 
00391         return null;
00392     }
00393 
00403     public function __set($key, $value)
00404     {
00405         $this->_config[$key] = $value;
00406     }
00407 
00414     public function setNamespace($namespace)
00415     {
00416         if (empty($namespace)) {
00417             $this->_namespace = '';
00418             return;
00419         }
00420 
00421         if (!is_string($namespace) || !preg_match('/[a-z0-9_\.]+/i', $namespace)) {
00422             require_once 'Zend/Server/Reflection/Exception.php';
00423             throw new Zend_Server_Reflection_Exception('Invalid namespace');
00424         }
00425 
00426         $this->_namespace = $namespace;
00427     }
00428 
00434     public function getNamespace()
00435     {
00436         return $this->_namespace;
00437     }
00438 
00445     public function setDescription($string)
00446     {
00447         if (!is_string($string)) {
00448             require_once 'Zend/Server/Reflection/Exception.php';
00449             throw new Zend_Server_Reflection_Exception('Invalid description');
00450         }
00451 
00452         $this->_description = $string;
00453     }
00454 
00460     public function getDescription()
00461     {
00462         return $this->_description;
00463     }
00464 
00471     public function getPrototypes()
00472     {
00473         return $this->_prototypes;
00474     }
00475 
00481     public function getInvokeArguments()
00482     {
00483         return $this->_argv;
00484     }
00485 
00494     public function __wakeup()
00495     {
00496         if ($this->_reflection instanceof ReflectionMethod) {
00497             $class = new ReflectionClass($this->_class);
00498             $this->_reflection = new ReflectionMethod($class->newInstance(), $this->getName());
00499         } else {
00500             $this->_reflection = new ReflectionFunction($this->getName());
00501         }
00502     }
00503 }
 All Data Structures Namespaces Files Functions Variables Enumerations