Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/grid/ |
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/main/lib/grid/grid.php |
<?php namespace Bitrix\Main\Grid; use Bitrix\Main\Context; use Bitrix\Main\Filter\Filter; use Bitrix\Main\Grid\Action\Action; use Bitrix\Main\Grid\Action\PaginationAction; use Bitrix\Main\Grid\Column\Column; use Bitrix\Main\Grid\Column\Columns; use Bitrix\Main\Grid\Pagination\Storage\StorageSupporter; use Bitrix\Main\Grid\Panel\Panel; use Bitrix\Main\Grid\Row\Assembler\EmptyRowAssembler; use Bitrix\Main\Grid\Row\Rows; use Bitrix\Main\Grid\UI\GridResponse; use Bitrix\Main\Grid\UI\Request\GridRequestFactory; use Bitrix\Main\Grid\UI\Response\GridResponseFactory; use Bitrix\Main\HttpRequest; use Bitrix\Main\UI\PageNavigation; use Bitrix\Main\Web\PostDecodeFilter; /** * Grid object. * * Contains all the necessary information to work with the grid: columns, settings, actions. * There is no work with the filter here, there is a separate `Filter` class for this. * * @see \Bitrix\Main\Filter\Filter * * Usage example: * ```php // // create instances for grid and filter // $settings = new \Bitrix\Main\Grid\Settings([ 'ID' => 'test-grid', ]); $grid = new Grid($settings); // // init pagination (if using) // $totalCount = Entity::getCount( $grid->getOrmFilter() ?? [] ); $grid->initPagination($totalCount); // // processing grid actions from current request // $grid->processRequest(); // // fill grid rows with raw data // It is important to do this AFTER processing the request, because the handlers could change the data. // $grid->setRawRows( Entity::getList($grid->getOrmParams()) ); // // render component // $APPLICATION->IncludeComponent( 'bitrix:main.ui.grid', '', \Bitrix\Main\Grid\Component\ComponentParams::get($grid, [ // additional params ]) ); * ``` */ abstract class Grid { use StorageSupporter; private array $rawRows; private Options $options; private Settings $settings; private Columns $columns; private Rows $rows; // optional private ?Panel $panel = null; private ?Filter $filter = null; private ?PageNavigation $pagination = null; // internal private array $actionsMap; protected GridRequestFactory $gridRequestFactory; protected GridResponseFactory $gridResponseFactory; /** * @param Settings $settings required for all childs! */ public function __construct(Settings $settings) { $this->settings = $settings; $this->gridRequestFactory = new GridRequestFactory; $this->gridResponseFactory = new GridResponseFactory; } #region public api /** * Grid id. * * @return string */ final public function getId(): string { return $this->getSettings()->getId(); } /** * Configuration settings. * * @return Settings */ final public function getSettings(): Settings { return $this->settings; } /** * User options. * * @return Options */ final public function getOptions(): Options { $this->options ??= new Options($this->getId()); return $this->options; } /** * Grid columns. * * @return Columns */ final public function getColumns(): Columns { $this->columns ??= $this->createColumns(); return $this->columns; } /** * Grid rows. * * @return Rows */ final public function getRows(): Rows { $this->rows ??= $this->createRows(); return $this->rows; } /** * Grid footer actions panel. * * @return Panel|null */ final public function getPanel(): ?Panel { $this->panel ??= $this->createPanel(); return $this->panel; } /** * Grid filter. * * @return Filter|null */ final public function getFilter(): ?Filter { $this->filter ??= $this->createFilter(); return $this->filter; } /** * Grid pagination. * * @return PageNavigation|null */ final public function getPagination(): ?PageNavigation { return $this->pagination; } /** * Init pagination. * * If you use pagination, you need to call this method before processing the request (`processRequest` method) * and getting the ORM parameters (`getOrmParams` method). * * Ideally, call it immediately after creating the grid instance. * * @param int $totalRowsCount * @param string|null $navId * * @return void */ public function initPagination(int $totalRowsCount, ?string $navId = null): void { $navParams = $this->getOptions()->GetNavParams(); if (empty($navId)) { $navId = $this->getId() . '_nav'; } $this->pagination = new PageNavigation($navId); $this->pagination->allowAllRecords(false); $this->pagination->setPageSize($navParams['nPageSize']); $this->pagination->setPageSizes($this->getPageSizes()); $this->pagination->setRecordCount($totalRowsCount); $storage = $this->getPaginationStorage(); if (isset($storage)) { $storage->fill($this->pagination); } } /** * Set raw rows (only data after ORM calling). * * @param iterable $rawValue * * @return void */ public function setRawRows(iterable $rawValue): void { $this->rawRows = []; foreach ($rawValue as $item) { $this->rawRows[] = $item; } } /** * Get raw rows. * * @return array */ final protected function getRawRows(): array { return $this->rawRows; } /** * Gets rows prepared for output. * * @return array[] */ public function prepareRows(): array { return $this->getRows()->prepareRows($this->getRawRows()); } /** * Gets columns prepared for output. * * @return Column[] */ public function prepareColumns(): array { $result = []; foreach ($this->getColumns() as $column) { $result[] = $column; } return $result; } /** * Processing all actions of the grid. * * Handles actions of the grid, panel, and rows. * * @param HttpRequest|null $request * * @return void */ public function processRequest(?HttpRequest $request = null): void { $request ??= Context::getCurrent()->getRequest(); $request->addFilter(new PostDecodeFilter); $gridRequest = $this->gridRequestFactory->createFromRequest($request); $response = $this->processGridActionsRequest($gridRequest); if ($response instanceof GridResponse) { if ($response->isSendable()) { $response->send(); } return; } $panel = $this->getPanel(); if (isset($panel)) { $response = $panel->processRequest($gridRequest, $this->getFilter()); if ($response instanceof GridResponse) { if ($response->isSendable()) { $response->send(); } return; } } $response = $this->getRows()->processRequest($gridRequest); if ($response instanceof GridResponse) { if ($response->isSendable()) { $response->send(); } return; } } #region orm /** * Params for ORM and `getList` method. * * @see \Bitrix\Main\ORM\Data\DataManager method `getList` * * @return array */ public function getOrmParams(): array { $params = [ 'select' => $this->getOrmSelect(), 'order' => $this->getOrmOrder(), ]; $filter = $this->getOrmFilter(); if (isset($filter)) { $params['filter'] = $filter; } $pagination = $this->getPagination(); if (isset($pagination)) { $params['limit'] = $pagination->getLimit(); $params['offset'] = $pagination->getOffset(); } return $params; } /** * Select for ORM and `getList` method. * * @see \Bitrix\Main\ORM\Data\DataManager method `getList` * * @return array */ public function getOrmSelect(): array { return $this->getColumns()->getSelect( $this->getVisibleColumnsIds() ); } /** * Filter for ORM and `getList` method. * * @see \Bitrix\Main\ORM\Data\DataManager method `getList` * * @return array|null is filter not setted, returns `null` */ public function getOrmFilter(): ?array { $filter = $this->getFilter(); if (isset($filter)) { return $filter->getValue(); } return null; } /** * Order for ORM and `getList` method. * * @see \Bitrix\Main\ORM\Data\DataManager method `getList` * * @return array */ public function getOrmOrder(): array { $sorting = $this->getOptions()->getSorting( $this->getDefaultSorting() ); return $sorting['sort']; } #endregion orm #endregion public api /** * Grid actions. * * These are the actions of the grid itself, and not its component parts (rows, panel, ...). * * @return Action[] */ protected function getActions(): array { $result = []; $pagination = $this->getPagination(); if (isset($pagination)) { $result[] = new PaginationAction($pagination, $this->getPaginationStorage()); } return $result; } /** * Grid action. * * @param string $id * * @return Action|null */ final protected function getActionById(string $id): ?Action { if (empty($id)) { return null; } if (!isset($this->actionsMap)) { $this->actionsMap = []; foreach ($this->getActions() as $action) { $this->actionsMap[$action::getId()] = $action; } } return $this->actionsMap[$id] ?? null; } /** * Processing only grid actions. * * @see `::processRequest` for processing all actions (grid, rows and panel). * * @param GridRequest $request * * @return GridResponse|null */ protected function processGridActionsRequest(GridRequest $request): ?GridResponse { $result = null; if (!check_bitrix_sessid()) { return null; } $requestGridId = $request->getGridId(); if ($requestGridId !== $this->getId()) { return null; } $action = $this->getActionById( $request->getGridActionId() ?? '' ); if ($action) { $result = $action->processRequest($request->getHttpRequest()); } else { return null; } return isset($result) ? $this->gridResponseFactory->createFromResult($result) : null ; } /** * Ids of visible columns. * * If the user's display options are filled in, they are used. * Otherwise, used default columns. * * @return string[] columns ids */ public function getVisibleColumnsIds(): array { $visibleColumns = $this->getOptions()->GetVisibleColumns(); if (empty($visibleColumns)) { $visibleColumns = []; foreach ($this->getColumns() as $column) { if ($column->isDefault()) { $visibleColumns[] = $column->getId(); } } } return $visibleColumns; } /** * Available page sizes. * * @return int[] */ protected function getPageSizes(): array { return [ 5, 10, 20, 50, 100, ]; } /** * Default sorting. * * @return array */ protected function getDefaultSorting(): array { return [ 'ID' => 'ASC', ]; } /** * Create columns collection. * * @return Columns */ abstract protected function createColumns(): Columns; /** * Create rows collection. * * @return Rows */ protected function createRows(): Rows { $emptyRowAssembler = new EmptyRowAssembler( $this->getVisibleColumnsIds() ); return new Rows( $emptyRowAssembler ); } /** * Create panel. * * @return Panel|null */ protected function createPanel(): ?Panel { return null; } /** * Create filter. * * @return Filter|null */ protected function createFilter(): ?Filter { return null; } }