web/lib/Zend/File/ClassFileLocator.php
changeset 1230 68c69c656a2c
parent 808 6b6c2214f778
equal deleted inserted replaced
1229:5a6b6e770365 1230:68c69c656a2c
    12  * obtain it through the world-wide-web, please send an email
    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.
    13  * to license@zend.com so we can send you a copy immediately.
    14  *
    14  *
    15  * @category   Zend
    15  * @category   Zend
    16  * @package    Zend_File
    16  * @package    Zend_File
    17  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    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
    18  * @license    http://framework.zend.com/license/new-bsd     New BSD License
    19  */
    19  */
    20 
    20 
       
    21 require_once 'Zend/File/PhpClassFile.php';
       
    22 
    21 /**
    23 /**
    22  * Locate files containing PHP classes, interfaces, or abstracts
    24  * Locate files containing PHP classes, interfaces, or abstracts
    23  * 
    25  *
    24  * @package    Zend_File
    26  * @package    Zend_File
    25  * @copyright  Copyright (c) 2005-2012 Zend Technologies USA Inc. (http://www.zend.com)
    27  * @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}
    28  * @license    New BSD {@link http://framework.zend.com/license/new-bsd}
    27  */
    29  */
    28 class Zend_File_ClassFileLocator extends FilterIterator
    30 class Zend_File_ClassFileLocator extends FilterIterator
    29 {
    31 {
    30     /**
    32     /**
    31      * Create an instance of the locator iterator
    33      * Create an instance of the locator iterator
    32      * 
    34      *
    33      * Expects either a directory, or a DirectoryIterator (or its recursive variant) 
    35      * Expects either a directory, or a DirectoryIterator (or its recursive variant)
    34      * instance.
    36      * instance.
    35      * 
    37      *
    36      * @param  string|DirectoryIterator $dirOrIterator 
    38      * @param  string|DirectoryIterator $dirOrIterator
    37      * @return void
       
    38      */
    39      */
    39     public function __construct($dirOrIterator = '.')
    40     public function __construct($dirOrIterator = '.')
    40     {
    41     {
    41         if (is_string($dirOrIterator)) {
    42         if (is_string($dirOrIterator)) {
    42             if (!is_dir($dirOrIterator)) {
    43             if (!is_dir($dirOrIterator)) {
    54         } else {
    55         } else {
    55             $iterator = $dirOrIterator;
    56             $iterator = $dirOrIterator;
    56         }
    57         }
    57 
    58 
    58         parent::__construct($iterator);
    59         parent::__construct($iterator);
       
    60         $this->setInfoClass('Zend_File_PhpClassFile');
    59 
    61 
    60         // Forward-compat with PHP 5.3
    62         // Forward-compat with PHP 5.3
    61         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
    63         if (version_compare(PHP_VERSION, '5.3.0', '<')) {
    62             if (!defined('T_NAMESPACE')) {
    64             if (!defined('T_NAMESPACE')) {
    63                 define('T_NAMESPACE', 'namespace');
    65                 define('T_NAMESPACE', 'namespace');
    68         }
    70         }
    69     }
    71     }
    70 
    72 
    71     /**
    73     /**
    72      * Filter for files containing PHP classes, interfaces, or abstracts
    74      * Filter for files containing PHP classes, interfaces, or abstracts
    73      * 
    75      *
    74      * @return bool
    76      * @return bool
    75      */
    77      */
    76     public function accept()
    78     public function accept()
    77     {
    79     {
    78         $file = $this->getInnerIterator()->current();
    80         $file = $this->getInnerIterator()->current();
    79 
    81         // If we somehow have something other than an SplFileInfo object, just
    80         // If we somehow have something other than an SplFileInfo object, just 
       
    81         // return false
    82         // return false
    82         if (!$file instanceof SplFileInfo) {
    83         if (!$file instanceof SplFileInfo) {
    83             return false;
    84             return false;
    84         }
    85         }
    85 
    86 
    94         }
    95         }
    95 
    96 
    96         $contents = file_get_contents($file->getRealPath());
    97         $contents = file_get_contents($file->getRealPath());
    97         $tokens   = token_get_all($contents);
    98         $tokens   = token_get_all($contents);
    98         $count    = count($tokens);
    99         $count    = count($tokens);
    99         $i        = 0;
   100         $t_trait  = defined('T_TRAIT') ? T_TRAIT : -1; // For preserve PHP 5.3 compatibility
   100         while ($i < $count) {
   101         for ($i = 0; $i < $count; $i++) {
   101             $token = $tokens[$i];
   102             $token = $tokens[$i];
   102 
       
   103             if (!is_array($token)) {
   103             if (!is_array($token)) {
   104                 // single character token found; skip
   104                 // single character token found; skip
   105                 $i++;
   105                 $i++;
   106                 continue;
   106                 continue;
   107             }
   107             }
   108 
   108             switch ($token[0]) {
   109             list($id, $content, $line) = $token;
       
   110 
       
   111             switch ($id) {
       
   112                 case T_NAMESPACE:
   109                 case T_NAMESPACE:
   113                     // Namespace found; grab it for later
   110                     // Namespace found; grab it for later
   114                     $namespace = '';
   111                     $namespace = '';
   115                     $done      = false;
   112                     for ($i++; $i < $count; $i++) {
   116                     do {
       
   117                         ++$i;
       
   118                         $token = $tokens[$i];
   113                         $token = $tokens[$i];
   119                         if (is_string($token)) {
   114                         if (is_string($token)) {
   120                             if (';' === $token) {
   115                             if (';' === $token) {
   121                                 $done = true;
   116                                 $saveNamespace = false;
       
   117                                 break;
       
   118                             }
       
   119                             if ('{' === $token) {
       
   120                                 $saveNamespace = true;
       
   121                                 break;
   122                             }
   122                             }
   123                             continue;
   123                             continue;
   124                         }
   124                         }
   125                         list($type, $content, $line) = $token;
   125                         list($type, $content, $line) = $token;
   126                         switch ($type) {
   126                         switch ($type) {
   127                             case T_STRING:
   127                             case T_STRING:
   128                             case T_NS_SEPARATOR:
   128                             case T_NS_SEPARATOR:
   129                                 $namespace .= $content;
   129                                 $namespace .= $content;
   130                                 break;
   130                                 break;
   131                         }
   131                         }
   132                     } while (!$done && $i < $count);
   132                     }
   133 
   133                     if ($saveNamespace) {
   134                     // Set the namespace of this file in the object
   134                         $savedNamespace = $namespace;
   135                     $file->namespace = $namespace;
   135                     }
   136                     break;
   136                     break;
       
   137                 case $t_trait:
   137                 case T_CLASS:
   138                 case T_CLASS:
   138                 case T_INTERFACE:
   139                 case T_INTERFACE:
   139                     // Abstract class, class, or interface found
   140                     // Abstract class, class, interface or trait found
   140 
   141 
   141                     // Get the classname
   142                     // Get the classname
   142                     $class = '';
   143                     for ($i++; $i < $count; $i++) {
   143                     do {
       
   144                         ++$i;
       
   145                         $token = $tokens[$i];
   144                         $token = $tokens[$i];
   146                         if (is_string($token)) {
   145                         if (is_string($token)) {
   147                             continue;
   146                             continue;
   148                         }
   147                         }
   149                         list($type, $content, $line) = $token;
   148                         list($type, $content, $line) = $token;
   150                         switch ($type) {
   149                         if (T_STRING == $type) {
   151                             case T_STRING:
   150                     // If a classname was found, set it in the object, and
   152                                 $class = $content;
   151                     // return boolean true (found)
   153                                 break;
   152                             if (!isset($namespace) || null === $namespace) {
       
   153                                 if (isset($saveNamespace) && $saveNamespace) {
       
   154                                     $namespace = $savedNamespace;
       
   155                                 } else {
       
   156                                     $namespace = null;
       
   157                     }
       
   158 
       
   159                             }
       
   160                             $class = (null === $namespace) ? $content : $namespace . '\\' . $content;
       
   161                             $file->addClass($class);
       
   162                             $namespace = null;
       
   163                     break;
   154                         }
   164                         }
   155                     } while (empty($class) && $i < $count);
       
   156 
       
   157                     // If a classname was found, set it in the object, and 
       
   158                     // return boolean true (found)
       
   159                     if (!empty($class)) {
       
   160                         $file->classname = $class;
       
   161                         return true;
       
   162                     }
   165                     }
   163                     break;
   166                     break;
   164                 default:
   167                 default:
   165                     break;
   168                     break;
   166             }
   169             }
   167             ++$i;
       
   168         }
   170         }
   169 
   171         $classes = $file->getClasses();
       
   172         if (!empty($classes)) {
       
   173             return true;
       
   174         }
   170         // No class-type tokens found; return false
   175         // No class-type tokens found; return false
   171         return false;
   176         return false;
   172     }
   177     }
   173 }
   178 }