/library/Zend/Code/Reflection/FileReflection.php

https://github.com/zucchi/zf2 · PHP · 313 lines · 140 code · 36 blank · 137 comment · 13 complexity · a6ef64083bf7c20cef361df764713059 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework (http://framework.zend.com/)
  4. *
  5. * @link http://github.com/zendframework/zf2 for the canonical source repository
  6. * @copyright Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
  7. * @license http://framework.zend.com/license/new-bsd New BSD License
  8. * @package Zend_Code
  9. */
  10. namespace Zend\Code\Reflection;
  11. use Zend\Code\Scanner\CachingFileScanner;
  12. /**
  13. * @category Zend
  14. * @package Zend_Reflection
  15. */
  16. class FileReflection implements ReflectionInterface
  17. {
  18. /**
  19. * @var string
  20. */
  21. protected $filePath = null;
  22. /**
  23. * @var string
  24. */
  25. protected $docComment = null;
  26. /**
  27. * @var int
  28. */
  29. protected $startLine = 1;
  30. /**
  31. * @var int
  32. */
  33. protected $endLine = null;
  34. /**
  35. * @var string
  36. */
  37. protected $namespaces = array();
  38. /**
  39. * @var string[]
  40. */
  41. protected $uses = array();
  42. /**
  43. * @var string[]
  44. */
  45. protected $requiredFiles = array();
  46. /**
  47. * @var ReflectionClass[]
  48. */
  49. protected $classes = array();
  50. /**
  51. * @var FunctionReflection[]
  52. */
  53. protected $functions = array();
  54. /**
  55. * @var string
  56. */
  57. protected $contents = null;
  58. /**
  59. * Constructor
  60. *
  61. * @param string $filename
  62. * @throws Exception\RuntimeException
  63. * @return FileReflection
  64. */
  65. public function __construct($filename)
  66. {
  67. if (($fileRealPath = realpath($filename)) === false) {
  68. $fileRealPath = stream_resolve_include_path($filename);
  69. }
  70. if (!$fileRealPath || !in_array($fileRealPath, get_included_files())) {
  71. throw new Exception\RuntimeException('File ' . $filename . ' must be required before it can be reflected');
  72. }
  73. $this->filePath = $fileRealPath;
  74. $this->reflect();
  75. }
  76. /**
  77. * Export
  78. *
  79. * Required by the Reflector interface.
  80. *
  81. * @todo What should this do?
  82. * @return null
  83. */
  84. public static function export()
  85. {
  86. return null;
  87. }
  88. /**
  89. * Return the file name of the reflected file
  90. *
  91. * @return string
  92. */
  93. public function getFileName()
  94. {
  95. // @todo get file name from path
  96. return $this->filePath;
  97. }
  98. /**
  99. * Get the start line - Always 1, staying consistent with the Reflection API
  100. *
  101. * @return int
  102. */
  103. public function getStartLine()
  104. {
  105. return $this->startLine;
  106. }
  107. /**
  108. * Get the end line / number of lines
  109. *
  110. * @return int
  111. */
  112. public function getEndLine()
  113. {
  114. return $this->endLine;
  115. }
  116. /**
  117. * Return the doc comment
  118. *
  119. * @return string
  120. */
  121. public function getDocComment()
  122. {
  123. return $this->docComment;
  124. }
  125. /**
  126. * Return the DocBlock
  127. *
  128. * @return DocBlockReflection
  129. */
  130. public function getDocBlock()
  131. {
  132. if (!($docComment = $this->getDocComment())) {
  133. return false;
  134. }
  135. $instance = new DocBlockReflection($docComment);
  136. return $instance;
  137. }
  138. public function getNamespaces()
  139. {
  140. return $this->namespaces;
  141. }
  142. /**
  143. * getNamespace()
  144. *
  145. * @return string
  146. */
  147. public function getNamespace()
  148. {
  149. if (count($this->namespaces) > 0) {
  150. return $this->namespaces[0];
  151. }
  152. return null;
  153. }
  154. /**
  155. * getUses()
  156. *
  157. * @return string[]
  158. */
  159. public function getUses()
  160. {
  161. return $this->uses;
  162. }
  163. /**
  164. * Return the reflection classes of the classes found inside this file
  165. *
  166. * @return array Array of \Zend\Code\Reflection\ReflectionClass instances
  167. */
  168. public function getClasses()
  169. {
  170. $classes = array();
  171. foreach ($this->classes as $class) {
  172. $instance = new ClassReflection($class);
  173. $classes[] = $instance;
  174. }
  175. return $classes;
  176. }
  177. /**
  178. * Return the reflection functions of the functions found inside this file
  179. *
  180. * @return array Array of Zend_Reflection_Functions
  181. */
  182. public function getFunctions()
  183. {
  184. $functions = array();
  185. foreach ($this->functions as $function) {
  186. $instance = new FunctionReflection($function);
  187. $functions[] = $instance;
  188. }
  189. return $functions;
  190. }
  191. /**
  192. * Retrieve the reflection class of a given class found in this file
  193. *
  194. * @param null|string $name
  195. * @return ClassReflection
  196. * @throws Exception\InvalidArgumentException for invalid class name or invalid reflection class
  197. */
  198. public function getClass($name = null)
  199. {
  200. if ($name === null) {
  201. reset($this->classes);
  202. $selected = current($this->classes);
  203. $instance = new ClassReflection($selected);
  204. return $instance;
  205. }
  206. if (in_array($name, $this->classes)) {
  207. $instance = new ClassReflection($name);
  208. return $instance;
  209. }
  210. throw new Exception\InvalidArgumentException('Class by name ' . $name . ' not found.');
  211. }
  212. /**
  213. * Return the full contents of file
  214. *
  215. * @return string
  216. */
  217. public function getContents()
  218. {
  219. return file_get_contents($this->filePath);
  220. }
  221. public function toString()
  222. {
  223. return ''; // @todo
  224. }
  225. /**
  226. * Serialize to string
  227. *
  228. * Required by the Reflector interface
  229. *
  230. * @todo What should this serialization look like?
  231. * @return string
  232. */
  233. public function __toString()
  234. {
  235. return '';
  236. }
  237. /**
  238. * This method does the work of "reflecting" the file
  239. *
  240. * Uses Zend\Code\Scanner\FileScanner to gather file information
  241. *
  242. * @return void
  243. */
  244. protected function reflect()
  245. {
  246. $scanner = new CachingFileScanner($this->filePath);
  247. $this->docComment = $scanner->getDocComment();
  248. $this->requiredFiles = $scanner->getIncludes();
  249. $this->classes = $scanner->getClassNames();
  250. $this->namespaces = $scanner->getNamespaces();
  251. $this->uses = $scanner->getUses();
  252. }
  253. /**
  254. * Validate / check a file level DocBlock
  255. *
  256. * @param array $tokens Array of tokenizer tokens
  257. * @return void
  258. */
  259. protected function checkFileDocBlock($tokens)
  260. {
  261. foreach ($tokens as $token) {
  262. $type = $token[0];
  263. $value = $token[1];
  264. $lineNum = $token[2];
  265. if (($type == T_OPEN_TAG) || ($type == T_WHITESPACE)) {
  266. continue;
  267. } elseif ($type == T_DOC_COMMENT) {
  268. $this->docComment = $value;
  269. $this->startLine = $lineNum + substr_count($value, "\n") + 1;
  270. return;
  271. } else {
  272. // Only whitespace is allowed before file DocBlocks
  273. return;
  274. }
  275. }
  276. }
  277. }