1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
configurator.php
См. документацию.
1<?php
2
3namespace Bitrix\Main\Engine;
4
5use Bitrix\Main\Engine\ActionFilter\Attribute\AttributeReader;
6use Bitrix\Main\Engine\ActionFilter\FilterType;
7use Bitrix\Main\Engine\Contract\Controllerable;
8use Bitrix\Main\Engine\Exception\ActionConfigurationException;
9use Bitrix\Main\Event;
10use Bitrix\Main\EventResult;
11use Closure;
12use ReflectionClass;
13use ReflectionMethod;
14
15final class Configurator
16{
17 public const EVENT_ON_BUILD_ACTIONS = 'onBuildActions';
18
19 public function getConfigurationByController(Controller $controller): array
20 {
21 $newConfiguration = $this->onBuildConfigurationOfActions($controller);
22 $configuration = $controller->configureActions() ? : [];
23
24 $lengthSuffix = mb_strlen(Controllerable::METHOD_ACTION_SUFFIX);
25 $reflectionClass = new ReflectionClass($controller);
26
27 $attributeReader = new AttributeReader();
28
29 foreach ($reflectionClass->getMethods(ReflectionMethod::IS_PUBLIC) as $method)
30 {
31 $probablySuffix = mb_substr($method->getName(), -$lengthSuffix);
32 if ($probablySuffix !== Controllerable::METHOD_ACTION_SUFFIX)
33 {
34 continue;
35 }
36
37 $actionName = mb_substr($method->name, 0, -$lengthSuffix);
38 if (!$attributeReader->hasMethodFilterAttributes($method))
39 {
40 continue;
41 }
42
43 if ($this->isExists($configuration, $actionName))
44 {
45 throw new ActionConfigurationException('Invalid configuration of actions. Configuration is multiple');
46 }
47
48 $configuration[$actionName] = $attributeReader->buildConfig($method);
49 }
50
51 $configuration = array_merge($newConfiguration, $configuration);
52 $configuration = $this->wrapClosure($configuration);
53
54 $this->checkConfigurations($configuration);
55
56 return $configuration;
57 }
58
59 private function isExists(array $configuration, $actionName): bool
60 {
61 $listOfActions = array_change_key_case($configuration);
62 $actionName = mb_strtolower($actionName);
63
64 return isset($listOfActions[$actionName]);
65 }
66
67 private function onBuildConfigurationOfActions(Controller $controller): array
68 {
69 $event = new Event(
70 'main',
71 self::EVENT_ON_BUILD_ACTIONS,
72 [
73 'controller' => $controller,
74 ]
75 );
76 $event->send($this);
77
78 $newConfiguration = [];
79 foreach ($event->getResults() as $eventResult)
80 {
81 if ($eventResult->getType() != EventResult::SUCCESS)
82 {
83 continue;
84 }
85
86 $parameters = $eventResult->getParameters();
87 if (isset($parameters['extraActions']) && is_array($parameters['extraActions']))
88 {
89 //configuration in $this->configureActions() has more priority then configuration which was provided by event
90 $newConfiguration = array_merge($newConfiguration, $parameters['extraActions']);
91 }
92 }
93
94 return $newConfiguration;
95 }
96
97 public function wrapFiltersClosure(array $filters): array
98 {
99 foreach ($filters as $i => $filter)
100 {
101 if (!($filter instanceof Closure))
102 {
103 continue;
104 }
105
106 $filters[$i] = new ActionFilter\ClosureWrapper($filter);
107 }
108
109 return $filters;
110 }
111
112 private function wrapClosure(array $configurations): array
113 {
114 foreach ($configurations as $actionName => $configuration)
115 {
116 if (!empty($configuration[FilterType::Prefilter->value]))
117 {
118 $configurations[$actionName][FilterType::Prefilter->value] =
119 $this->wrapFiltersClosure($configuration[FilterType::Prefilter->value]);
120 }
121
122 if (!empty($configuration[FilterType::EnablePrefilter->value]))
123 {
124 $configurations[$actionName][FilterType::EnablePrefilter->value] =
125 $this->wrapFiltersClosure($configuration[FilterType::EnablePrefilter->value]);
126 }
127
128 if (!empty($configuration[FilterType::Postfilter->value]))
129 {
130 $configurations[$actionName][FilterType::Postfilter->value] =
131 $this->wrapFiltersClosure($configuration[FilterType::Postfilter->value]);
132 }
133
134 if (!empty($configuration[FilterType::EnablePostfilter->value]))
135 {
136 $configurations[$actionName][FilterType::EnablePostfilter->value]
137 = $this->wrapFiltersClosure($configuration[FilterType::EnablePostfilter->value]);
138 }
139 }
140
141 return $configurations;
142 }
143
144 private function checkConfigurations(array $configurations): void
145 {
146 foreach ($configurations as $actionName => $configuration)
147 {
148 if (!is_string($actionName))
149 {
150 throw new ActionConfigurationException('Invalid configuration of actions. Action has to be string');
151 }
152
153 if (!is_array($configuration))
154 {
155 throw new ActionConfigurationException('Invalid configuration of actions. Configuration has to be array');
156 }
157
158 if (!empty($configuration[FilterType::Prefilter->value]))
159 {
160 $this->checkFilters($configuration[FilterType::Prefilter->value]);
161 }
162
163 if (!empty($configuration[FilterType::Postfilter->value]))
164 {
165 $this->checkFilters($configuration[FilterType::Postfilter->value]);
166 }
167 }
168 }
169
170 private function checkFilters(array $filters): void
171 {
172 foreach ($filters as $filter)
173 {
174 if (!($filter instanceof ActionFilter\Base))
175 {
176 throw new ActionConfigurationException('Filter has to be subclass of ' . ActionFilter\Base::className());
177 }
178 }
179 }
180}
const EVENT_ON_BUILD_ACTIONS
Определения configurator.php:17
getConfigurationByController(Controller $controller)
Определения configurator.php:19
wrapFiltersClosure(array $filters)
Определения configurator.php:97
Определения event.php:5
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$filter
Определения iblock_catalog_list.php:54
$event
Определения prolog_after.php:141
$i
Определения factura.php:643
$method
Определения index.php:27