[ Index ]

PHP Cross Reference of Moodle 1.9.3 [Build 15-Oct-2008]

title

Body

[close]

/lib/simpletestlib/ -> reflection_php5.php (source)

   1  <?php
   2      /**
   3       *    base include file for SimpleTest
   4       *    @package    SimpleTest
   5       *    @subpackage    UnitTester
   6       *    @version    $Id$
   7       */
   8  
   9      /**
  10       *    Version specific reflection API.
  11       *    @package SimpleTest
  12       *    @subpackage UnitTester
  13       */
  14      class SimpleReflection {
  15          var $_interface;
  16  
  17          /**
  18           *    Stashes the class/interface.
  19           *    @param string $interface    Class or interface
  20           *                                to inspect.
  21           */
  22          function SimpleReflection($interface) {
  23              $this->_interface = $interface;
  24          }
  25  
  26          /**
  27           *    Checks that a class has been declared. Versions
  28           *    before PHP5.0.2 need a check that it's not really
  29           *    an interface.
  30           *    @return boolean            True if defined.
  31           *    @access public
  32           */
  33          function classExists() {
  34              if (! class_exists($this->_interface)) {
  35                  return false;
  36              }
  37              $reflection = new ReflectionClass($this->_interface);
  38              return ! $reflection->isInterface();
  39          }
  40  
  41          /**
  42           *    Needed to kill the autoload feature in PHP5
  43           *    for classes created dynamically.
  44           *    @return boolean        True if defined.
  45           *    @access public
  46           */
  47          function classExistsSansAutoload() {
  48              return class_exists($this->_interface, false);
  49          }
  50  
  51          /**
  52           *    Checks that a class or interface has been
  53           *    declared.
  54           *    @return boolean            True if defined.
  55           *    @access public
  56           */
  57          function classOrInterfaceExists() {
  58              return $this->_classOrInterfaceExistsWithAutoload($this->_interface, true);
  59          }
  60  
  61          /**
  62           *    Needed to kill the autoload feature in PHP5
  63           *    for classes created dynamically.
  64           *    @return boolean        True if defined.
  65           *    @access public
  66           */
  67          function classOrInterfaceExistsSansAutoload() {
  68              return $this->_classOrInterfaceExistsWithAutoload($this->_interface, false);
  69          }
  70  
  71          /**
  72           *    Needed to select the autoload feature in PHP5
  73           *    for classes created dynamically.
  74           *    @param string $interface       Class or interface name.
  75           *    @param boolean $autoload       True totriggerautoload.
  76           *    @return boolean                True if interface defined.
  77           *    @access private
  78           */
  79          function _classOrInterfaceExistsWithAutoload($interface, $autoload) {
  80              if (function_exists('interface_exists')) {
  81                  if (interface_exists($this->_interface, $autoload)) {
  82                      return true;
  83                  }
  84              }
  85              return class_exists($this->_interface, $autoload);
  86          }
  87  
  88          /**
  89           *    Gets the list of methods on a class or
  90           *    interface. Needs to recursively look at all of
  91           *    the interfaces included.
  92           *    @returns array              List of method names.
  93           *    @access public
  94           */
  95          function getMethods() {
  96              return array_unique(get_class_methods($this->_interface));
  97          }
  98  
  99          /**
 100           *    Gets the list of interfaces from a class. If the
 101           *    class name is actually an interface then just that
 102           *    interface is returned.
 103           *    @returns array          List of interfaces.
 104           *    @access public
 105           */
 106          function getInterfaces() {
 107              $reflection = new ReflectionClass($this->_interface);
 108              if ($reflection->isInterface()) {
 109                  return array($this->_interface);
 110              }
 111              return $this->_onlyParents($reflection->getInterfaces());
 112          }
 113  
 114          /**
 115           *    Gets the list of methods for the implemented
 116           *    interfaces only.
 117           *    @returns array      List of enforced method signatures.
 118           *    @access public
 119           */
 120          function getInterfaceMethods() {
 121              $methods = array();
 122              foreach ($this->getInterfaces() as $interface) {
 123                  $methods = array_merge($methods, get_class_methods($interface));
 124              }
 125              return array_unique($methods);
 126          }
 127          
 128          /**
 129           *    Checks to see if the method signature has to be tightly
 130           *    specified.
 131           *    @param string $method        Method name.
 132           *    @returns boolean             True if enforced.
 133           *    @access private
 134           */
 135          function _isInterfaceMethod($method) {
 136              return in_array($method, $this->getInterfaceMethods());
 137          }
 138  
 139          /**
 140           *    Finds the parent class name.
 141           *    @returns string      Parent class name.
 142           *    @access public
 143           */
 144          function getParent() {
 145              $reflection = new ReflectionClass($this->_interface);
 146              $parent = $reflection->getParentClass();
 147              if ($parent) {
 148                  return $parent->getName();
 149              }
 150              return false;
 151          }
 152  
 153          /**
 154           *    Determines if the class is abstract.
 155           *    @returns boolean      True if abstract.
 156           *    @access public
 157           */
 158          function isAbstract() {
 159              $reflection = new ReflectionClass($this->_interface);
 160              return $reflection->isAbstract();
 161          }
 162  
 163          /**
 164           *    Wittles a list of interfaces down to only the top
 165           *    level parents.
 166           *    @param array $interfaces     Reflection API interfaces
 167           *                                 to reduce.
 168           *    @returns array               List of parent interface names.
 169           *    @access private
 170           */
 171          function _onlyParents($interfaces) {
 172              $parents = array();
 173              foreach ($interfaces as $interface) {
 174                  foreach($interfaces as $possible_parent) {
 175                      if ($interface->getName() == $possible_parent->getName()) {
 176                          continue;
 177                      }
 178                      if ($interface->isSubClassOf($possible_parent)) {
 179                          break;
 180                      }
 181                  }
 182                  $parents[] = $interface->getName();
 183              }
 184              return $parents;
 185          }
 186  
 187          /**
 188           *    Gets the source code matching the declaration
 189           *    of a method.
 190           *    @param string $name    Method name.
 191           *    @return string         Method signature up to last
 192           *                           bracket.
 193           *    @access public
 194           */
 195          function getSignature($name) {
 196              if ($name == '__set') {
 197                  return 'function __set($key, $value)';
 198              }
 199              if ($name == '__call') {
 200                  return 'function __call($method, $arguments)';
 201              }
 202              if (version_compare(phpversion(), '5.1.0', '>=')) {
 203                  if (in_array($name, array('__get', '__isset', $name == '__unset'))) {
 204                      return "function {$name}(\$key)";
 205                  }
 206              }
 207              if (! is_callable(array($this->_interface, $name))) {
 208                  return "function $name()";
 209              }
 210              if ($this->_isInterfaceMethod($name)) {
 211                  return $this->_getFullSignature($name);
 212              }
 213              return "function $name()";
 214          }
 215          
 216          /**
 217           *    For a signature specified in an interface, full
 218           *    details must be replicated to be a valid implementation.
 219           *    @param string $name    Method name.
 220           *    @return string         Method signature up to last
 221           *                           bracket.
 222           *    @access private
 223           */
 224          function _getFullSignature($name) {
 225              $interface = new ReflectionClass($this->_interface);
 226              $method = $interface->getMethod($name);
 227              $reference = $method->returnsReference() ? '&' : '';
 228              return "function $reference$name(" .
 229                      implode(', ', $this->_getParameterSignatures($method)) .
 230                      ")";
 231          }
 232  
 233          /**
 234           *    Gets the source code for each parameter.
 235           *    @param ReflectionMethod $method   Method object from
 236           *                                        reflection API
 237           *    @return array                     List of strings, each
 238           *                                      a snippet of code.
 239           *    @access private
 240           */
 241          function _getParameterSignatures($method) {
 242              $signatures = array();
 243              foreach ($method->getParameters() as $parameter) {
 244                  $type = $parameter->getClass();
 245                  $signatures[] =
 246                          (! is_null($type) ? $type->getName() . ' ' : '') .
 247                          ($parameter->isPassedByReference() ? '&' : '') .
 248                          '$' . $this->_suppressSpurious($parameter->getName()) .
 249                          ($this->_isOptional($parameter) ? ' = null' : '');
 250              }
 251              return $signatures;
 252          }
 253  
 254          /**
 255           *    The SPL library has problems with the
 256           *    Reflection library. In particular, you can
 257           *    get extra characters in parameter names :(.
 258           *    @param string $name    Parameter name.
 259           *    @return string         Cleaner name.
 260           *    @access private
 261           */
 262          function _suppressSpurious($name) {
 263              return str_replace(array('[', ']', ' '), '', $name);
 264          }
 265  
 266          /**
 267           *    Test of a reflection parameter being optional
 268           *    that works with early versions of PHP5.
 269           *    @param reflectionParameter $parameter    Is this optional.
 270           *    @return boolean                          True if optional.
 271           *    @access private
 272           */
 273          function _isOptional($parameter) {
 274              if (method_exists($parameter, 'isOptional')) {
 275                  return $parameter->isOptional();
 276              }
 277              return false;
 278          }
 279      }
 280  ?>


Generated: Wed Jan 14 11:33:29 2009 Cross-referenced by PHPXref 0.7