Skip to content

Commit acf4ffe

Browse files
Новый алгоритм поиска классов
1 parent a74383d commit acf4ffe

File tree

2 files changed

+60
-102
lines changed

2 files changed

+60
-102
lines changed

src/main/BitrixNeverInclude.php

Lines changed: 41 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -4,80 +4,14 @@
44

55
use Bitrix\Main\Loader;
66
use RuntimeException;
7+
use WebArch\BitrixCache\BitrixCache;
78

89
class BitrixNeverInclude
910
{
10-
11-
/**
12-
* @var BitrixNeverInclude
13-
*/
14-
protected static $instance;
15-
1611
/**
17-
* @return array
12+
* Тег для кеша маппинга глобальных классов из старых модулей
1813
*/
19-
protected function getModulePrefixMap()
20-
{
21-
//TODO Изменить способ определения - определять сразу по имени класса без всяких префиксов, что вычислительно быстрее!в
22-
return [
23-
24-
'iblock' => [
25-
'CIBlock',
26-
'_CIB',
27-
'CAllIBlock',
28-
'CEventIblock',
29-
'CRatingsComponentsIBlock',
30-
],
31-
32-
'catalog' => [
33-
'CCatalog',
34-
'CExtra',
35-
'CPrice',
36-
'CGlobalCond',
37-
],
38-
39-
'sale' => [
40-
'CSale',
41-
'CBaseSale',
42-
'IBXSale',
43-
'IPayment',
44-
'IShipment',
45-
'CAdminSale',
46-
],
47-
48-
'form' => [
49-
'CForm',
50-
'CAllForm',
51-
],
52-
53-
'highloadblock' => [
54-
'CUserTypeHlblock',
55-
'CIBlockPropertyDirectory',
56-
],
57-
58-
'idea' => [
59-
'CIdeaManagment',
60-
],
61-
62-
];
63-
}
64-
65-
protected function __construct()
66-
{
67-
68-
}
69-
70-
/**
71-
* @return BitrixNeverInclude
72-
*/
73-
protected function getInstance()
74-
{
75-
if (is_null(static::$instance)) {
76-
static::$instance = new static();
77-
}
78-
79-
return static::$instance;
80-
}
14+
const CACHE_TAG = 'BitrixNeverInclude';
8115

8216
/**
8317
* Зарегистрировать автолоадер модулей Битрикс
@@ -87,11 +21,34 @@ protected function getInstance()
8721
*/
8822
public static function registerModuleAutoload()
8923
{
90-
if (!spl_autoload_register([static::getInstance(), 'autoloadModule'])) {
24+
if (!spl_autoload_register([(new static()), 'autoloadModule'])) {
9125
throw new RuntimeException('Error register autoloader ' . __CLASS__);
9226
}
9327
}
9428

29+
/**
30+
* Возвращает маппинг имени модуля по имени класса. Имя класса всегда в нижнем регистре, т.к. сам Битрикс к нему
31+
* преобразует.
32+
*
33+
* Рекомендуется назначить вызов этого метода в конце сброса всего кеша, чтобы при следующем хите он уже был создан.
34+
*
35+
* @return array
36+
*/
37+
public static function getClassMapping()
38+
{
39+
$closure = function () {
40+
$tools = new Tools();
41+
$tools->includeAllInstalledModules();
42+
43+
return $tools->getModuleByClassNameMapping($tools->getAutoLoadClasses());
44+
};
45+
46+
return (new BitrixCache())
47+
->withTime(86400)
48+
->withTag(self::CACHE_TAG)
49+
->resultOf($closure);
50+
}
51+
9552
/**
9653
* @param string $class
9754
*/
@@ -113,48 +70,37 @@ protected function autoloadModule($class)
11370
}
11471

11572
/**
116-
* Определение имени модуля по префиксу класса
73+
* Определение модуля для старых классов из глобальной области
11774
*
11875
* @param string $class
11976
*
12077
* @return string Пустая строка, если не удалось определить имя модуля
12178
*/
122-
protected function checkPrefix($class)
79+
protected function recognizeOldModule($class)
12380
{
124-
125-
foreach (static::getModulePrefixMap() as $moduleName => $prefixList) {
126-
foreach ($prefixList as $prefix) {
127-
if (strpos($class, $prefix) === 0) {
128-
return (string)$moduleName;
129-
}
130-
}
81+
if (strpos($class, '\\') !== false) {
82+
return '';
13183
}
13284

133-
return '';
85+
return $this->checkClassMapping($class);
13486
}
13587

13688
/**
137-
* Определение модуля для старых классов из глобальной области
138-
*
13989
* @param string $class
14090
*
141-
* @return string Пустая строка, если не удалось определить имя модуля
91+
* @return string
14292
*/
143-
protected function recognizeOldModule($class)
93+
private function checkClassMapping($class)
14494
{
145-
/*
146-
* Если содержит обратный слеш или не начинается с 'C' или 'I',
147-
* то это не старый класс из глобальной области
148-
*/
149-
$first = substr($class, 0, 1);
150-
if (
151-
($first !== 'C' && $first !== 'I')
152-
|| strpos($class, '\\') !== false
153-
) {
95+
$lowClass = strtolower(trim($class));
96+
97+
$classMapping = static::getClassMapping();
98+
99+
if (!isset($classMapping[$lowClass])) {
154100
return '';
155101
}
156102

157-
return $this->checkPrefix($class);
103+
return (string)$classMapping[$lowClass];
158104
}
159105

160106
/**
@@ -179,11 +125,7 @@ protected function recognizeNewModule($class)
179125
* Иной кастомный модуль
180126
*/
181127
if (isset($chunks[0], $chunks[1])) {
182-
return sprintf(
183-
'%s.%s',
184-
strtolower($chunks[0]),
185-
strtolower($chunks[1])
186-
);
128+
return strtolower($chunks[0] . '.' . $chunks[1]);
187129
}
188130

189131
return '';

src/main/Tools.php

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,32 @@ public function getAutoLoadClasses()
3434
return $staticProperties['arAutoLoadClasses'];
3535
}
3636

37-
public function getClassNameMap(array $autoLoadClasses)
37+
/**
38+
* Вернуть индекс модуля по имени класса
39+
*
40+
* @param array $autoLoadClasses
41+
*
42+
* @return array
43+
*/
44+
public function getModuleByClassNameMapping(array $autoLoadClasses)
3845
{
3946
$map = [];
4047

4148
foreach ($autoLoadClasses as $className => $data) {
42-
if (!isset($data['module'])) {
49+
50+
/**
51+
* Нас не интересует модуль `main`, т.к. всегда подключён.
52+
* Также не интересуют классы не из глобального namespace
53+
*/
54+
if (
55+
!isset($data['module'])
56+
|| 'main' === $data['module']
57+
|| strpos($className, '\\') !== false
58+
) {
4359
continue;
4460
}
4561

46-
$map[$data['module']][] = $className;
62+
$map[$className] = $data['module'];
4763
}
4864

4965
return $map;

0 commit comments

Comments
 (0)