/lib/Zend/File/ClassFileLocator.php

https://gitlab.com/LisovyiEvhenii/ismextensions · PHP · 178 lines · 115 code · 12 blank · 51 comment · 31 complexity · a763041253fb82e55d99e50078f9e791 MD5 · raw file

  1. <?php
  2. /**
  3. * Zend Framework
  4. *
  5. * LICENSE
  6. *
  7. * This source file is subject to the new BSD license that is bundled
  8. * with this package in the file LICENSE.txt.
  9. * It is also available through the world-wide-web at this URL:
  10. * http://framework.zend.com/license/new-bsd
  11. * If you did not receive a copy of the license and are unable to
  12. * obtain it through the world-wide-web, please send an email
  13. * to license@zend.com so we can send you a copy immediately.
  14. *
  15. * @category Zend
  16. * @package Zend_File
  17. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  18. * @license http://framework.zend.com/license/new-bsd New BSD License
  19. */
  20. #require_once 'Zend/File/PhpClassFile.php';
  21. /**
  22. * Locate files containing PHP classes, interfaces, or abstracts
  23. *
  24. * @package Zend_File
  25. * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
  26. * @license New BSD {@link http://framework.zend.com/license/new-bsd}
  27. */
  28. class Zend_File_ClassFileLocator extends FilterIterator
  29. {
  30. /**
  31. * Create an instance of the locator iterator
  32. *
  33. * Expects either a directory, or a DirectoryIterator (or its recursive variant)
  34. * instance.
  35. *
  36. * @param string|DirectoryIterator $dirOrIterator
  37. */
  38. public function __construct($dirOrIterator = '.')
  39. {
  40. if (is_string($dirOrIterator)) {
  41. if (!is_dir($dirOrIterator)) {
  42. throw new InvalidArgumentException('Expected a valid directory name');
  43. }
  44. $dirOrIterator = new RecursiveDirectoryIterator($dirOrIterator);
  45. }
  46. if (!$dirOrIterator instanceof DirectoryIterator) {
  47. throw new InvalidArgumentException('Expected a DirectoryIterator');
  48. }
  49. if ($dirOrIterator instanceof RecursiveIterator) {
  50. $iterator = new RecursiveIteratorIterator($dirOrIterator);
  51. } else {
  52. $iterator = $dirOrIterator;
  53. }
  54. parent::__construct($iterator);
  55. $this->setInfoClass('Zend_File_PhpClassFile');
  56. // Forward-compat with PHP 5.3
  57. if (version_compare(PHP_VERSION, '5.3.0', '<')) {
  58. if (!defined('T_NAMESPACE')) {
  59. define('T_NAMESPACE', 'namespace');
  60. }
  61. if (!defined('T_NS_SEPARATOR')) {
  62. define('T_NS_SEPARATOR', '\\');
  63. }
  64. }
  65. }
  66. /**
  67. * Filter for files containing PHP classes, interfaces, or abstracts
  68. *
  69. * @return bool
  70. */
  71. public function accept()
  72. {
  73. $file = $this->getInnerIterator()->current();
  74. // If we somehow have something other than an SplFileInfo object, just
  75. // return false
  76. if (!$file instanceof SplFileInfo) {
  77. return false;
  78. }
  79. // If we have a directory, it's not a file, so return false
  80. if (!$file->isFile()) {
  81. return false;
  82. }
  83. // If not a PHP file, skip
  84. if ($file->getBasename('.php') == $file->getBasename()) {
  85. return false;
  86. }
  87. $contents = file_get_contents($file->getRealPath());
  88. $tokens = token_get_all($contents);
  89. $count = count($tokens);
  90. $t_trait = defined('T_TRAIT') ? T_TRAIT : -1; // For preserve PHP 5.3 compatibility
  91. for ($i = 0; $i < $count; $i++) {
  92. $token = $tokens[$i];
  93. if (!is_array($token)) {
  94. // single character token found; skip
  95. $i++;
  96. continue;
  97. }
  98. switch ($token[0]) {
  99. case T_NAMESPACE:
  100. // Namespace found; grab it for later
  101. $namespace = '';
  102. for ($i++; $i < $count; $i++) {
  103. $token = $tokens[$i];
  104. if (is_string($token)) {
  105. if (';' === $token) {
  106. $saveNamespace = false;
  107. break;
  108. }
  109. if ('{' === $token) {
  110. $saveNamespace = true;
  111. break;
  112. }
  113. continue;
  114. }
  115. list($type, $content, $line) = $token;
  116. switch ($type) {
  117. case T_STRING:
  118. case T_NS_SEPARATOR:
  119. $namespace .= $content;
  120. break;
  121. }
  122. }
  123. if ($saveNamespace) {
  124. $savedNamespace = $namespace;
  125. }
  126. break;
  127. case $t_trait:
  128. case T_CLASS:
  129. case T_INTERFACE:
  130. // Abstract class, class, interface or trait found
  131. // Get the classname
  132. for ($i++; $i < $count; $i++) {
  133. $token = $tokens[$i];
  134. if (is_string($token)) {
  135. continue;
  136. }
  137. list($type, $content, $line) = $token;
  138. if (T_STRING == $type) {
  139. // If a classname was found, set it in the object, and
  140. // return boolean true (found)
  141. if (!isset($namespace) || null === $namespace) {
  142. if (isset($saveNamespace) && $saveNamespace) {
  143. $namespace = $savedNamespace;
  144. } else {
  145. $namespace = null;
  146. }
  147. }
  148. $class = (null === $namespace) ? $content : $namespace . '\\' . $content;
  149. $file->addClass($class);
  150. $namespace = null;
  151. break;
  152. }
  153. }
  154. break;
  155. default:
  156. break;
  157. }
  158. }
  159. $classes = $file->getClasses();
  160. if (!empty($classes)) {
  161. return true;
  162. }
  163. // No class-type tokens found; return false
  164. return false;
  165. }
  166. }