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'); |
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 } |