📜 ⬆️ ⬇️

OOP constructor admin for Bitrix

The more seriously we take our projects, the more we want our tasks to be solved in the best possible way. For example, we want to provide the client with a quality admin panel in adequate time. Personally, at such moments I immediately recall Django: created a model - get an admin panel. Or widgets in Yii. Or a wonderful combination of hooks and classes in Drupal 7. Or Sonata in Symfony, about which I, however, only heard. And what if we got Beatrix?

Admin bitrobrikomu "feng shui"


Unfortunately, Bitriks, despite the attempts of developers to somehow fix the situation, in many of its aspects remains an archaic system: procedural pieces of code in a few hundred lines, copy-paste built to the level of a manual, classes from which it is impossible to inherit normally the day remains a reality for those who have to work with this system. And I am sure that this will not happen soon.

What should the developer do if he needs to create an administrative interface for any custom table in the database? According to the manual, we need to copy the “fish” with a code of 417 lines for the item list page and 365 lines for the item edit page. Well, or write everything yourself, if we are happy owners of phenomenal memory. Well, 2016 is a good start to the yard!

But we still have nothing working! After we have completed the copy-paste act, we need to carefully subtract 782 lines of code, delete all unnecessary and add our own. Namely:
')
  1. Write validation data filters.
  2. Specify the list of columns for filtering the selection.
  3. Write processing actions on a single element and on a group of list elements.
  4. Make the sample itself. And usually no one is soared, they just make SELECT * FROM ... - in the “fish” from the bitrix, it is not proposed to limit the list of selectable fields to only those that are necessary.
  5. Specify a list of columns to display in the list.
  6. In the process of displaying the list for each column to display a specific control.
  7. Print the table footer.
  8. Print the filter above the table.

This is for a list page. I specifically pointed out the points not in the order in which the logic prompts, and in which they are displayed on the resulting page, but in the order in which this code is found in the “fish” from the manual.

Now, what do we need to do if we decide to, say, add another field to the list? Or even just rename some existing one? We have to register this new field in 7 places or change the existing one without ever making a mistake! The situation is complicated by the fact that along with the php-code in the same file goes html, moreover, completely not in the order in which it appears on the page, unreadable neither by your favorite IDE, nor by the human eye, because many tags are generated somewhere in the depths. This is all very difficult to navigate. Especially when the page is not at all simple and it also contains a JS-code, usually written inline.

What do we get in the end? Bugs. Difficulty of support. Unnecessarily high time costs, even when changing any little things. For the item edit page, the situation is the same. Sincerely I do not understand how so many years it was possible to chew such a cactus?

How could it be


Oddly enough, the API for the admin at Bitrix is ​​designed well. After the above horrors, it is hard to believe, but it really is. Because the problem is not in the API itself, but in how it was later used. One gets the impression that the developer (s) of the API had some plans for the future about him, or simply some vague insights, but they didn’t make a simple and logical next step: creating a set of MVC classes. Probably the reason for this is the absence until recently of a single interface for working with the database.

After viewing a great number of self-administered admins, it becomes clear that, regardless of the complexity and peculiarities of the task, the process of building the admin includes the same steps that I described above. So, the code is the same everywhere, it remains only to change the input data. The following entities can be distinguished without being tied to the code:

  1. Interface configuration: a list of fields that will be used to form filters, columns of a list table or a set of inputs on the edit page.
  2. Class representation for the output interface. At the entrance, he should receive the config, “under the hood” he will have all the logic that we see in the “fish” from the bitrix, at the output he will display the rendered page.
  3. Widget. It contains the logic of the work of a separate admin field. In the list, it draws the table cells, and on the edit page the element fields.

To be fair, it’s necessary to say that the echoes of this concept are visible in the Bitrix source code: in particular, “user types”, which exist for both information blocks and “Highload” information blocks, are nothing but “widgets” in the above scheme.

By implementing the above classes, we could significantly reduce the "fish" from the bitrix to something like this:

