Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like AdminBaseHelper often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use AdminBaseHelper, and based on these observations, apply Extract Interface, too.
1 | <?php |
||
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 = "") |
||
291 | |||
292 | /** |
||
293 | * @param string $viewName Имя вьюхи, для которой мы хотим получить натсройки |
||
294 | * |
||
295 | * @return array Возвращает настройки интерфейса для данного класса. |
||
296 | * |
||
297 | * @see AdminBaseHelper::setInterfaceSettings() |
||
298 | * @api |
||
299 | */ |
||
300 | public static function getInterfaceSettings($viewName = '') |
||
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 = '') |
||
333 | |||
334 | /** |
||
335 | * Привязывает класса хелпера из которого вызывается к интерфесу, используется при получении |
||
336 | * данных об элементах управления из интерфейса. |
||
337 | * |
||
338 | * @param $class |
||
339 | */ |
||
340 | public static function setInterfaceClass($class) |
||
344 | |||
345 | /** |
||
346 | * Возвращает класс интерфейса к которому привязан хелпер из которого вызван метод. |
||
347 | * |
||
348 | * @return array |
||
349 | */ |
||
350 | public static function getInterfaceClass() |
||
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) |
||
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) |
||
406 | |||
407 | /** |
||
408 | * Возвращает имя текущего представления. |
||
409 | * |
||
410 | * @return string |
||
411 | * @api |
||
412 | */ |
||
413 | public static function getViewName() |
||
439 | |||
440 | /** |
||
441 | * Возвращает поле модели которое используется для привязки к разделу из поля с типом совпадающим с классом модели |
||
442 | * раздела. |
||
443 | * @return string |
||
444 | * @throws Exception |
||
445 | */ |
||
446 | public static function getSectionField() |
||
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() |
||
485 | |||
486 | /** |
||
487 | * Возвращает имя модуля. Если оно не задано, то определяет автоматически из namespace класса. |
||
488 | * |
||
489 | * @return string |
||
490 | * |
||
491 | * @throws LoaderException |
||
492 | * @api |
||
493 | */ |
||
494 | public static function getModule() |
||
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')) |
||
565 | |||
566 | /** |
||
567 | * Возвращает список полей интерфейса. |
||
568 | * |
||
569 | * @see AdminBaseHelper::setInterfaceSettings() |
||
570 | * |
||
571 | * @return array |
||
572 | * |
||
573 | * @api |
||
574 | */ |
||
575 | public function getFields() |
||
579 | |||
580 | /** |
||
581 | * Окончательно выводит административную страницу. |
||
582 | */ |
||
583 | abstract public function show(); |
||
584 | |||
585 | /** |
||
586 | * Получает название таблицы используемой модели. |
||
587 | * |
||
588 | * @return mixed |
||
589 | */ |
||
590 | public function table() |
||
599 | |||
600 | /** |
||
601 | * Возвращает первичный ключ таблицы используемой модели |
||
602 | * Для HL-инфоблоков битрикс - всегда ID. Но может поменяться для какой-либо другой сущности. |
||
603 | * @return string |
||
604 | * @api |
||
605 | */ |
||
606 | public function pk() |
||
610 | |||
611 | /** |
||
612 | * Возвращает значение первичного ключа таблицы используемой модели |
||
613 | * @return array|int|null |
||
614 | * |
||
615 | * @api |
||
616 | */ |
||
617 | public function getPk() |
||
621 | |||
622 | /** |
||
623 | * Возвращает первичный ключ таблицы используемой модели разделов. Для HL-инфоблоков битрикс - всегда ID. |
||
624 | * Но может поменяться для какой-либо другой сущности. |
||
625 | * |
||
626 | * @return string |
||
627 | * |
||
628 | * @api |
||
629 | */ |
||
630 | public function sectionPk() |
||
634 | |||
635 | /** |
||
636 | * Устанавливает заголовок раздела в админке. |
||
637 | * |
||
638 | * @param string $title |
||
639 | * |
||
640 | * @api |
||
641 | */ |
||
642 | public function setTitle($title) |
||
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) |
||
660 | |||
661 | /** |
||
662 | * Выполняется проверка прав на доступ к сущности. |
||
663 | * |
||
664 | * @return bool |
||
665 | * |
||
666 | * @api |
||
667 | */ |
||
668 | protected function hasRights() |
||
672 | |||
673 | /** |
||
674 | * Выполняется проверка прав на выполнение операций чтения элементов. |
||
675 | * |
||
676 | * @return bool |
||
677 | * |
||
678 | * @api |
||
679 | */ |
||
680 | protected function hasReadRights() |
||
684 | |||
685 | /** |
||
686 | * Выполняется проверка прав на выполнение операций редактирования элементов. |
||
687 | * |
||
688 | * @return bool |
||
689 | * |
||
690 | * @api |
||
691 | */ |
||
692 | protected function hasWriteRights() |
||
696 | |||
697 | /** |
||
698 | * Проверка прав на изменение определенного элемента. |
||
699 | * |
||
700 | * @param array $element Массив данных элемента. |
||
701 | * |
||
702 | * @return bool |
||
703 | * |
||
704 | * @api |
||
705 | */ |
||
706 | protected function hasWriteRightsElement($element = array()) |
||
714 | |||
715 | /** |
||
716 | * Выполняется проверка прав на выполнение опреаций удаления элементов. |
||
717 | * |
||
718 | * @return bool |
||
719 | * |
||
720 | * @api |
||
721 | */ |
||
722 | protected function hasDeleteRights() |
||
726 | |||
727 | /** |
||
728 | * Выводит сообщения об ошибках. |
||
729 | * |
||
730 | * @internal |
||
731 | */ |
||
732 | protected function showMessages() |
||
755 | |||
756 | /** |
||
757 | * @return bool|\CApplicationException |
||
758 | * |
||
759 | * @internal |
||
760 | */ |
||
761 | View Code Duplication | protected function getLastException() |
|
774 | |||
775 | /** |
||
776 | * @param $e |
||
777 | */ |
||
778 | protected function setAppException($e) |
||
782 | |||
783 | /** |
||
784 | * Добавляет ошибку или массив ошибок для показа пользователю. |
||
785 | * |
||
786 | * @param array|string $errors |
||
787 | * |
||
788 | * @api |
||
789 | */ |
||
790 | View Code Duplication | public function addErrors($errors) |
|
803 | |||
804 | /** |
||
805 | * Добавляет уведомление или список уведомлений для показа пользователю. |
||
806 | * |
||
807 | * @param array|string $notes |
||
808 | * |
||
809 | * @api |
||
810 | */ |
||
811 | View Code Duplication | public function addNotes($notes) |
|
825 | |||
826 | /** |
||
827 | * @return bool|array |
||
828 | * |
||
829 | * @api |
||
830 | */ |
||
831 | View Code Duplication | protected function getErrors() |
|
843 | |||
844 | /** |
||
845 | * @return bool |
||
846 | * |
||
847 | * @api |
||
848 | */ |
||
849 | View Code Duplication | protected function getNotes() |
|
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) |
||
907 | |||
908 | /** |
||
909 | * Возвращает относительный namespace до хелперов в виде URL параметра. |
||
910 | * |
||
911 | * @return string |
||
912 | */ |
||
913 | public static function getEntityCode() |
||
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()) |
|
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()) |
|
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()) |
|
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()) |
||
1029 | |||
1030 | /** |
||
1031 | * Возвращает адрес обработчика запросов к админ. интерфейсу. |
||
1032 | * |
||
1033 | * @return string |
||
1034 | * |
||
1035 | * @api |
||
1036 | */ |
||
1037 | public static function getRouterURL() |
||
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()) |
||
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()) |
||
1090 | |||
1091 | /** |
||
1092 | * Метод вызывается при создании виджета для текущего поля. Может быть использован для изменения настроек виджета |
||
1093 | * на основе передаваемых данных. |
||
1094 | * |
||
1095 | * @param \DigitalWand\AdminHelper\Widget\HelperWidget $widget |
||
1096 | * @param array $data |
||
1097 | */ |
||
1098 | protected function onCreateWidgetForField(&$widget, $data = array()) |
||
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) |
||
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) |
||
1161 | |||
1162 | /** |
||
1163 | * Отобразить страницу 404 ошибка |
||
1164 | */ |
||
1165 | protected function show404() |
||
1174 | |||
1175 | /** |
||
1176 | * Выставляет текущий контекст исполнения. |
||
1177 | * |
||
1178 | * @param $context |
||
1179 | * |
||
1180 | * @see $context |
||
1181 | */ |
||
1182 | protected function setContext($context) |
||
1186 | |||
1187 | public function getContext() |
||
1191 | |||
1192 | public static function className() |
||
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.