File indexing completed on 2024-05-12 06:02:32

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 }