$fields = include('fields.conf.php'); $adminListHelper = new MyHelper($fields); $adminListHelper->buildList(array($by => $order)); require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/prolog_admin_after.php"); $adminListHelper ->createFilterForm(); $adminListHelper ->show(); require($_SERVER["DOCUMENT_ROOT"] . "/bitrix/modules/main/include/epilog_admin.php"); 

In this seven-line piece of code, the main steps to create the admin panel, described at the beginning of the article, are displayed. But instead of copying this, albeit short, snippet every time, it is better to work a little more and do this:


As a result, the code needed to create the base pages of the list and edit is reduced by several times, and since we are no longer talking about hundreds of lines, I can bring it here:

List class
 class TableListHelper extends AdminListHelper { static protected $model = 'MyModelTable'; static public $module = 'my.module'; static protected $viewName = 'table_list'; static protected $editViewName = 'table_detail'; } 


Editing page class
 class TableEditHelper extends AdminEditHelper { static protected $model = 'MyModelTable'; static public $module = 'my.module'; static protected $listViewName = 'table_list'; static protected $viewName = 'table_detail'; } 


Interface settings
 AdminBaseHelper::setInterfaceSettings( array( 'FIELDS' => array( 'ID' => array( 'WIDGET' => new NumberWidget(), 'TITLE' => 'ID', 'TAB' => 'TAB_ONE' ), 'STRING' => array( 'WIDGET' => new StringWidget(), 'TITLE' => 'STRING', 'TAB' => 'TAB_ONE' ), 'NUMBER' => array( 'WIDGET' => new NumberWidget(), 'TITLE' => 'NUMBER', 'TAB' => 'TAB_ANOTHER' ), 'TEXT' => array( 'WIDGET' => new TextAreaWidget(), 'TITLE' => 'TEXT', 'TAB' => 'TAB_ANOTHER' ) ), 'TABS' => array( 'TAB_ONE' => Loc::getMessage('TAB_ONE'), 'TAB_ANOTHER' => Loc::getMessage('TAB_ANOTHER'), ) ), array( '\TableEditHelper', '\TableListHelper' ), 'my.module' ); 


File menu.php
 $menu = array( array( "parent_menu" => "global_menu_services", "section" => "table", "sort" => 140, "text" => Loc::getMessage('TABLE_MENU_TEXT'), "title" => Loc::getMessage('TABLE_MENU_TITLE'), "icon" => "table_menu_icon", "page_icon" => "table_page_icon", "items_id" => "menu_table", "url" => TableEditHelper::getListPageURL(), "more_url" => array( TableListHelper::getEditPageURL() ), ), ); return $menu; 


There are no hundreds of lines of copy-paste and copying files into / bitrix / admin - and as a result we get a completely working admin panel for a table with four columns: a list page, an edit page and links to them in the system menu. With support for CRUD operations out of the box. With normal routing (in this example, /bitrix/admin/route.php?module=my.module&view=tab_list will open the list page. You can modify this to “CNC” if you want or need). Then we only redefine the methods of the base classes in order to customize its behavior for its tasks. It looks tempting, isn't it?

The future is here!


And now about the pleasant: the above described is no longer just a concept, but a real, working, already been in the production of many projects, a module that I would like to share:

github.com/DigitalWand/digitalwand.admin_helper

The code becomes several orders more concise, the template copy-paste is minimized, giving way to arrays with a configuration, which was not in principle in the bitrix:

The amount of code using the module and without it
The comparison is based on:


The module can work both with fully custom tables, and with tables created through Bitrix functionality of “Highload” -blocks, while instead of “widgets” it is possible to use classes of “user properties”. Thus, all the functionality available in the admin of Highload infolok is available to us, only now we can easily customize it to fit our needs.

I should also warn readers that this article has intentionally used the “old style” of working with the module from its first version in order to more clearly demonstrate the internal mechanism of its work. In the latest versions in helper classes, it is enough to specify only the model - the module itself will determine the rest.

From useful materials are available:


I would like to complete the article with words of gratitude to the authors of Qt Framework, who inspired the desire for beauty and the web, wishing success to those who are now actively developing this module, as well as the hope that someday writing under Bitrix will be not only beneficial, but also pleasant.

Source: https://habr.com/ru/post/276481/


All Articles