File indexing completed on 2024-12-22 05:36:40
0001 <?php 0002 /** 0003 * Zend Framework 0004 * 0005 * LICENSE 0006 * 0007 * This source file is subject to the new BSD license that is bundled 0008 * with this package in the file LICENSE.txt. 0009 * It is also available through the world-wide-web at this URL: 0010 * http://framework.zend.com/license/new-bsd 0011 * If you did not receive a copy of the license and are unable to 0012 * obtain it through the world-wide-web, please send an email 0013 * to license@zend.com so we can send you a copy immediately. 0014 * 0015 * @category Zend 0016 * @package Zend_File 0017 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0018 * @license http://framework.zend.com/license/new-bsd New BSD License 0019 */ 0020 0021 // require_once 'Zend/File/PhpClassFile.php'; 0022 0023 /** 0024 * Locate files containing PHP classes, interfaces, or abstracts 0025 * 0026 * @package Zend_File 0027 * @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com) 0028 * @license New BSD {@link http://framework.zend.com/license/new-bsd} 0029 */ 0030 class Zend_File_ClassFileLocator extends FilterIterator 0031 { 0032 /** 0033 * Create an instance of the locator iterator 0034 * 0035 * Expects either a directory, or a DirectoryIterator (or its recursive variant) 0036 * instance. 0037 * 0038 * @param string|DirectoryIterator $dirOrIterator 0039 */ 0040 public function __construct($dirOrIterator = '.') 0041 { 0042 if (is_string($dirOrIterator)) { 0043 if (!is_dir($dirOrIterator)) { 0044 throw new InvalidArgumentException('Expected a valid directory name'); 0045 } 0046 0047 $dirOrIterator = new RecursiveDirectoryIterator($dirOrIterator); 0048 } 0049 if (!$dirOrIterator instanceof DirectoryIterator) { 0050 throw new InvalidArgumentException('Expected a DirectoryIterator'); 0051 } 0052 0053 if ($dirOrIterator instanceof RecursiveIterator) { 0054 $iterator = new RecursiveIteratorIterator($dirOrIterator); 0055 } else { 0056 $iterator = $dirOrIterator; 0057 } 0058 0059 parent::__construct($iterator); 0060 $this->setInfoClass('Zend_File_PhpClassFile'); 0061 0062 // Forward-compat with PHP 5.3 0063 if (version_compare(PHP_VERSION, '5.3.0', '<')) { 0064 if (!defined('T_NAMESPACE')) { 0065 define('T_NAMESPACE', 'namespace'); 0066 } 0067 if (!defined('T_NS_SEPARATOR')) { 0068 define('T_NS_SEPARATOR', '\\'); 0069 } 0070 } 0071 } 0072 0073 /** 0074 * Filter for files containing PHP classes, interfaces, or abstracts 0075 * 0076 * @return bool 0077 */ 0078 public function accept() 0079 { 0080 $file = $this->getInnerIterator()->current(); 0081 // If we somehow have something other than an SplFileInfo object, just 0082 // return false 0083 if (!$file instanceof SplFileInfo) { 0084 return false; 0085 } 0086 0087 // If we have a directory, it's not a file, so return false 0088 if (!$file->isFile()) { 0089 return false; 0090 } 0091 0092 // If not a PHP file, skip 0093 if ($file->getBasename('.php') == $file->getBasename()) { 0094 return false; 0095 } 0096 0097 $contents = file_get_contents($file->getRealPath()); 0098 $tokens = token_get_all($contents); 0099 $count = count($tokens); 0100 $t_trait = defined('T_TRAIT') ? T_TRAIT : -1; // For preserve PHP 5.3 compatibility 0101 for ($i = 0; $i < $count; $i++) { 0102 $token = $tokens[$i]; 0103 if (!is_array($token)) { 0104 // single character token found; skip 0105 $i++; 0106 continue; 0107 } 0108 switch ($token[0]) { 0109 case T_NAMESPACE: 0110 // Namespace found; grab it for later 0111 $namespace = ''; 0112 for ($i++; $i < $count; $i++) { 0113 $token = $tokens[$i]; 0114 if (is_string($token)) { 0115 if (';' === $token) { 0116 $saveNamespace = false; 0117 break; 0118 } 0119 if ('{' === $token) { 0120 $saveNamespace = true; 0121 break; 0122 } 0123 continue; 0124 } 0125 list($type, $content, $line) = $token; 0126 switch ($type) { 0127 case T_STRING: 0128 case T_NS_SEPARATOR: 0129 $namespace .= $content; 0130 break; 0131 } 0132 } 0133 if ($saveNamespace) { 0134 $savedNamespace = $namespace; 0135 } 0136 break; 0137 case $t_trait: 0138 case T_CLASS: 0139 case T_INTERFACE: 0140 // Abstract class, class, interface or trait found 0141 0142 // Get the classname 0143 for ($i++; $i < $count; $i++) { 0144 $token = $tokens[$i]; 0145 if (is_string($token)) { 0146 continue; 0147 } 0148 list($type, $content, $line) = $token; 0149 if (T_STRING == $type) { 0150 // If a classname was found, set it in the object, and 0151 // return boolean true (found) 0152 if (!isset($namespace) || null === $namespace) { 0153 if (isset($saveNamespace) && $saveNamespace) { 0154 $namespace = $savedNamespace; 0155 } else { 0156 $namespace = null; 0157 } 0158 0159 } 0160 $class = (null === $namespace) ? $content : $namespace . '\\' . $content; 0161 $file->addClass($class); 0162 $namespace = null; 0163 break; 0164 } 0165 } 0166 break; 0167 default: 0168 break; 0169 } 0170 } 0171 $classes = $file->getClasses(); 0172 if (!empty($classes)) { 0173 return true; 0174 } 0175 // No class-type tokens found; return false 0176 return false; 0177 } 0178 }