1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
ClassLocator.php
См. документацию.
1<?php
2
3namespace Bitrix\Main;
4
5use Bitrix\Main\IO\Directory;
6use Bitrix\Main\IO\File;
7
8final class ClassLocator
9{
10 private static array $loadedClasses = [];
11
12 public static function getClassesByNamespace(string $namespace): array
13 {
14 $result = [];
15 $directories = self::getDirectoriesByNamespace($namespace);
16 foreach ($directories as $directory)
17 {
18 $classes = self::getClassesByPath($directory);
19 if (!empty($classes))
20 {
21 $result = array_merge($result, $classes);
22 }
23 }
24
25 return $result;
26 }
27
28 private static function getDirectoriesByNamespace(string $namespaceDirectory): array
29 {
30 $originalNamespaceDirectory = trim($namespaceDirectory, '\\');
31 $namespaceDirectory = self::normalizeNamespace($namespaceDirectory);
32
33 $namespaces = Loader::getNamespaces();
34
35 $namespaceDirectories = $namespaces[$namespaceDirectory] ?? [];
36
37 $directories = [];
38
39 if (empty($namespaceDirectories))
40 {
41 $namespaceParts = explode('\\', trim($namespaceDirectory, '\\'));
42 $originalNamespaceParts = explode('\\', $originalNamespaceDirectory);
43 for ($i = count($namespaceParts); $i >= 0; $i--)
44 {
45 $partNamespace = join('\\', array_slice($namespaceParts, 0, $i)) . '\\';
46 $partNamespaceDirectories = $namespaces[$partNamespace] ?? null;
47 if (empty($partNamespaceDirectories))
48 {
49 continue;
50 }
51
52 foreach ($partNamespaceDirectories as $partNamespaceDirectoriesItem)
53 {
54 $originalStylePath =
55 $partNamespaceDirectoriesItem['path']
56 . DIRECTORY_SEPARATOR
57 . join(DIRECTORY_SEPARATOR, array_slice($originalNamespaceParts, $i))
58 ;
59 if (is_dir($originalStylePath))
60 {
61 $directories[] = $originalStylePath;
62 continue;
63 }
64
65 $lowerStylePath =
66 $partNamespaceDirectoriesItem['path']
67 . DIRECTORY_SEPARATOR
68 . join(DIRECTORY_SEPARATOR, array_slice($namespaceParts, $i))
69 ;
70 if (is_dir($lowerStylePath))
71 {
72 $directories[] = $lowerStylePath;
73 continue;
74 }
75 }
76 }
77
78 }
79 else
80 {
81 foreach ($namespaceDirectories as $namespaceItem)
82 {
83 $directories[] = $namespaceItem['path'];
84 }
85 }
86
87 $directories = array_unique($directories);
88
89 return array_unique($directories);
90 }
91
92 private static function getClassesByPath($path): array
93 {
94 if (isset(self::$loadedClasses[$path]))
95 {
96 return self::$loadedClasses[$path];
97 }
98
99 $pathFiles = self::getFilesByPath($path);
100 foreach ($pathFiles as $pathFile)
101 {
102 $classesNames = self::getClassesNamesFromFilePath($pathFile);
103 foreach ($classesNames as $className)
104 {
105 if (class_exists($className))
106 {
107 self::$loadedClasses[$path][] = $className;
108 }
109 }
110 }
111
112 return self::$loadedClasses[$path] ?? [];
113 }
114
115 private static function getFilesByPath(string $path): array
116 {
117 $files = [];
118 $directory = new Directory($path);
119 if ($directory->isExists())
120 {
121 foreach ($directory->getChildren() as $child)
122 {
123 if ($child instanceof File)
124 {
125 $files[] = $child->getPath();
126 }
127 elseif ($child instanceof Directory)
128 {
129 foreach (self::getFilesByPath($child->getPath()) as $file)
130 {
131 $files[] = $file;
132 }
133 }
134 }
135 }
136 else
137 {
138 throw new ArgumentException('Invalid directory path');
139 }
140
141 return $files;
142 }
143
144 private static function getClassesNamesFromFilePath(string $filePath): array
145 {
146 $classes = [];
147 $file = new File($filePath);
148 if ($file->isExists() && $file->getExtension() === 'php')
149 {
150 $namespace = '';
151 $tokens = token_get_all($file->getContents());
152 $tokenCount = count($tokens);
153
154 for ($i = 0; $i < $tokenCount; $i++)
155 {
156 if (!is_array($tokens[$i]))
157 {
158 continue;
159 }
160
161 $tokenType = $tokens[$i][0];
162
163 if ($tokenType === T_NAMESPACE)
164 {
165 $namespace = '';
166 for ($j = $i + 1; $j < $tokenCount; $j++)
167 {
168 if ($tokens[$j] === ';')
169 {
170 break;
171 }
172 if (is_array($tokens[$j]) && in_array($tokens[$j][0], [T_NAME_QUALIFIED, T_STRING, T_NS_SEPARATOR]))
173 {
174 $namespace .= $tokens[$j][1];
175 }
176 }
177 continue;
178 }
179
180 if ($tokenType === T_CLASS)
181 {
182 $classNameToken = $i + 1;
183 while (
184 isset($tokens[$classNameToken]) &&
185 is_array($tokens[$classNameToken]) &&
186 $tokens[$classNameToken][0] === T_WHITESPACE
187 )
188 {
189 $classNameToken++;
190 }
191
192 if (
193 isset($tokens[$classNameToken]) &&
194 is_array($tokens[$classNameToken]) &&
195 $tokens[$classNameToken][0] === T_STRING
196 )
197 {
198 $className = $tokens[$classNameToken][1];
199 $classes[] = $namespace ? $namespace . '\\' . $className : $className;
200 }
201 }
202 }
203 }
204
205 return $classes;
206 }
207
208 private static function normalizeNamespace($namespace): string
209 {
210 return trim(strtolower($namespace), '\\') . '\\';
211 }
212}
$path
Определения access_edit.php:21
static getClassesByNamespace(string $namespace)
Определения ClassLocator.php:12
static getNamespaces()
Определения loader.php:652
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$files
Определения mysql_to_pgsql.php:30
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
$i
Определения factura.php:643
</p ></td >< td valign=top style='border-top:none;border-left:none;border-bottom:solid windowtext 1.0pt;border-right:solid windowtext 1.0pt;padding:0cm 2.0pt 0cm 2.0pt;height:9.0pt'>< p class=Normal align=center style='margin:0cm;margin-bottom:.0001pt;text-align:center;line-height:normal'>< a name=ТекстовоеПоле54 ></a ><?=($taxRate > count( $arTaxList) > 0) ? $taxRate."%"
Определения waybill.php:936