This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
2 | ||||||||||||
3 | namespace DigitalWand\AdminHelper\Helper; |
|||||||||||
4 | ||||||||||||
5 | use Bitrix\Main\Loader; |
|||||||||||
6 | use Bitrix\Main\LoaderException; |
|||||||||||
7 | use Bitrix\Main\Localization\Loc; |
|||||||||||
8 | use Bitrix\Main\ModuleManager; |
|||||||||||
9 | use DigitalWand\AdminHelper\EntityManager; |
|||||||||||
10 | use DigitalWand\AdminHelper\Widget\HelperWidget; |
|||||||||||
11 | use Bitrix\Main\Entity\DataManager; |
|||||||||||
12 | use Bitrix\Highloadblock as HL; |
|||||||||||
13 | use Bitrix\Main\Context; |
|||||||||||
14 | ||||||||||||
15 | Loader::includeModule('highloadblock'); |
|||||||||||
16 | Loc::loadMessages(__FILE__); |
|||||||||||
17 | ||||||||||||
18 | /** |
|||||||||||
19 | * Данный модуль реализует подход MVC для создания административного интерфейса. |
|||||||||||
20 | * |
|||||||||||
21 | * Возможность построения административного интерфейса появляется благодаря наличию единого API для CRUD-операциями над |
|||||||||||
22 | * сущностями. Поэтому построение админ. интерфейса средствами данного модуля возможно только для классов, реализующих |
|||||||||||
23 | * API ORM Битрикс. При желании использовать данный модуль для сущностей, не использующих ORM Битрикс, можно |
|||||||||||
24 | * подготовить для таких сущностей класс-обёртку, реализующий необходимые функции. |
|||||||||||
25 | * |
|||||||||||
26 | * Основные понятия модуля: |
|||||||||||
27 | * <ul> |
|||||||||||
28 | * <li>Мдель: "model" в терминах MVC. Класс, унаследованный от DataManager или реализующий аналогичный API.</li> |
|||||||||||
29 | * <li>Хэлпер: "view" в терминах MVC. Класс, реализующий отрисовку интерфейса списка или детальной страницы.</li> |
|||||||||||
30 | * <li>Роутер: "controller" в терминах MVC. Файл, принимающий все запросы к админке данного модуля, создающий нужные |
|||||||||||
31 | * хэлперы с нужными настройками. С ним напрямую работать не придётся.</li> |
|||||||||||
32 | * <li>Виджеты: "delegate" в терминах MVC. Классы, отвечающие за отрисовку элементов управления для отдельных полей |
|||||||||||
33 | * сущностей. В списке и на детальной.</li> |
|||||||||||
34 | * </ul> |
|||||||||||
35 | * |
|||||||||||
36 | * Схема работы с модулем следующая: |
|||||||||||
37 | * <ul> |
|||||||||||
38 | * <li>Реализация класса AdminListHelper - для управления страницей списка элементов</li> |
|||||||||||
39 | * <li>Реализация класса AdminEditHelper - для управления страницей просмотра/редактирования элемента</li> |
|||||||||||
40 | * <li>Реализация класса AdminInterface - для описания конфигурации полей админки и классы интерфейсов</li> |
|||||||||||
41 | * <li>Реализация класса AdminSectionListHelper - для описания странице списка разделов(если они используются)</li> |
|||||||||||
42 | * <li>Реализация класса AdminSectionEditHelper - для управления страницей просмотра/редактирования раздела(если они используются)</li> |
|||||||||||
43 | * <li>Если не хватает возможностей виджетов, идущих с модулем, можно реализовать свой виджет, унаследованный от любого |
|||||||||||
44 | * другого готового виджета или от абстрактного класса HelperWidget</li> |
|||||||||||
45 | * </ul> |
|||||||||||
46 | * |
|||||||||||
47 | * Устаревший функционал: |
|||||||||||
48 | * <ul> |
|||||||||||
49 | * <li>Файл Interface.php с вызовом AdminBaseHelper::setInterfaceSettings(), в который передается |
|||||||||||
50 | * конфигурация полей админки и классы.</li> |
|||||||||||
51 | * |
|||||||||||
52 | * Рекомендуемая файловая структура для модулей, использующих данный функционал: |
|||||||||||
53 | * <ul> |
|||||||||||
54 | * <li>Каталог <b>admin</b>. Достаточно поместить в него файл menu.php, отдельные файлы для списка и детальной |
|||||||||||
55 | * создавать не надо благодаря единому роутингу.</li> |
|||||||||||
56 | * <li>Каталог <b>classes</b> (или lib): содержит классы модли, представлений и делегатов.</li> |
|||||||||||
57 | * <li> -- <b>classes/admininterface</b>: каталог, содержащий классы "view", унаследованные от AdminListHelper, |
|||||||||||
58 | * AdminEditHelper, AdminInterface, AdminSectionListHelper и AdminSectionEditHelper.</li> |
|||||||||||
59 | * <li> -- <b>classes/widget</b>: каталог, содержащий виджеты ("delegate"), если для модуля пришлось создавать |
|||||||||||
60 | * свои.</li> |
|||||||||||
61 | * <li> -- <b>classes/model</b>: каталог с моделями, если пришлось переопределять поведение стандартынх функций getList |
|||||||||||
62 | * и т.д.</li> |
|||||||||||
63 | * </ul> |
|||||||||||
64 | * |
|||||||||||
65 | * Использовать данную структуру не обязательно, это лишь рекомендация, основанная на успешном опыте применения модуля |
|||||||||||
66 | * в ряде проектов. |
|||||||||||
67 | * |
|||||||||||
68 | * Единственное <b>обязательное</b> условие - расположение всех реализуемых классов админ хелперов и админ интерфейсов |
|||||||||||
69 | * в одном неймспейсе |
|||||||||||
70 | * |
|||||||||||
71 | * При использовании разделов нужно обязательно прописать в модели элементов привязку к модели разделов, например: |
|||||||||||
72 | * |
|||||||||||
73 | * ```php |
|||||||||||
74 | * <?php |
|||||||||||
75 | * class ElementModel |
|||||||||||
76 | * { |
|||||||||||
77 | * public static function getMap() |
|||||||||||
78 | * { |
|||||||||||
79 | * return [ |
|||||||||||
80 | * 'CATEGORY' => [ |
|||||||||||
81 | * 'data_type' => 'Vendor\Module\CategoryTable', |
|||||||||||
82 | * 'reference' => ['=this.CATEGORY_ID' => 'ref.ID'], |
|||||||||||
83 | * ] |
|||||||||||
84 | * ]; |
|||||||||||
85 | * } |
|||||||||||
86 | * ``` |
|||||||||||
87 | * |
|||||||||||
88 | * @see AdminInterface::fields() |
|||||||||||
89 | * @package AdminHelper |
|||||||||||
90 | * |
|||||||||||
91 | * @author Nik Samokhvalov <[email protected]> |
|||||||||||
92 | * @author Artem Yarygin <[email protected]> |
|||||||||||
93 | */ |
|||||||||||
94 | abstract class AdminBaseHelper |
|||||||||||
95 | { |
|||||||||||
96 | /** |
|||||||||||
97 | * @internal |
|||||||||||
98 | * @var string адрес обработчика запросов к админ. интерфейсу. |
|||||||||||
99 | */ |
|||||||||||
100 | static protected $routerUrl = '/bitrix/admin/admin_helper_route.php'; |
|||||||||||
101 | ||||||||||||
102 | /** |
|||||||||||
103 | * @var string |
|||||||||||
104 | * Имя класса используемой модели. Используется для выполнения CRUD-операций. |
|||||||||||
105 | * При наследовании класса необходимо переопределить эту переменную, указав полное имя класса модели. |
|||||||||||
106 | * |
|||||||||||
107 | * @see DataManager |
|||||||||||
108 | * @api |
|||||||||||
109 | */ |
|||||||||||
110 | static protected $model; |
|||||||||||
111 | ||||||||||||
112 | /** |
|||||||||||
113 | * @var string |
|||||||||||
114 | * Имя класса используемого менеджера сущностей. Используется для выполнения CRUD-операций. |
|||||||||||
115 | * |
|||||||||||
116 | * @see DataManager |
|||||||||||
117 | * @api |
|||||||||||
118 | */ |
|||||||||||
119 | static protected $entityManager = '\DigitalWand\AdminHelper\EntityManager'; |
|||||||||||
120 | ||||||||||||
121 | /** |
|||||||||||
122 | * @var string |
|||||||||||
123 | * Назвние модуля данной модели. |
|||||||||||
124 | * При наследовании класса необходимо указать нзвание модуля, в котором он находится. |
|||||||||||
125 | * А можно и не указывать, в этому случае он определится автоматически по namespace класса |
|||||||||||
126 | * Используется для избежания конфликтов между именами представлений. |
|||||||||||
127 | * |
|||||||||||
128 | * @api |
|||||||||||
129 | */ |
|||||||||||
130 | static public $module = array(); |
|||||||||||
131 | ||||||||||||
132 | /** |
|||||||||||
133 | * @var string[] |
|||||||||||
134 | * Название представления. |
|||||||||||
135 | * При наследовании класса необходимо указать название представления. |
|||||||||||
136 | * А можно и не указывать, в этому случае оно определится автоматически по namespace класса. |
|||||||||||
137 | * Оно будет использовано при построении URL к данному разделу админки. |
|||||||||||
138 | * Не должно содержать пробелов и других символов, требующих преобразований для |
|||||||||||
139 | * адресной строки браузера. |
|||||||||||
140 | * |
|||||||||||
141 | * @api |
|||||||||||
142 | */ |
|||||||||||
143 | static protected $viewName = array(); |
|||||||||||
144 | ||||||||||||
145 | /** |
|||||||||||
146 | * @var array |
|||||||||||
147 | * Настройки интерфейса |
|||||||||||
148 | * @see AdminBaseHelper::setInterfaceSettings() |
|||||||||||
149 | * @internal |
|||||||||||
150 | */ |
|||||||||||
151 | static protected $interfaceSettings = array(); |
|||||||||||
152 | ||||||||||||
153 | /** |
|||||||||||
154 | * @var array |
|||||||||||
155 | * Привязка класса интерфеса к классу хелпера |
|||||||||||
156 | */ |
|||||||||||
157 | static protected $interfaceClass = array(); |
|||||||||||
158 | ||||||||||||
159 | /** |
|||||||||||
160 | * @var array |
|||||||||||
161 | * Хранит список отображаемых полей и настройки их отображения |
|||||||||||
162 | * @see AdminBaseHelper::setInterfaceSettings() |
|||||||||||
163 | */ |
|||||||||||
164 | protected $fields = array(); |
|||||||||||
165 | ||||||||||||
166 | /** |
|||||||||||
167 | * @var \CMain |
|||||||||||
168 | * Замена global $APPLICATION; |
|||||||||||
169 | */ |
|||||||||||
170 | protected $app; |
|||||||||||
171 | protected $validationErrors = array(); |
|||||||||||
172 | ||||||||||||
173 | /** |
|||||||||||
174 | * @var string |
|||||||||||
175 | * Позволяет непосредственно указать адрес страницы списка. Полезно, в случае, если такая станица реализована без |
|||||||||||
176 | * использования данного модуля. В случае, если поле определено для класса, роутинг не используется. |
|||||||||||
177 | * |
|||||||||||
178 | * @see AdminBaseHelper::getListPageUrl |
|||||||||||
179 | * @api |
|||||||||||
180 | */ |
|||||||||||
181 | static protected $listPageUrl; |
|||||||||||
182 | ||||||||||||
183 | /** |
|||||||||||
184 | * @var string |
|||||||||||
185 | * $viewName представления, отвечающего за страницу списка. Необходимо указывать только для классов, уналедованных |
|||||||||||
186 | * от AdminEditHelper. |
|||||||||||
187 | * Необязательное, сгенерируется автоматически если не определено |
|||||||||||
188 | * |
|||||||||||
189 | * @see AdminBaseHelper::getViewName() |
|||||||||||
190 | * @see AdminBaseHelper::getListPageUrl |
|||||||||||
191 | * @see AdminEditHelper |
|||||||||||
192 | * @api |
|||||||||||
193 | */ |
|||||||||||
194 | static protected $listViewName; |
|||||||||||
195 | ||||||||||||
196 | /** |
|||||||||||
197 | * @var string |
|||||||||||
198 | * Позволяет непосредственно указать адрес страницы просмотра/редактирования элемента. Полезно, в случае, если |
|||||||||||
199 | * такая станица реализована без использования данного модуля. В случае, если поле определено для класса, |
|||||||||||
200 | * роутинг не используется. |
|||||||||||
201 | * |
|||||||||||
202 | * @see AdminBaseHelper::getEditPageUrl |
|||||||||||
203 | * @api |
|||||||||||
204 | */ |
|||||||||||
205 | static protected $editPageUrl; |
|||||||||||
206 | ||||||||||||
207 | /** |
|||||||||||
208 | * @var string |
|||||||||||
209 | * $viewName представления, отвечающего за страницу редактирования/просмотра элемента. Необходимо указывать только |
|||||||||||
210 | * для классов, уналедованных от AdminListHelper. |
|||||||||||
211 | * |
|||||||||||
212 | * @see AdminBaseHelper::getViewName() |
|||||||||||
213 | * @see AdminBaseHelper::getEditPageUrl |
|||||||||||
214 | * @see AdminListHelper |
|||||||||||
215 | * @api |
|||||||||||
216 | */ |
|||||||||||
217 | static protected $editViewName; |
|||||||||||
218 | ||||||||||||
219 | /** |
|||||||||||
220 | * @var string |
|||||||||||
221 | * Позволяет непосредственно указать адрес страницы просмотра/редактирования раздела. Полезно, в случае, если |
|||||||||||
222 | * такая станица реализована без использования данного модуля. В случае, если поле определено для класса, |
|||||||||||
223 | * роутинг не используется. |
|||||||||||
224 | * |
|||||||||||
225 | * @see AdminBaseHelper::getEditPageUrl |
|||||||||||
226 | * @api |
|||||||||||
227 | */ |
|||||||||||
228 | static protected $sectionsEditPageUrl; |
|||||||||||
229 | ||||||||||||
230 | /** |
|||||||||||
231 | * @var string |
|||||||||||
232 | * $viewName представления, отвечающего за страницу редактирования/просмотра раздела. Необходимо указывать только |
|||||||||||
233 | * для классов, уналедованных от AdminListHelper. |
|||||||||||
234 | * Необязательное, сгенерируется автоматически если не определено |
|||||||||||
235 | * |
|||||||||||
236 | * @see AdminBaseHelper::getViewName() |
|||||||||||
237 | * @see AdminBaseHelper::getEditPageUrl |
|||||||||||
238 | * @see AdminListHelper |
|||||||||||
239 | * @api |
|||||||||||
240 | */ |
|||||||||||
241 | static protected $sectionsEditViewName; |
|||||||||||
242 | ||||||||||||
243 | /** |
|||||||||||
244 | * @var array |
|||||||||||
245 | * Дополнительные параметры URL, которые будут добавлены к параметрам по-умолчанию, генерируемым автоматически |
|||||||||||
246 | * @api |
|||||||||||
247 | */ |
|||||||||||
248 | protected $additionalUrlParams = array(); |
|||||||||||
249 | ||||||||||||
250 | /** |
|||||||||||
251 | * @var string контекст выполнения. Полезен для информирования виджетов о том, какая операция в настоящий момент |
|||||||||||
252 | * производится. |
|||||||||||
253 | */ |
|||||||||||
254 | protected $context = ''; |
|||||||||||
255 | ||||||||||||
256 | /** |
|||||||||||
257 | * Флаг использования разделов, необходимо переопределять в дочернем классе |
|||||||||||
258 | * @var bool |
|||||||||||
259 | */ |
|||||||||||
260 | static protected $useSections = false; |
|||||||||||
261 | ||||||||||||
262 | /** |
|||||||||||
263 | * Правило именования хелперов для разделов по умолчанию |
|||||||||||
264 | * @var string |
|||||||||||
265 | */ |
|||||||||||
266 | static protected $sectionSuffix = 'Sections'; |
|||||||||||
267 | ||||||||||||
268 | /** |
|||||||||||
269 | * @param array $fields список используемых полей и виджетов для них |
|||||||||||
270 | * @param array $tabs список вкладок для детальной страницы |
|||||||||||
271 | * @param string $module название модуля |
|||||||||||
272 | */ |
|||||||||||
273 | public function __construct(array $fields, array $tabs = array(), $module = "") |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
274 | { |
|||||||||||
275 | global $APPLICATION; |
|||||||||||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
||||||||||||
276 | ||||||||||||
277 | $this->app = $APPLICATION; |
|||||||||||
278 | ||||||||||||
279 | $settings = array( |
|||||||||||
280 | 'FIELDS' => $fields, |
|||||||||||
281 | 'TABS' => $tabs |
|||||||||||
282 | ); |
|||||||||||
283 | if (static::setInterfaceSettings($settings)) { |
|||||||||||
284 | $this->fields = $fields; |
|||||||||||
285 | } |
|||||||||||
286 | else { |
|||||||||||
287 | $settings = static::getInterfaceSettings(); |
|||||||||||
288 | $this->fields = $settings['FIELDS']; |
|||||||||||
289 | } |
|||||||||||
290 | } |
|||||||||||
291 | ||||||||||||
292 | /** |
|||||||||||
293 | * @param string $viewName Имя вьюхи, для которой мы хотим получить натсройки |
|||||||||||
294 | * |
|||||||||||
295 | * @return array Возвращает настройки интерфейса для данного класса. |
|||||||||||
296 | * |
|||||||||||
297 | * @see AdminBaseHelper::setInterfaceSettings() |
|||||||||||
298 | * @api |
|||||||||||
299 | */ |
|||||||||||
300 | public static function getInterfaceSettings($viewName = '') |
|||||||||||
301 | { |
|||||||||||
302 | if (empty($viewName)) { |
|||||||||||
303 | $viewName = static::getViewName(); |
|||||||||||
304 | } |
|||||||||||
305 | ||||||||||||
306 | return self::$interfaceSettings[static::getModule()][$viewName]['interface']; |
|||||||||||
307 | } |
|||||||||||
308 | ||||||||||||
309 | /** |
|||||||||||
310 | * Основная функция для конфигурации всего административного интерфейса. |
|||||||||||
311 | * |
|||||||||||
312 | * @param array $settings настройки полей и вкладок |
|||||||||||
313 | * @param array $helpers список классов-хэлперов, используемых для отрисовки админки |
|||||||||||
314 | * @param string $module название модуля |
|||||||||||
315 | * |
|||||||||||
316 | * @return bool false, если для данного класса уже были утановлены настройки |
|||||||||||
317 | * |
|||||||||||
318 | * @api |
|||||||||||
319 | */ |
|||||||||||
320 | public static function setInterfaceSettings(array $settings, array $helpers = array(), $module = '') |
|||||||||||
321 | { |
|||||||||||
322 | foreach ($helpers as $helperClass => $helperSettings) { |
|||||||||||
323 | if (!is_array($helperSettings)) { // поддержка старого формата описания хелперов |
|||||||||||
324 | $helperClass = $helperSettings; // в значении передается класс хелпера а не настройки |
|||||||||||
325 | $helperSettings = array(); // настроек в старом формате нет |
|||||||||||
326 | } |
|||||||||||
327 | $success = $helperClass::registerInterfaceSettings($module, array_merge($settings, $helperSettings)); |
|||||||||||
328 | if (!$success) return false; |
|||||||||||
329 | } |
|||||||||||
330 | ||||||||||||
331 | return true; |
|||||||||||
332 | } |
|||||||||||
333 | ||||||||||||
334 | /** |
|||||||||||
335 | * Привязывает класса хелпера из которого вызывается к интерфесу, используется при получении |
|||||||||||
336 | * данных об элементах управления из интерфейса. |
|||||||||||
337 | * |
|||||||||||
338 | * @param $class |
|||||||||||
339 | */ |
|||||||||||
340 | public static function setInterfaceClass($class) |
|||||||||||
341 | { |
|||||||||||
342 | static::$interfaceClass[get_called_class()] = $class; |
|||||||||||
343 | } |
|||||||||||
344 | ||||||||||||
345 | /** |
|||||||||||
346 | * Возвращает класс интерфейса к которому привязан хелпер из которого вызван метод. |
|||||||||||
347 | * |
|||||||||||
348 | * @return array |
|||||||||||
349 | */ |
|||||||||||
350 | public static function getInterfaceClass() |
|||||||||||
351 | { |
|||||||||||
352 | return isset(static::$interfaceClass[get_called_class()]) ? static::$interfaceClass[get_called_class()] : false; |
|||||||||||
353 | } |
|||||||||||
354 | ||||||||||||
355 | /** |
|||||||||||
356 | * Регистрирует настройки интерфейса для текущего хелпера |
|||||||||||
357 | * |
|||||||||||
358 | * @param string $module имя текущего модуля |
|||||||||||
359 | * @param $interfaceSettings |
|||||||||||
360 | * |
|||||||||||
361 | * @return bool |
|||||||||||
362 | * @internal |
|||||||||||
363 | */ |
|||||||||||
364 | public static function registerInterfaceSettings($module, $interfaceSettings) |
|||||||||||
365 | { |
|||||||||||
366 | if (isset(self::$interfaceSettings[$module][static::getViewName()]) || empty($module) |
|||||||||||
367 | || empty($interfaceSettings) |
|||||||||||
368 | ) { |
|||||||||||
369 | return false; |
|||||||||||
370 | } |
|||||||||||
371 | ||||||||||||
372 | self::$interfaceSettings[$module][static::getViewName()] = array( |
|||||||||||
373 | 'helper' => get_called_class(), |
|||||||||||
374 | 'interface' => $interfaceSettings |
|||||||||||
375 | ); |
|||||||||||
376 | ||||||||||||
377 | return true; |
|||||||||||
378 | } |
|||||||||||
379 | ||||||||||||
380 | /** |
|||||||||||
381 | * Получает настройки интерфейса для данного модуля и представления. Используется при роутинге. |
|||||||||||
382 | * Возвращается массив со следующими ключами: |
|||||||||||
383 | * |
|||||||||||
384 | * <ul> |
|||||||||||
385 | * <li> helper - название класса-хэлпера, который будет рисовать страницу</li> |
|||||||||||
386 | * <li> interface - настройки интерфейса для хелпера</li> |
|||||||||||
387 | * </ul> |
|||||||||||
388 | * |
|||||||||||
389 | * @param string $module Модуль, для которого нужно получить настройки. |
|||||||||||
390 | * @param string $view Название представления. |
|||||||||||
391 | * |
|||||||||||
392 | * @return array |
|||||||||||
393 | * @internal |
|||||||||||
394 | */ |
|||||||||||
395 | public static function getGlobalInterfaceSettings($module, $view) |
|||||||||||
396 | { |
|||||||||||
397 | if (!isset(self::$interfaceSettings[$module][$view])) { |
|||||||||||
398 | return false; |
|||||||||||
399 | } |
|||||||||||
400 | ||||||||||||
401 | return array( |
|||||||||||
402 | self::$interfaceSettings[$module][$view]['helper'], |
|||||||||||
403 | self::$interfaceSettings[$module][$view]['interface'], |
|||||||||||
404 | ); |
|||||||||||
405 | } |
|||||||||||
406 | ||||||||||||
407 | /** |
|||||||||||
408 | * Возвращает имя текущего представления. |
|||||||||||
409 | * |
|||||||||||
410 | * @return string |
|||||||||||
411 | * @api |
|||||||||||
412 | */ |
|||||||||||
413 | public static function getViewName() |
|||||||||||
414 | { |
|||||||||||
415 | if (!is_array(static::$viewName)) { |
|||||||||||
416 | return static::$viewName; |
|||||||||||
417 | } |
|||||||||||
418 | ||||||||||||
419 | $className = get_called_class(); |
|||||||||||
420 | ||||||||||||
421 | if (!isset(static::$viewName[$className])) { |
|||||||||||
422 | $classNameParts = explode('\\', trim($className, '\\')); |
|||||||||||
423 | ||||||||||||
424 | if (count($classNameParts) > 2) { |
|||||||||||
425 | $classCaption = array_pop($classNameParts); // название класса без namespace |
|||||||||||
426 | preg_match_all('/((?:^|[A-Z])[a-z]+)/', $classCaption, $matches); |
|||||||||||
427 | $classCaptionParts = $matches[0]; |
|||||||||||
428 | ||||||||||||
429 | if (end($classCaptionParts) == 'Helper') { |
|||||||||||
430 | array_pop($classCaptionParts); |
|||||||||||
431 | } |
|||||||||||
432 | ||||||||||||
433 | static::$viewName[$className] = strtolower(implode('_', $classCaptionParts)); |
|||||||||||
434 | } |
|||||||||||
435 | } |
|||||||||||
436 | ||||||||||||
437 | return static::$viewName[$className]; |
|||||||||||
438 | } |
|||||||||||
439 | ||||||||||||
440 | /** |
|||||||||||
441 | * Возвращает поле модели которое используется для привязки к разделу из поля с типом совпадающим с классом модели |
|||||||||||
442 | * раздела. |
|||||||||||
443 | * @return string |
|||||||||||
444 | * @throws Exception |
|||||||||||
445 | */ |
|||||||||||
446 | public static function getSectionField() |
|||||||||||
447 | { |
|||||||||||
448 | $sectionListHelper = static::getHelperClass(AdminSectionListHelper::className()); |
|||||||||||
449 | ||||||||||||
450 | if (empty($sectionListHelper)) |
|||||||||||
451 | { |
|||||||||||
452 | return null; |
|||||||||||
453 | } |
|||||||||||
454 | ||||||||||||
455 | $sectionModelClass = $sectionListHelper::getModel(); |
|||||||||||
456 | $modelClass = static::getModel(); |
|||||||||||
457 | ||||||||||||
458 | foreach ($modelClass::getMap() as $field => $data) { |
|||||||||||
459 | if ($data['data_type'] === $sectionModelClass) { |
|||||||||||
460 | return str_replace('=this.', '', key($data['reference'])); |
|||||||||||
461 | } |
|||||||||||
462 | } |
|||||||||||
463 | ||||||||||||
464 | throw new Exception('References to section model not found'); |
|||||||||||
465 | } |
|||||||||||
466 | ||||||||||||
467 | /** |
|||||||||||
468 | * Возвращает имя класса используемой модели. |
|||||||||||
469 | * |
|||||||||||
470 | * @return \Bitrix\Main\Entity\DataManager|string |
|||||||||||
471 | * |
|||||||||||
472 | * @throws \Bitrix\Main\ArgumentException |
|||||||||||
473 | * @throws \Bitrix\Main\SystemException |
|||||||||||
474 | * @throws \Exception |
|||||||||||
475 | * @api |
|||||||||||
476 | */ |
|||||||||||
477 | public static function getModel() |
|||||||||||
478 | { |
|||||||||||
479 | if (static::$model) { |
|||||||||||
480 | return static::getHLEntity(static::$model); |
|||||||||||
481 | } |
|||||||||||
482 | ||||||||||||
483 | return null; |
|||||||||||
484 | } |
|||||||||||
485 | ||||||||||||
486 | /** |
|||||||||||
487 | * Возвращает имя модуля. Если оно не задано, то определяет автоматически из namespace класса. |
|||||||||||
488 | * |
|||||||||||
489 | * @return string |
|||||||||||
490 | * |
|||||||||||
491 | * @throws LoaderException |
|||||||||||
492 | * @api |
|||||||||||
493 | */ |
|||||||||||
494 | public static function getModule() |
|||||||||||
495 | { |
|||||||||||
496 | if (!is_array(static::$module)) { |
|||||||||||
497 | return static::$module; |
|||||||||||
498 | } |
|||||||||||
499 | ||||||||||||
500 | $className = get_called_class(); |
|||||||||||
501 | ||||||||||||
502 | if (!isset(static::$module[$className])) { |
|||||||||||
503 | $classNameParts = explode('\\', trim($className, '\\')); |
|||||||||||
504 | ||||||||||||
505 | $moduleNameParts = array(); |
|||||||||||
506 | $moduleName = false; |
|||||||||||
507 | ||||||||||||
508 | while (count($classNameParts)) { |
|||||||||||
509 | $moduleNameParts[] = strtolower(array_shift($classNameParts)); |
|||||||||||
510 | $moduleName = implode('.', $moduleNameParts); |
|||||||||||
511 | ||||||||||||
512 | if (ModuleManager::isModuleInstalled($moduleName)) { |
|||||||||||
513 | static::$module[$className] = $moduleName; |
|||||||||||
514 | break; |
|||||||||||
515 | } |
|||||||||||
516 | } |
|||||||||||
517 | ||||||||||||
518 | if (empty($moduleName)) { |
|||||||||||
519 | throw new LoaderException('Module name not found'); |
|||||||||||
520 | } |
|||||||||||
521 | } |
|||||||||||
522 | ||||||||||||
523 | return static::$module[$className]; |
|||||||||||
524 | } |
|||||||||||
525 | ||||||||||||
526 | /** |
|||||||||||
527 | * Возвращает модифцированный массив с описанием элемента управления по его коду. Берет название и настройки |
|||||||||||
528 | * из админ-интерфейса, если они не заданы — используются значения по умолчанию. |
|||||||||||
529 | * |
|||||||||||
530 | * Если элемент управления описан в админ-интерфейсе, то дефолтные настройки и описанные в классе интерфейса |
|||||||||||
531 | * будут совмещены (смержены). |
|||||||||||
532 | * |
|||||||||||
533 | * @param $code |
|||||||||||
534 | * @param $params |
|||||||||||
535 | * @param array $keys |
|||||||||||
536 | * |
|||||||||||
537 | * @return array|bool |
|||||||||||
538 | */ |
|||||||||||
539 | protected function getButton($code, $params, $keys = array('name', 'TEXT')) |
|||||||||||
540 | { |
|||||||||||
541 | $interfaceClass = static::getInterfaceClass(); |
|||||||||||
542 | $interfaceSettings = static::getInterfaceSettings(); |
|||||||||||
543 | ||||||||||||
544 | if ($interfaceClass && !empty($interfaceSettings['BUTTONS'])) { |
|||||||||||
0 ignored issues
–
show
The expression
$interfaceClass of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent. Consider making the comparison explicit by using ![]() |
||||||||||||
545 | $buttons = $interfaceSettings['BUTTONS']; |
|||||||||||
546 | ||||||||||||
547 | if (is_array($buttons) && isset($buttons[$code])) { |
|||||||||||
548 | if ($buttons[$code]['VISIBLE'] == 'N') { |
|||||||||||
549 | return false; |
|||||||||||
550 | } |
|||||||||||
551 | $params = array_merge($params, $buttons[$code]); |
|||||||||||
552 | ||||||||||||
553 | return $params; |
|||||||||||
554 | } |
|||||||||||
555 | } |
|||||||||||
556 | ||||||||||||
557 | $text = Loc::getMessage('DIGITALWAND_ADMIN_HELPER_' . $code); |
|||||||||||
558 | ||||||||||||
559 | foreach ($keys as $key) { |
|||||||||||
560 | $params[$key] = $text; |
|||||||||||
561 | } |
|||||||||||
562 | ||||||||||||
563 | return $params; |
|||||||||||
564 | } |
|||||||||||
565 | ||||||||||||
566 | /** |
|||||||||||
567 | * Возвращает список полей интерфейса. |
|||||||||||
568 | * |
|||||||||||
569 | * @see AdminBaseHelper::setInterfaceSettings() |
|||||||||||
570 | * |
|||||||||||
571 | * @return array |
|||||||||||
572 | * |
|||||||||||
573 | * @api |
|||||||||||
574 | */ |
|||||||||||
575 | public function getFields() |
|||||||||||
576 | { |
|||||||||||
577 | return $this->fields; |
|||||||||||
578 | } |
|||||||||||
579 | ||||||||||||
580 | /** |
|||||||||||
581 | * Окончательно выводит административную страницу. |
|||||||||||
582 | */ |
|||||||||||
583 | abstract public function show(); |
|||||||||||
584 | ||||||||||||
585 | /** |
|||||||||||
586 | * Получает название таблицы используемой модели. |
|||||||||||
587 | * |
|||||||||||
588 | * @return mixed |
|||||||||||
589 | */ |
|||||||||||
590 | public function table() |
|||||||||||
591 | { |
|||||||||||
592 | /** |
|||||||||||
593 | * @var DataManager $className |
|||||||||||
594 | */ |
|||||||||||
595 | $className = static::getModel(); |
|||||||||||
596 | ||||||||||||
597 | return $className::getTableName(); |
|||||||||||
598 | } |
|||||||||||
599 | ||||||||||||
600 | /** |
|||||||||||
601 | * Возвращает первичный ключ таблицы используемой модели |
|||||||||||
602 | * Для HL-инфоблоков битрикс - всегда ID. Но может поменяться для какой-либо другой сущности. |
|||||||||||
603 | * @return string |
|||||||||||
604 | * @api |
|||||||||||
605 | */ |
|||||||||||
606 | public function pk() |
|||||||||||
607 | { |
|||||||||||
608 | return 'ID'; |
|||||||||||
609 | } |
|||||||||||
610 | ||||||||||||
611 | /** |
|||||||||||
612 | * Возвращает значение первичного ключа таблицы используемой модели |
|||||||||||
613 | * @return array|int|null |
|||||||||||
614 | * |
|||||||||||
615 | * @api |
|||||||||||
616 | */ |
|||||||||||
617 | public function getPk() |
|||||||||||
0 ignored issues
–
show
getPk uses the super-global variable $_REQUEST which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
618 | { |
|||||||||||
619 | return isset($_REQUEST['FIELDS'][$this->pk()]) ? $_REQUEST['FIELDS'][$this->pk()] : $_REQUEST[$this->pk()]; |
|||||||||||
620 | } |
|||||||||||
621 | ||||||||||||
622 | /** |
|||||||||||
623 | * Возвращает первичный ключ таблицы используемой модели разделов. Для HL-инфоблоков битрикс - всегда ID. |
|||||||||||
624 | * Но может поменяться для какой-либо другой сущности. |
|||||||||||
625 | * |
|||||||||||
626 | * @return string |
|||||||||||
627 | * |
|||||||||||
628 | * @api |
|||||||||||
629 | */ |
|||||||||||
630 | public function sectionPk() |
|||||||||||
631 | { |
|||||||||||
632 | return 'ID'; |
|||||||||||
633 | } |
|||||||||||
634 | ||||||||||||
635 | /** |
|||||||||||
636 | * Устанавливает заголовок раздела в админке. |
|||||||||||
637 | * |
|||||||||||
638 | * @param string $title |
|||||||||||
639 | * |
|||||||||||
640 | * @api |
|||||||||||
641 | */ |
|||||||||||
642 | public function setTitle($title) |
|||||||||||
643 | { |
|||||||||||
644 | $this->app->SetTitle($title); |
|||||||||||
645 | } |
|||||||||||
646 | ||||||||||||
647 | /** |
|||||||||||
648 | * Функция для обработки дополнительных операций над элементами в админке. Как правило, должно оканчиваться |
|||||||||||
649 | * LocalRedirect после внесения изменений. |
|||||||||||
650 | * |
|||||||||||
651 | * @param string $action Название действия. |
|||||||||||
652 | * @param null|int $id ID элемента. |
|||||||||||
653 | * |
|||||||||||
654 | * @api |
|||||||||||
655 | */ |
|||||||||||
656 | protected function customActions($action, $id = null) |
|||||||||||
657 | { |
|||||||||||
658 | return; |
|||||||||||
659 | } |
|||||||||||
660 | ||||||||||||
661 | /** |
|||||||||||
662 | * Выполняется проверка прав на доступ к сущности. |
|||||||||||
663 | * |
|||||||||||
664 | * @return bool |
|||||||||||
665 | * |
|||||||||||
666 | * @api |
|||||||||||
667 | */ |
|||||||||||
668 | protected function hasRights() |
|||||||||||
669 | { |
|||||||||||
670 | return true; |
|||||||||||
671 | } |
|||||||||||
672 | ||||||||||||
673 | /** |
|||||||||||
674 | * Выполняется проверка прав на выполнение операций чтения элементов. |
|||||||||||
675 | * |
|||||||||||
676 | * @return bool |
|||||||||||
677 | * |
|||||||||||
678 | * @api |
|||||||||||
679 | */ |
|||||||||||
680 | protected function hasReadRights() |
|||||||||||
681 | { |
|||||||||||
682 | return true; |
|||||||||||
683 | } |
|||||||||||
684 | ||||||||||||
685 | /** |
|||||||||||
686 | * Выполняется проверка прав на выполнение операций редактирования элементов. |
|||||||||||
687 | * |
|||||||||||
688 | * @return bool |
|||||||||||
689 | * |
|||||||||||
690 | * @api |
|||||||||||
691 | */ |
|||||||||||
692 | protected function hasWriteRights() |
|||||||||||
693 | { |
|||||||||||
694 | return true; |
|||||||||||
695 | } |
|||||||||||
696 | ||||||||||||
697 | /** |
|||||||||||
698 | * Проверка прав на изменение определенного элемента. |
|||||||||||
699 | * |
|||||||||||
700 | * @param array $element Массив данных элемента. |
|||||||||||
701 | * |
|||||||||||
702 | * @return bool |
|||||||||||
703 | * |
|||||||||||
704 | * @api |
|||||||||||
705 | */ |
|||||||||||
706 | protected function hasWriteRightsElement($element = array()) |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
707 | { |
|||||||||||
708 | if (!$this->hasWriteRights()) { |
|||||||||||
709 | return false; |
|||||||||||
710 | } |
|||||||||||
711 | ||||||||||||
712 | return true; |
|||||||||||
713 | } |
|||||||||||
714 | ||||||||||||
715 | /** |
|||||||||||
716 | * Выполняется проверка прав на выполнение опреаций удаления элементов. |
|||||||||||
717 | * |
|||||||||||
718 | * @return bool |
|||||||||||
719 | * |
|||||||||||
720 | * @api |
|||||||||||
721 | */ |
|||||||||||
722 | protected function hasDeleteRights() |
|||||||||||
723 | { |
|||||||||||
724 | return true; |
|||||||||||
725 | } |
|||||||||||
726 | ||||||||||||
727 | /** |
|||||||||||
728 | * Выводит сообщения об ошибках. |
|||||||||||
729 | * |
|||||||||||
730 | * @internal |
|||||||||||
731 | */ |
|||||||||||
732 | protected function showMessages() |
|||||||||||
733 | { |
|||||||||||
734 | $allErrors = $this->getErrors(); |
|||||||||||
735 | $notes = $this->getNotes(); |
|||||||||||
736 | ||||||||||||
737 | if (!empty($allErrors)) { |
|||||||||||
738 | $errorList[] = implode("\n", $allErrors); |
|||||||||||
0 ignored issues
–
show
Coding Style
Comprehensibility
introduced
by
$errorList was never initialized. Although not strictly required by PHP, it is generally a good practice to add $errorList = array(); before regardless.
Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code. Let’s take a look at an example: foreach ($collection as $item) {
$myArray['foo'] = $item->getFoo();
if ($item->hasBar()) {
$myArray['bar'] = $item->getBar();
}
// do something with $myArray
}
As you can see in this example, the array This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop. ![]() |
||||||||||||
739 | } |
|||||||||||
740 | if ($e = $this->getLastException()) { |
|||||||||||
741 | $errorList[] = trim($e->GetString()); |
|||||||||||
0 ignored issues
–
show
The variable
$errorList does not seem to be defined for all execution paths leading up to this point.
If you define a variable conditionally, it can happen that it is not defined for all execution paths. Let’s take a look at an example: function myFunction($a) {
switch ($a) {
case 'foo':
$x = 1;
break;
case 'bar':
$x = 2;
break;
}
// $x is potentially undefined here.
echo $x;
}
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined. Available Fixes
![]() |
||||||||||||
742 | } |
|||||||||||
743 | ||||||||||||
744 | if (!empty($errorList)) { |
|||||||||||
745 | $errorText = implode("\n\n", $errorList); |
|||||||||||
746 | \CAdminMessage::ShowOldStyleError($errorText); |
|||||||||||
747 | } |
|||||||||||
748 | else { |
|||||||||||
749 | if (!empty($notes)) { |
|||||||||||
750 | $noteText = implode("\n\n", $notes); |
|||||||||||
751 | \CAdminMessage::ShowNote($noteText); |
|||||||||||
752 | } |
|||||||||||
753 | } |
|||||||||||
754 | } |
|||||||||||
755 | ||||||||||||
756 | /** |
|||||||||||
757 | * @return bool|\CApplicationException |
|||||||||||
758 | * |
|||||||||||
759 | * @internal |
|||||||||||
760 | */ |
|||||||||||
761 | View Code Duplication | protected function getLastException() |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() getLastException uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
762 | { |
|||||||||||
763 | if (isset($_SESSION['APPLICATION_EXCEPTION']) AND !empty($_SESSION['APPLICATION_EXCEPTION'])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
764 | /** @var CApplicationException $e */ |
|||||||||||
765 | $e = $_SESSION['APPLICATION_EXCEPTION']; |
|||||||||||
766 | unset($_SESSION['APPLICATION_EXCEPTION']); |
|||||||||||
767 | ||||||||||||
768 | return $e; |
|||||||||||
769 | } |
|||||||||||
770 | else { |
|||||||||||
771 | return false; |
|||||||||||
772 | } |
|||||||||||
773 | } |
|||||||||||
774 | ||||||||||||
775 | /** |
|||||||||||
776 | * @param $e |
|||||||||||
777 | */ |
|||||||||||
778 | protected function setAppException($e) |
|||||||||||
0 ignored issues
–
show
setAppException uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
779 | { |
|||||||||||
780 | $_SESSION['APPLICATION_EXCEPTION'] = $e; |
|||||||||||
781 | } |
|||||||||||
782 | ||||||||||||
783 | /** |
|||||||||||
784 | * Добавляет ошибку или массив ошибок для показа пользователю. |
|||||||||||
785 | * |
|||||||||||
786 | * @param array|string $errors |
|||||||||||
787 | * |
|||||||||||
788 | * @api |
|||||||||||
789 | */ |
|||||||||||
790 | View Code Duplication | public function addErrors($errors) |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() addErrors uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
791 | { |
|||||||||||
792 | if (!is_array($errors)) { |
|||||||||||
793 | $errors = array($errors); |
|||||||||||
794 | } |
|||||||||||
795 | ||||||||||||
796 | if (isset($_SESSION['ELEMENT_SAVE_ERRORS']) AND !empty($_SESSION['ELEMENT_SAVE_ERRORS'])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
797 | $_SESSION['ELEMENT_SAVE_ERRORS'] = array_merge($_SESSION['ELEMENT_SAVE_ERRORS'], $errors); |
|||||||||||
798 | } |
|||||||||||
799 | else { |
|||||||||||
800 | $_SESSION['ELEMENT_SAVE_ERRORS'] = $errors; |
|||||||||||
801 | } |
|||||||||||
802 | } |
|||||||||||
803 | ||||||||||||
804 | /** |
|||||||||||
805 | * Добавляет уведомление или список уведомлений для показа пользователю. |
|||||||||||
806 | * |
|||||||||||
807 | * @param array|string $notes |
|||||||||||
808 | * |
|||||||||||
809 | * @api |
|||||||||||
810 | */ |
|||||||||||
811 | View Code Duplication | public function addNotes($notes) |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() addNotes uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
812 | { |
|||||||||||
813 | if (!is_array($notes)) { |
|||||||||||
814 | $notes = array($notes); |
|||||||||||
815 | } |
|||||||||||
816 | ||||||||||||
817 | if (isset($_SESSION['ELEMENT_SAVE_NOTES']) AND !empty($_SESSION['ELEMENT_SAVE_NOTES'])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
818 | $_SESSION['ELEMENT_SAVE_NOTES'] = array_merge($_SESSION['ELEMENT_SAVE_NOTES'], |
|||||||||||
819 | $notes); |
|||||||||||
820 | } |
|||||||||||
821 | else { |
|||||||||||
822 | $_SESSION['ELEMENT_SAVE_NOTES'] = $notes; |
|||||||||||
823 | } |
|||||||||||
824 | } |
|||||||||||
825 | ||||||||||||
826 | /** |
|||||||||||
827 | * @return bool|array |
|||||||||||
828 | * |
|||||||||||
829 | * @api |
|||||||||||
830 | */ |
|||||||||||
831 | View Code Duplication | protected function getErrors() |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() getErrors uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
832 | { |
|||||||||||
833 | if (isset($_SESSION['ELEMENT_SAVE_ERRORS']) AND !empty($_SESSION['ELEMENT_SAVE_ERRORS'])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
834 | $errors = $_SESSION['ELEMENT_SAVE_ERRORS']; |
|||||||||||
835 | unset($_SESSION['ELEMENT_SAVE_ERRORS']); |
|||||||||||
836 | ||||||||||||
837 | return $errors; |
|||||||||||
838 | } |
|||||||||||
839 | else { |
|||||||||||
840 | return false; |
|||||||||||
841 | } |
|||||||||||
842 | } |
|||||||||||
843 | ||||||||||||
844 | /** |
|||||||||||
845 | * @return bool |
|||||||||||
846 | * |
|||||||||||
847 | * @api |
|||||||||||
848 | */ |
|||||||||||
849 | View Code Duplication | protected function getNotes() |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() getNotes uses the super-global variable $_SESSION which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
850 | { |
|||||||||||
851 | if (isset($_SESSION['ELEMENT_SAVE_NOTES']) AND !empty($_SESSION['ELEMENT_SAVE_NOTES'])) { |
|||||||||||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
Using logical operators such as
and instead of && is generally not recommended.
PHP has two types of connecting operators (logical operators, and boolean operators):
The difference between these is the order in which they are executed. In most cases,
you would want to use a boolean operator like Let’s take a look at a few examples: // Logical operators have lower precedence:
$f = false or true;
// is executed like this:
($f = false) or true;
// Boolean operators have higher precedence:
$f = false || true;
// is executed like this:
$f = (false || true);
Logical Operators are used for Control-FlowOne case where you explicitly want to use logical operators is for control-flow such as this: $x === 5
or die('$x must be 5.');
// Instead of
if ($x !== 5) {
die('$x must be 5.');
}
Since // The following is currently a parse error.
$x === 5
or throw new RuntimeException('$x must be 5.');
These limitations lead to logical operators rarely being of use in current PHP code. ![]() |
||||||||||||
852 | $notes = $_SESSION['ELEMENT_SAVE_NOTES']; |
|||||||||||
853 | unset($_SESSION['ELEMENT_SAVE_NOTES']); |
|||||||||||
854 | ||||||||||||
855 | return $notes; |
|||||||||||
856 | } |
|||||||||||
857 | else { |
|||||||||||
858 | return false; |
|||||||||||
859 | } |
|||||||||||
860 | } |
|||||||||||
861 | ||||||||||||
862 | /** |
|||||||||||
863 | * Возвращает класс хелпера нужного типа из всех зарегистрированных хелперов в модуле и находящихся |
|||||||||||
864 | * в том же неймспейсе что класс хелпера из которого вызван этот метод |
|||||||||||
865 | * |
|||||||||||
866 | * Под типом понимается ближайший родитель из модуля AdminHelper. |
|||||||||||
867 | * |
|||||||||||
868 | * Например если нам нужно получить ListHelper для формирования ссылки на список из EditHelper, |
|||||||||||
869 | * то это будет вглядеть так $listHelperClass = static::getHelperClass(AdminListHelper::getClass()) |
|||||||||||
870 | * |
|||||||||||
871 | * @param $class |
|||||||||||
872 | * |
|||||||||||
873 | * @return string|bool |
|||||||||||
874 | */ |
|||||||||||
875 | public function getHelperClass($class) |
|||||||||||
876 | { |
|||||||||||
877 | $interfaceSettings = self::$interfaceSettings[static::getModule()]; |
|||||||||||
878 | ||||||||||||
879 | foreach ($interfaceSettings as $viewName => $settings) { |
|||||||||||
880 | $parentClasses = class_parents($settings['helper']); |
|||||||||||
881 | array_pop($parentClasses); // AdminBaseHelper |
|||||||||||
882 | ||||||||||||
883 | $parentClass = array_pop($parentClasses); |
|||||||||||
884 | $thirdClass = array_pop($parentClasses); |
|||||||||||
885 | ||||||||||||
886 | if (in_array($thirdClass, array(AdminSectionListHelper::className(), AdminSectionEditHelper::className()))) { |
|||||||||||
887 | $parentClass = $thirdClass; |
|||||||||||
888 | } |
|||||||||||
889 | ||||||||||||
890 | if ($parentClass == $class && class_exists($settings['helper'])) { |
|||||||||||
891 | $helperClassParts = explode('\\', $settings['helper']); |
|||||||||||
892 | array_pop($helperClassParts); |
|||||||||||
893 | $helperNamespace = implode('\\', $helperClassParts); |
|||||||||||
894 | ||||||||||||
895 | $сlassParts = explode('\\', get_called_class()); |
|||||||||||
896 | array_pop($сlassParts); |
|||||||||||
897 | $classNamespace = implode('\\', $сlassParts); |
|||||||||||
898 | ||||||||||||
899 | if ($helperNamespace == $classNamespace) { |
|||||||||||
900 | return $settings['helper']; |
|||||||||||
901 | } |
|||||||||||
902 | } |
|||||||||||
903 | } |
|||||||||||
904 | ||||||||||||
905 | return false; |
|||||||||||
906 | } |
|||||||||||
907 | ||||||||||||
908 | /** |
|||||||||||
909 | * Возвращает относительный namespace до хелперов в виде URL параметра. |
|||||||||||
910 | * |
|||||||||||
911 | * @return string |
|||||||||||
912 | */ |
|||||||||||
913 | public static function getEntityCode() |
|||||||||||
914 | { |
|||||||||||
915 | $namespaceParts = explode('\\', get_called_class()); |
|||||||||||
916 | array_pop($namespaceParts); |
|||||||||||
917 | array_shift($namespaceParts); |
|||||||||||
918 | array_shift($namespaceParts); |
|||||||||||
919 | ||||||||||||
920 | if (end($namespaceParts) == 'AdminInterface') { |
|||||||||||
921 | array_pop($namespaceParts); |
|||||||||||
922 | } |
|||||||||||
923 | ||||||||||||
924 | return str_replace( |
|||||||||||
925 | '\\', |
|||||||||||
926 | '_', |
|||||||||||
927 | implode( |
|||||||||||
928 | '\\', |
|||||||||||
929 | array_map('lcfirst', $namespaceParts) |
|||||||||||
930 | ) |
|||||||||||
931 | ); |
|||||||||||
932 | } |
|||||||||||
933 | ||||||||||||
934 | /** |
|||||||||||
935 | * Возвращает URL страницы редактирования класса данного представления. |
|||||||||||
936 | * |
|||||||||||
937 | * @param array $params |
|||||||||||
938 | * |
|||||||||||
939 | * @return string |
|||||||||||
940 | * |
|||||||||||
941 | * @api |
|||||||||||
942 | */ |
|||||||||||
943 | View Code Duplication | public static function getEditPageURL($params = array()) |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
944 | { |
|||||||||||
945 | $editHelperClass = str_replace('List', 'Edit', get_called_class()); |
|||||||||||
946 | if (empty(static::$editViewName) && class_exists($editHelperClass)) { |
|||||||||||
947 | return $editHelperClass::getViewURL($editHelperClass::getViewName(), static::$editPageUrl, $params); |
|||||||||||
948 | } |
|||||||||||
949 | else { |
|||||||||||
950 | return static::getViewURL(static::$editViewName, static::$editPageUrl, $params); |
|||||||||||
951 | } |
|||||||||||
952 | } |
|||||||||||
953 | ||||||||||||
954 | /** |
|||||||||||
955 | * Возвращает URL страницы редактирования класса данного представления. |
|||||||||||
956 | * |
|||||||||||
957 | * @param array $params |
|||||||||||
958 | * |
|||||||||||
959 | * @return string |
|||||||||||
960 | * |
|||||||||||
961 | * @api |
|||||||||||
962 | */ |
|||||||||||
963 | View Code Duplication | public static function getSectionsEditPageURL($params = array()) |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
964 | { |
|||||||||||
965 | $sectionEditHelperClass = str_replace('List', 'SectionsEdit', get_called_class()); |
|||||||||||
966 | ||||||||||||
967 | if (empty(static::$sectionsEditViewName) && class_exists($sectionEditHelperClass)) { |
|||||||||||
968 | return $sectionEditHelperClass::getViewURL($sectionEditHelperClass::getViewName(), static::$sectionsEditPageUrl, $params); |
|||||||||||
969 | } |
|||||||||||
970 | else { |
|||||||||||
971 | return static::getViewURL(static::$sectionsEditViewName, static::$sectionsEditPageUrl, $params); |
|||||||||||
972 | } |
|||||||||||
973 | } |
|||||||||||
974 | ||||||||||||
975 | /** |
|||||||||||
976 | * Возвращает URL страницы списка класса данного представления. |
|||||||||||
977 | * |
|||||||||||
978 | * @param array $params |
|||||||||||
979 | * |
|||||||||||
980 | * @return string |
|||||||||||
981 | * |
|||||||||||
982 | * @api |
|||||||||||
983 | */ |
|||||||||||
984 | View Code Duplication | public static function getListPageURL($params = array()) |
||||||||||
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
985 | { |
|||||||||||
986 | $listHelperClass = str_replace('Edit', 'List', get_called_class()); |
|||||||||||
987 | ||||||||||||
988 | if (empty(static::$listViewName) && class_exists($listHelperClass)) { |
|||||||||||
989 | return $listHelperClass::getViewURL($listHelperClass::getViewName(), static::$listPageUrl, $params); |
|||||||||||
990 | } |
|||||||||||
991 | else { |
|||||||||||
992 | return static::getViewURL(static::$listViewName, static::$listPageUrl, $params); |
|||||||||||
993 | } |
|||||||||||
994 | } |
|||||||||||
995 | ||||||||||||
996 | /** |
|||||||||||
997 | * Получает URL для указанного представления |
|||||||||||
998 | * |
|||||||||||
999 | * @param string $viewName Название представления. |
|||||||||||
1000 | * @param string $defaultURL Позволяет указать URL напрямую. Если указано, то будет использовано это значение. |
|||||||||||
1001 | * @param array $params Дополнительные query-параметры в URL. |
|||||||||||
1002 | * |
|||||||||||
1003 | * @return string |
|||||||||||
1004 | * |
|||||||||||
1005 | * @internal |
|||||||||||
1006 | */ |
|||||||||||
1007 | public static function getViewURL($viewName, $defaultURL, $params = array()) |
|||||||||||
1008 | { |
|||||||||||
1009 | $params['entity'] = static::getEntityCode(); |
|||||||||||
1010 | ||||||||||||
1011 | if (isset($defaultURL)) { |
|||||||||||
1012 | $url = $defaultURL . "?lang=" . LANGUAGE_ID; |
|||||||||||
1013 | } |
|||||||||||
1014 | else { |
|||||||||||
1015 | $url = static::getRouterURL() . '?lang=' . LANGUAGE_ID . '&module=' . static::getModule() . '&view=' . $viewName; |
|||||||||||
1016 | } |
|||||||||||
1017 | ||||||||||||
1018 | if (!empty($params)) { |
|||||||||||
1019 | unset($params['lang']); |
|||||||||||
1020 | unset($params['module']); |
|||||||||||
1021 | unset($params['view']); |
|||||||||||
1022 | ||||||||||||
1023 | $query = http_build_query($params); |
|||||||||||
1024 | $url .= '&' . $query; |
|||||||||||
1025 | } |
|||||||||||
1026 | ||||||||||||
1027 | return $url; |
|||||||||||
1028 | } |
|||||||||||
1029 | ||||||||||||
1030 | /** |
|||||||||||
1031 | * Возвращает адрес обработчика запросов к админ. интерфейсу. |
|||||||||||
1032 | * |
|||||||||||
1033 | * @return string |
|||||||||||
1034 | * |
|||||||||||
1035 | * @api |
|||||||||||
1036 | */ |
|||||||||||
1037 | public static function getRouterURL() |
|||||||||||
1038 | { |
|||||||||||
1039 | return static::$routerUrl; |
|||||||||||
1040 | } |
|||||||||||
1041 | ||||||||||||
1042 | /** |
|||||||||||
1043 | * Возвращает URL страницы с хелпером. Как правило, метод вызывается при генерации административного |
|||||||||||
1044 | * меню (`menu.php`). |
|||||||||||
1045 | * |
|||||||||||
1046 | * @param array $params Дополнительные GET-параметры для подстановки в URL. |
|||||||||||
1047 | * |
|||||||||||
1048 | * @return string |
|||||||||||
1049 | */ |
|||||||||||
1050 | public static function getUrl(array $params = array()) |
|||||||||||
1051 | { |
|||||||||||
1052 | return static::getViewURL(static::getViewName(), null, $params); |
|||||||||||
1053 | } |
|||||||||||
1054 | ||||||||||||
1055 | /** |
|||||||||||
1056 | * Получает виджет для текущего поля, выполняет базовую инициализацию. |
|||||||||||
1057 | * |
|||||||||||
1058 | * @param string $code Ключ поля для данного виджета (должен быть в массиве $data). |
|||||||||||
1059 | * @param array $data Данные объекта в виде массива. |
|||||||||||
1060 | * |
|||||||||||
1061 | * @return bool|\DigitalWand\AdminHelper\Widget\HelperWidget |
|||||||||||
1062 | * |
|||||||||||
1063 | * @throws \DigitalWand\AdminHelper\Helper\Exception |
|||||||||||
1064 | * |
|||||||||||
1065 | * @internal |
|||||||||||
1066 | */ |
|||||||||||
1067 | public function createWidgetForField($code, &$data = array()) |
|||||||||||
1068 | { |
|||||||||||
1069 | View Code Duplication | if (!isset($this->fields[$code]['WIDGET'])) { |
||||||||||
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
||||||||||||
1070 | $error = str_replace('#CODE#', $code, 'Can\'t create widget for the code "#CODE#"'); |
|||||||||||
1071 | throw new Exception($error, Exception::CODE_NO_WIDGET); |
|||||||||||
1072 | } |
|||||||||||
1073 | ||||||||||||
1074 | /** @var HelperWidget $widget */ |
|||||||||||
1075 | $widget = $this->fields[$code]['WIDGET']; |
|||||||||||
1076 | ||||||||||||
1077 | $widget->setHelper($this); |
|||||||||||
1078 | $widget->setCode($code); |
|||||||||||
1079 | $widget->setData($data); |
|||||||||||
1080 | $widget->setEntityName($this->getModel()); |
|||||||||||
0 ignored issues
–
show
$this->getModel() is of type object<Bitrix\Highloadblock\DataManager>|null , but the function expects a string .
It seems like the type of the argument is not accepted by the function/method which you are calling. In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug. We suggest to add an explicit type cast like in the following example: function acceptsInteger($int) { }
$x = '123'; // string "123"
// Instead of
acceptsInteger($x);
// we recommend to use
acceptsInteger((integer) $x);
![]() |
||||||||||||
1081 | ||||||||||||
1082 | $this->onCreateWidgetForField($widget, $data); |
|||||||||||
1083 | ||||||||||||
1084 | if (!$this->hasWriteRightsElement($data)) { |
|||||||||||
1085 | $widget->setSetting('READONLY', true); |
|||||||||||
1086 | } |
|||||||||||
1087 | ||||||||||||
1088 | return $widget; |
|||||||||||
1089 | } |
|||||||||||
1090 | ||||||||||||
1091 | /** |
|||||||||||
1092 | * Метод вызывается при создании виджета для текущего поля. Может быть использован для изменения настроек виджета |
|||||||||||
1093 | * на основе передаваемых данных. |
|||||||||||
1094 | * |
|||||||||||
1095 | * @param \DigitalWand\AdminHelper\Widget\HelperWidget $widget |
|||||||||||
1096 | * @param array $data |
|||||||||||
1097 | */ |
|||||||||||
1098 | protected function onCreateWidgetForField(&$widget, $data = array()) |
|||||||||||
0 ignored issues
–
show
|
||||||||||||
1099 | { |
|||||||||||
1100 | } |
|||||||||||
1101 | ||||||||||||
1102 | /** |
|||||||||||
1103 | * Если класс не объявлен, то битрикс генерирует новый класс в рантайме. Если класс уже есть, то возвращаем имя |
|||||||||||
1104 | * как есть. |
|||||||||||
1105 | * |
|||||||||||
1106 | * @param $className |
|||||||||||
1107 | * @return \Bitrix\Highloadblock\DataManager |
|||||||||||
1108 | * |
|||||||||||
1109 | * @throws \Bitrix\Main\ArgumentException |
|||||||||||
1110 | * @throws \Bitrix\Main\SystemException |
|||||||||||
1111 | * @throws Exception |
|||||||||||
1112 | */ |
|||||||||||
1113 | public static function getHLEntity($className) |
|||||||||||
1114 | { |
|||||||||||
1115 | if (!class_exists($className)) { |
|||||||||||
1116 | $info = static::getHLEntityInfo($className); |
|||||||||||
1117 | ||||||||||||
1118 | if ($info) { |
|||||||||||
1119 | $entity = HL\HighloadBlockTable::compileEntity($info); |
|||||||||||
1120 | ||||||||||||
1121 | return $entity->getDataClass(); |
|||||||||||
1122 | } |
|||||||||||
1123 | else { |
|||||||||||
1124 | $error = Loc::getMessage('DIGITALWAND_ADMIN_HELPER_GETMODEL_EXCEPTION', array('#CLASS#' => $className)); |
|||||||||||
1125 | $exception = new Exception($error, Exception::CODE_NO_HL_ENTITY_INFORMATION); |
|||||||||||
1126 | ||||||||||||
1127 | throw $exception; |
|||||||||||
1128 | } |
|||||||||||
1129 | } |
|||||||||||
1130 | ||||||||||||
1131 | return $className; |
|||||||||||
1132 | } |
|||||||||||
1133 | ||||||||||||
1134 | /** |
|||||||||||
1135 | * Получает запись из БД с информацией об HL. |
|||||||||||
1136 | * |
|||||||||||
1137 | * @param string $className Название класса, обязательно без Table в конце и без указания неймспейса. |
|||||||||||
1138 | * |
|||||||||||
1139 | * @return array|false |
|||||||||||
1140 | * |
|||||||||||
1141 | * @throws \Bitrix\Main\ArgumentException |
|||||||||||
1142 | */ |
|||||||||||
1143 | public static function getHLEntityInfo($className) |
|||||||||||
1144 | { |
|||||||||||
1145 | $className = str_replace('\\', '', $className); |
|||||||||||
1146 | $pos = strripos($className, 'Table', -5); |
|||||||||||
1147 | ||||||||||||
1148 | if ($pos !== false) { |
|||||||||||
1149 | $className = substr($className, 0, $pos); |
|||||||||||
1150 | } |
|||||||||||
1151 | ||||||||||||
1152 | $parameters = array( |
|||||||||||
1153 | 'filter' => array( |
|||||||||||
1154 | 'NAME' => $className, |
|||||||||||
1155 | ), |
|||||||||||
1156 | 'limit' => 1 |
|||||||||||
1157 | ); |
|||||||||||
1158 | ||||||||||||
1159 | return HL\HighloadBlockTable::getList($parameters)->fetch(); |
|||||||||||
1160 | } |
|||||||||||
1161 | ||||||||||||
1162 | /** |
|||||||||||
1163 | * Отобразить страницу 404 ошибка |
|||||||||||
1164 | */ |
|||||||||||
1165 | protected function show404() |
|||||||||||
0 ignored issues
–
show
show404 uses the super-global variable $_SERVER which is generally not recommended.
Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable: // Bad
class Router
{
public function generate($path)
{
return $_SERVER['HOST'].$path;
}
}
// Better
class Router
{
private $host;
public function __construct($host)
{
$this->host = $host;
}
public function generate($path)
{
return $this->host.$path;
}
}
class Controller
{
public function myAction(Request $request)
{
// Instead of
$page = isset($_GET['page']) ? intval($_GET['page']) : 1;
// Better (assuming you use the Symfony2 request)
$page = $request->query->get('page', 1);
}
}
![]() |
||||||||||||
1166 | { |
|||||||||||
1167 | // инициализация глобальных переменных, необходимых для вывода страницы административного раздела в |
|||||||||||
1168 | // текущей области видимости |
|||||||||||
1169 | global $APPLICATION, $adminPage, $adminMenu, $USER; |
|||||||||||
0 ignored issues
–
show
Compatibility
Best Practice
introduced
by
Use of
global functionality is not recommended; it makes your code harder to test, and less reusable.
Instead of relying on 1. Pass all data via parametersfunction myFunction($a, $b) {
// Do something
}
2. Create a class that maintains your stateclass MyClass {
private $a;
private $b;
public function __construct($a, $b) {
$this->a = $a;
$this->b = $b;
}
public function myFunction() {
// Do something
}
}
![]() |
||||||||||||
1170 | \CHTTP::SetStatus(404); |
|||||||||||
1171 | include $_SERVER['DOCUMENT_ROOT'] . BX_ROOT . '/admin/404.php'; |
|||||||||||
1172 | die(); |
|||||||||||
0 ignored issues
–
show
The method
show404() contains an exit expression.
An exit expression should only be used in rare cases. For example, if you write a short command line script. In most cases however, using an ![]() |
||||||||||||
1173 | } |
|||||||||||
1174 | ||||||||||||
1175 | /** |
|||||||||||
1176 | * Выставляет текущий контекст исполнения. |
|||||||||||
1177 | * |
|||||||||||
1178 | * @param $context |
|||||||||||
1179 | * |
|||||||||||
1180 | * @see $context |
|||||||||||
1181 | */ |
|||||||||||
1182 | protected function setContext($context) |
|||||||||||
1183 | { |
|||||||||||
1184 | $this->context = $context; |
|||||||||||
1185 | } |
|||||||||||
1186 | ||||||||||||
1187 | public function getContext() |
|||||||||||
1188 | { |
|||||||||||
1189 | return $this->context; |
|||||||||||
1190 | } |
|||||||||||
1191 | ||||||||||||
1192 | public static function className() |
|||||||||||
1193 | { |
|||||||||||
1194 | return get_called_class(); |
|||||||||||
1195 | } |
|||||||||||
1196 | } |
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.