PageRenderTime 51ms CodeModel.GetById 18ms RepoModel.GetById 1ms app.codeStats 0ms

/www/libs/nette-dev/Reflection/ClassReflection.php

https://github.com/bazo/Mokuji
PHP | 299 lines | 136 code | 90 blank | 73 comment | 11 complexity | b1d7c7c20f2d4b983763dbbba5a53a74 MD5 | raw file
Possible License(s): BSD-3-Clause, MIT
  1. <?php
  2. /**
  3. * Nette Framework
  4. *
  5. * @copyright Copyright (c) 2004, 2010 David Grudl
  6. * @license http://nettephp.com/license Nette license
  7. * @link http://nettephp.com
  8. * @category Nette
  9. * @package Nette\Reflection
  10. */
  11. /**
  12. * Reports information about a class.
  13. *
  14. * @copyright Copyright (c) 2004, 2010 David Grudl
  15. * @package Nette\Reflection
  16. */
  17. class ClassReflection extends ReflectionClass
  18. {
  19. /** @var array (method => array(type => callback)) */
  20. private static $extMethods;
  21. /**
  22. * @param string|object
  23. * @return ClassReflection
  24. */
  25. public static function from($class)
  26. {
  27. return new self($class);
  28. }
  29. public function __toString()
  30. {
  31. return 'Class ' . $this->getName();
  32. }
  33. /**
  34. * @return bool
  35. */
  36. public function hasEventProperty($name)
  37. {
  38. if (preg_match('#^on[A-Z]#', $name) && $this->hasProperty($name)) {
  39. $rp = $this->getProperty($name);
  40. return $rp->isPublic() && !$rp->isStatic();
  41. }
  42. return FALSE;
  43. }
  44. /**
  45. * Adds a method to class.
  46. * @param string method name
  47. * @param mixed callback or closure
  48. * @return ClassReflection provides a fluent interface
  49. */
  50. public function setExtensionMethod($name, $callback)
  51. {
  52. $l = & self::$extMethods[strtolower($name)];
  53. $l[strtolower($this->getName())] = callback($callback);
  54. $l[''] = NULL;
  55. return $this;
  56. }
  57. /**
  58. * Returns extension method.
  59. * @param string method name
  60. * @return mixed
  61. */
  62. public function getExtensionMethod($name)
  63. {
  64. if (self::$extMethods === NULL || $name === NULL) { // for backwards compatibility
  65. $list = get_defined_functions(); // names are lowercase!
  66. foreach ($list['user'] as $fce) {
  67. $pair = explode('_prototype_', $fce);
  68. if (count($pair) === 2) {
  69. self::$extMethods[$pair[1]][$pair[0]] = callback($fce);
  70. self::$extMethods[$pair[1]][''] = NULL;
  71. }
  72. }
  73. if ($name === NULL) return NULL;
  74. }
  75. $class = strtolower($this->getName());
  76. $l = & self::$extMethods[strtolower($name)];
  77. if (empty($l)) {
  78. return FALSE;
  79. } elseif (isset($l[''][$class])) { // cached value
  80. return $l[''][$class];
  81. }
  82. $cl = $class;
  83. do {
  84. if (isset($l[$cl])) {
  85. return $l[''][$class] = $l[$cl];
  86. }
  87. } while (($cl = strtolower(get_parent_class($cl))) !== '');
  88. foreach (class_implements($class) as $cl) {
  89. $cl = strtolower($cl);
  90. if (isset($l[$cl])) {
  91. return $l[''][$class] = $l[$cl];
  92. }
  93. }
  94. return $l[''][$class] = FALSE;
  95. }
  96. /********************* Reflection layer ****************d*g**/
  97. /**
  98. * @return ClassReflection
  99. * @ignore internal
  100. */
  101. public static function import(ReflectionClass $ref)
  102. {
  103. return new self($ref->getName());
  104. }
  105. /**
  106. * @return MethodReflection
  107. */
  108. public function getConstructor()
  109. {
  110. return ($ref = parent::getConstructor()) ? MethodReflection::import($ref) : NULL;
  111. }
  112. /**
  113. * @return ExtensionReflection
  114. */
  115. public function getExtension()
  116. {
  117. return ($ref = parent::getExtension()) ? ExtensionReflection::import($ref) : NULL;
  118. }
  119. public function getInterfaces()
  120. {
  121. return array_map(array('ClassReflection', 'import'), parent::getInterfaces());
  122. }
  123. /**
  124. * @return MethodReflection
  125. */
  126. public function getMethod($name)
  127. {
  128. return MethodReflection::import(parent::getMethod($name));
  129. }
  130. public function getMethods($filter = -1)
  131. {
  132. return array_map(array('MethodReflection', 'import'), parent::getMethods($filter));
  133. }
  134. /**
  135. * @return ClassReflection
  136. */
  137. public function getParentClass()
  138. {
  139. return ($ref = parent::getParentClass()) ? self::import($ref) : NULL;
  140. }
  141. public function getProperties($filter = -1)
  142. {
  143. return array_map(array('PropertyReflection', 'import'), parent::getProperties($filter));
  144. }
  145. /**
  146. * @return PropertyReflection
  147. */
  148. public function getProperty($name)
  149. {
  150. return PropertyReflection::import(parent::getProperty($name));
  151. }
  152. /********************* Nette\Annotations support ****************d*g**/
  153. /**
  154. * Has class specified annotation?
  155. * @param string
  156. * @return bool
  157. */
  158. public function hasAnnotation($name)
  159. {
  160. $res = AnnotationsParser::getAll($this);
  161. return !empty($res[$name]);
  162. }
  163. /**
  164. * Returns an annotation value.
  165. * @param string
  166. * @return IAnnotation
  167. */
  168. public function getAnnotation($name)
  169. {
  170. $res = AnnotationsParser::getAll($this);
  171. return isset($res[$name]) ? end($res[$name]) : NULL;
  172. }
  173. /**
  174. * Returns all annotations.
  175. * @return array
  176. */
  177. public function getAnnotations()
  178. {
  179. return AnnotationsParser::getAll($this);
  180. }
  181. /********************* Nette\Object behaviour ****************d*g**/
  182. /**
  183. * @return ClassReflection
  184. */
  185. public function getReflection()
  186. {
  187. return new ClassReflection($this);
  188. }
  189. public function __call($name, $args)
  190. {
  191. return ObjectMixin::call($this, $name, $args);
  192. }
  193. public function &__get($name)
  194. {
  195. return ObjectMixin::get($this, $name);
  196. }
  197. public function __set($name, $value)
  198. {
  199. return ObjectMixin::set($this, $name, $value);
  200. }
  201. public function __isset($name)
  202. {
  203. return ObjectMixin::has($this, $name);
  204. }
  205. public function __unset($name)
  206. {
  207. throw new MemberAccessException("Cannot unset the property {$this->reflection->name}::\$$name.");
  208. }
  209. }