Grid.php 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Backend\Block\Widget;
  7. /**
  8. * Backend grid widget block
  9. *
  10. * @api
  11. * @deprecated 100.2.0 in favour of UI component implementation
  12. * @method string getRowClickCallback() getRowClickCallback()
  13. * @method \Magento\Backend\Block\Widget\Grid setRowClickCallback(string $value)
  14. * @SuppressWarnings(PHPMD.TooManyFields)
  15. * @since 100.0.2
  16. */
  17. class Grid extends \Magento\Backend\Block\Widget
  18. {
  19. /**
  20. * Page and sorting var names
  21. *
  22. * @var string
  23. */
  24. protected $_varNameLimit = 'limit';
  25. /**
  26. * @var string
  27. */
  28. protected $_varNamePage = 'page';
  29. /**
  30. * @var string
  31. */
  32. protected $_varNameSort = 'sort';
  33. /**
  34. * @var string
  35. */
  36. protected $_varNameDir = 'dir';
  37. /**
  38. * @var string
  39. */
  40. protected $_varNameFilter = 'filter';
  41. /**
  42. * @var int
  43. */
  44. protected $_defaultLimit = 20;
  45. /**
  46. * @var int
  47. */
  48. protected $_defaultPage = 1;
  49. /**
  50. * @var bool|string
  51. */
  52. protected $_defaultSort = false;
  53. /**
  54. * @var string
  55. */
  56. protected $_defaultDir = 'desc';
  57. /**
  58. * @var array
  59. */
  60. protected $_defaultFilter = [];
  61. /**
  62. * Empty grid text
  63. *
  64. * @var string|null
  65. */
  66. protected $_emptyText;
  67. /**
  68. * Empty grid text CSS class
  69. *
  70. * @var string|null
  71. */
  72. protected $_emptyTextCss = 'empty-text';
  73. /**
  74. * Pager visibility
  75. *
  76. * @var boolean
  77. */
  78. protected $_pagerVisibility = true;
  79. /**
  80. * Massage block visibility
  81. *
  82. * @var boolean
  83. */
  84. protected $_messageBlockVisibility = false;
  85. /**
  86. * Should parameters be saved in session
  87. *
  88. * @var bool
  89. */
  90. protected $_saveParametersInSession = false;
  91. /**
  92. * Count totals
  93. *
  94. * @var boolean
  95. */
  96. protected $_countTotals = false;
  97. /**
  98. * Totals
  99. *
  100. * @var \Magento\Framework\DataObject
  101. */
  102. protected $_varTotals;
  103. /**
  104. * @var string
  105. */
  106. protected $_template = 'Magento_Backend::widget/grid.phtml';
  107. /**
  108. * @var \Magento\Backend\Model\Session
  109. */
  110. protected $_backendSession;
  111. /**
  112. * @var \Magento\Backend\Helper\Data
  113. */
  114. protected $_backendHelper;
  115. /**
  116. * @param \Magento\Backend\Block\Template\Context $context
  117. * @param \Magento\Backend\Helper\Data $backendHelper
  118. * @param array $data
  119. */
  120. public function __construct(
  121. \Magento\Backend\Block\Template\Context $context,
  122. \Magento\Backend\Helper\Data $backendHelper,
  123. array $data = []
  124. ) {
  125. $this->_backendHelper = $backendHelper;
  126. $this->_backendSession = $context->getBackendSession();
  127. parent::__construct($context, $data);
  128. }
  129. /**
  130. * Internal constructor, that is called from real constructor
  131. *
  132. * @return void
  133. *
  134. * @SuppressWarnings(PHPMD.NPathComplexity)
  135. */
  136. protected function _construct()
  137. {
  138. parent::_construct();
  139. if (!$this->getRowClickCallback()) {
  140. $this->setRowClickCallback('openGridRow');
  141. }
  142. if ($this->hasData('id')) {
  143. $this->setId($this->getData('id'));
  144. }
  145. if ($this->hasData('default_sort')) {
  146. $this->setDefaultSort($this->getData('default_sort'));
  147. }
  148. if ($this->hasData('default_dir')) {
  149. $this->setDefaultDir($this->getData('default_dir'));
  150. }
  151. if ($this->hasData('save_parameters_in_session')) {
  152. $this->setSaveParametersInSession($this->getData('save_parameters_in_session'));
  153. }
  154. $this->setPagerVisibility(
  155. $this->hasData('pager_visibility') ? (bool)$this->getData('pager_visibility') : true
  156. );
  157. $this->setData('use_ajax', $this->hasData('use_ajax') ? (bool)$this->getData('use_ajax') : false);
  158. }
  159. /**
  160. * Set collection object
  161. *
  162. * @param \Magento\Framework\Data\Collection $collection
  163. * @return void
  164. */
  165. public function setCollection($collection)
  166. {
  167. $this->setData('dataSource', $collection);
  168. }
  169. /**
  170. * Get collection object
  171. *
  172. * @return \Magento\Framework\Data\Collection
  173. */
  174. public function getCollection()
  175. {
  176. return $this->getData('dataSource');
  177. }
  178. /**
  179. * Retrieve column set block
  180. *
  181. * @return \Magento\Backend\Block\Widget\Grid\ColumnSet
  182. */
  183. public function getColumnSet()
  184. {
  185. return $this->getChildBlock('grid.columnSet');
  186. }
  187. /**
  188. * Retrieve export block
  189. *
  190. * @throws \Magento\Framework\Exception\LocalizedException
  191. * @return \Magento\Framework\View\Element\AbstractBlock|bool
  192. */
  193. public function getExportBlock()
  194. {
  195. if (!$this->getChildBlock('grid.export')) {
  196. throw new \Magento\Framework\Exception\LocalizedException(
  197. __('Export block for grid %1 is not defined', $this->getNameInLayout())
  198. );
  199. }
  200. return $this->getChildBlock('grid.export');
  201. }
  202. /**
  203. * Retrieve list of grid columns
  204. *
  205. * @return array
  206. */
  207. public function getColumns()
  208. {
  209. return $this->getColumnSet()->getColumns();
  210. }
  211. /**
  212. * Count grid columns
  213. *
  214. * @return int
  215. */
  216. public function getColumnCount()
  217. {
  218. return count($this->getColumns());
  219. }
  220. /**
  221. * Retrieve column by id
  222. *
  223. * @param string $columnId
  224. * @return \Magento\Framework\View\Element\AbstractBlock|bool
  225. */
  226. public function getColumn($columnId)
  227. {
  228. return $this->getColumnSet()->getChildBlock($columnId);
  229. }
  230. /**
  231. * Process column filtration values
  232. *
  233. * @param mixed $data
  234. * @return $this
  235. */
  236. protected function _setFilterValues($data)
  237. {
  238. foreach ($this->getColumns() as $columnId => $column) {
  239. if (isset(
  240. $data[$columnId]
  241. ) && (is_array(
  242. $data[$columnId]
  243. ) && !empty($data[$columnId]) || strlen(
  244. $data[$columnId]
  245. ) > 0) && $column->getFilter()
  246. ) {
  247. $column->getFilter()->setValue($data[$columnId]);
  248. $this->_addColumnFilterToCollection($column);
  249. }
  250. }
  251. return $this;
  252. }
  253. /**
  254. * Add column filtering conditions to collection
  255. *
  256. * @param \Magento\Backend\Block\Widget\Grid\Column $column
  257. * @return $this
  258. */
  259. protected function _addColumnFilterToCollection($column)
  260. {
  261. if ($this->getCollection()) {
  262. $field = $column->getFilterIndex() ? $column->getFilterIndex() : $column->getIndex();
  263. if ($column->getFilterConditionCallback()) {
  264. call_user_func($column->getFilterConditionCallback(), $this->getCollection(), $column);
  265. } else {
  266. $condition = $column->getFilter()->getCondition();
  267. if ($field && isset($condition)) {
  268. $this->getCollection()->addFieldToFilter($field, $condition);
  269. }
  270. }
  271. }
  272. return $this;
  273. }
  274. /**
  275. * Sets sorting order by some column
  276. *
  277. * @param \Magento\Backend\Block\Widget\Grid\Column $column
  278. * @return $this
  279. */
  280. protected function _setCollectionOrder($column)
  281. {
  282. $collection = $this->getCollection();
  283. if ($collection) {
  284. $columnIndex = $column->getFilterIndex() ? $column->getFilterIndex() : $column->getIndex();
  285. $collection->setOrder($columnIndex, strtoupper($column->getDir()));
  286. }
  287. return $this;
  288. }
  289. /**
  290. * Get prepared collection
  291. *
  292. * @return \Magento\Framework\Data\Collection
  293. */
  294. public function getPreparedCollection()
  295. {
  296. $this->_prepareCollection();
  297. return $this->getCollection();
  298. }
  299. /**
  300. * Apply sorting and filtering to collection
  301. *
  302. * @return $this
  303. * @SuppressWarnings(PHPMD.CyclomaticComplexity)
  304. */
  305. protected function _prepareCollection()
  306. {
  307. if ($this->getCollection()) {
  308. $this->_preparePage();
  309. $columnId = $this->getParam($this->getVarNameSort(), $this->_defaultSort);
  310. $dir = $this->getParam($this->getVarNameDir(), $this->_defaultDir);
  311. $filter = $this->getParam($this->getVarNameFilter(), null);
  312. if ($filter === null) {
  313. $filter = $this->_defaultFilter;
  314. }
  315. if (is_string($filter)) {
  316. $data = $this->_backendHelper->prepareFilterString($filter);
  317. $data = array_merge($data, (array)$this->getRequest()->getPost($this->getVarNameFilter()));
  318. $this->_setFilterValues($data);
  319. } elseif ($filter && is_array($filter)) {
  320. $this->_setFilterValues($filter);
  321. } elseif (0 !== sizeof($this->_defaultFilter)) {
  322. $this->_setFilterValues($this->_defaultFilter);
  323. }
  324. if ($this->getColumn($columnId) && $this->getColumn($columnId)->getIndex()) {
  325. $dir = strtolower($dir) == 'desc' ? 'desc' : 'asc';
  326. $this->getColumn($columnId)->setDir($dir);
  327. $this->_setCollectionOrder($this->getColumn($columnId));
  328. }
  329. }
  330. return $this;
  331. }
  332. /**
  333. * Apply pagination to collection
  334. *
  335. * @return void
  336. */
  337. protected function _preparePage()
  338. {
  339. $this->getCollection()->setPageSize((int)$this->getParam($this->getVarNameLimit(), $this->_defaultLimit));
  340. $this->getCollection()->setCurPage((int)$this->getParam($this->getVarNamePage(), $this->_defaultPage));
  341. }
  342. /**
  343. * Initialize grid
  344. *
  345. * @return void
  346. */
  347. protected function _prepareGrid()
  348. {
  349. $this->_eventManager->dispatch(
  350. 'backend_block_widget_grid_prepare_grid_before',
  351. ['grid' => $this, 'collection' => $this->getCollection()]
  352. );
  353. if ($this->getChildBlock('grid.massaction') && $this->getChildBlock('grid.massaction')->isAvailable()) {
  354. $this->getChildBlock('grid.massaction')->prepareMassactionColumn();
  355. }
  356. $this->_prepareCollection();
  357. if ($this->hasColumnRenderers()) {
  358. foreach ($this->getColumnRenderers() as $renderer => $rendererClass) {
  359. $this->getColumnSet()->setRendererType($renderer, $rendererClass);
  360. }
  361. }
  362. if ($this->hasColumnFilters()) {
  363. foreach ($this->getColumnFilters() as $filter => $filterClass) {
  364. $this->getColumnSet()->setFilterType($filter, $filterClass);
  365. }
  366. }
  367. $this->getColumnSet()->setSortable($this->getSortable());
  368. $this->_prepareFilterButtons();
  369. }
  370. /**
  371. * Get massaction block
  372. *
  373. * @return bool|\Magento\Framework\View\Element\AbstractBlock
  374. */
  375. public function getMassactionBlock()
  376. {
  377. return $this->getChildBlock('grid.massaction');
  378. }
  379. /**
  380. * Prepare grid filter buttons
  381. *
  382. * @return void
  383. */
  384. protected function _prepareFilterButtons()
  385. {
  386. $this->setChild(
  387. 'reset_filter_button',
  388. $this->getLayout()->createBlock(
  389. \Magento\Backend\Block\Widget\Button::class
  390. )->setData(
  391. [
  392. 'label' => __('Reset Filter'),
  393. 'onclick' => $this->getJsObjectName() . '.resetFilter()',
  394. 'class' => 'action-reset action-tertiary'
  395. ]
  396. )->setDataAttribute(['action' => 'grid-filter-reset'])
  397. );
  398. $this->setChild(
  399. 'search_button',
  400. $this->getLayout()->createBlock(
  401. \Magento\Backend\Block\Widget\Button::class
  402. )->setData(
  403. [
  404. 'label' => __('Search'),
  405. 'onclick' => $this->getJsObjectName() . '.doFilter()',
  406. 'class' => 'action-secondary',
  407. ]
  408. )->setDataAttribute(['action' => 'grid-filter-apply'])
  409. );
  410. }
  411. /**
  412. * Initialize grid before rendering
  413. *
  414. * @return $this
  415. */
  416. protected function _beforeToHtml()
  417. {
  418. $this->_prepareGrid();
  419. return parent::_beforeToHtml();
  420. }
  421. /**
  422. * Retrieve limit request key
  423. *
  424. * @return string
  425. */
  426. public function getVarNameLimit()
  427. {
  428. return $this->_varNameLimit;
  429. }
  430. /**
  431. * Retrieve page request key
  432. *
  433. * @return string
  434. */
  435. public function getVarNamePage()
  436. {
  437. return $this->_varNamePage;
  438. }
  439. /**
  440. * Retrieve sort request key
  441. *
  442. * @return string
  443. */
  444. public function getVarNameSort()
  445. {
  446. return $this->_varNameSort;
  447. }
  448. /**
  449. * Retrieve sort direction request key
  450. *
  451. * @return string
  452. */
  453. public function getVarNameDir()
  454. {
  455. return $this->_varNameDir;
  456. }
  457. /**
  458. * Retrieve filter request key
  459. *
  460. * @return string
  461. */
  462. public function getVarNameFilter()
  463. {
  464. return $this->_varNameFilter;
  465. }
  466. /**
  467. * Set Limit request key
  468. *
  469. * @param string $name
  470. * @return $this
  471. */
  472. public function setVarNameLimit($name)
  473. {
  474. $this->_varNameLimit = $name;
  475. return $this;
  476. }
  477. /**
  478. * Set Page request key
  479. *
  480. * @param string $name
  481. * @return $this
  482. */
  483. public function setVarNamePage($name)
  484. {
  485. $this->_varNamePage = $name;
  486. return $this;
  487. }
  488. /**
  489. * Set Sort request key
  490. *
  491. * @param string $name
  492. * @return $this
  493. */
  494. public function setVarNameSort($name)
  495. {
  496. $this->_varNameSort = $name;
  497. return $this;
  498. }
  499. /**
  500. * Set Sort Direction request key
  501. *
  502. * @param string $name
  503. * @return $this
  504. */
  505. public function setVarNameDir($name)
  506. {
  507. $this->_varNameDir = $name;
  508. return $this;
  509. }
  510. /**
  511. * Set Filter request key
  512. *
  513. * @param string $name
  514. * @return $this
  515. */
  516. public function setVarNameFilter($name)
  517. {
  518. $this->_varNameFilter = $name;
  519. return $this;
  520. }
  521. /**
  522. * Set visibility of pager
  523. *
  524. * @param bool $visible
  525. * @return $this
  526. */
  527. public function setPagerVisibility($visible = true)
  528. {
  529. $this->_pagerVisibility = $visible;
  530. return $this;
  531. }
  532. /**
  533. * Return visibility of pager
  534. *
  535. * @return bool
  536. * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  537. */
  538. public function getPagerVisibility()
  539. {
  540. return $this->_pagerVisibility;
  541. }
  542. /**
  543. * Set visibility of message blocks
  544. *
  545. * @param bool $visible
  546. * @return void
  547. */
  548. public function setMessageBlockVisibility($visible = true)
  549. {
  550. $this->_messageBlockVisibility = $visible;
  551. }
  552. /**
  553. * Return visibility of message blocks
  554. *
  555. * @return bool
  556. * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  557. */
  558. public function getMessageBlockVisibility()
  559. {
  560. return $this->_messageBlockVisibility;
  561. }
  562. /**
  563. * Set default limit
  564. *
  565. * @param int $limit
  566. * @return $this
  567. */
  568. public function setDefaultLimit($limit)
  569. {
  570. $this->_defaultLimit = $limit;
  571. return $this;
  572. }
  573. /**
  574. * Set default page
  575. *
  576. * @param int $page
  577. * @return $this
  578. */
  579. public function setDefaultPage($page)
  580. {
  581. $this->_defaultPage = $page;
  582. return $this;
  583. }
  584. /**
  585. * Set default sort
  586. *
  587. * @param string $sort
  588. * @return $this
  589. */
  590. public function setDefaultSort($sort)
  591. {
  592. $this->_defaultSort = $sort;
  593. return $this;
  594. }
  595. /**
  596. * Set default direction
  597. *
  598. * @param string $dir
  599. * @return $this
  600. */
  601. public function setDefaultDir($dir)
  602. {
  603. $this->_defaultDir = $dir;
  604. return $this;
  605. }
  606. /**
  607. * Set default filter
  608. *
  609. * @param string $filter
  610. * @return $this
  611. */
  612. public function setDefaultFilter($filter)
  613. {
  614. $this->_defaultFilter = $filter;
  615. return $this;
  616. }
  617. /**
  618. * Check whether grid container should be displayed
  619. *
  620. * @return bool
  621. */
  622. public function canDisplayContainer()
  623. {
  624. if ($this->getRequest()->getQuery('ajax')) {
  625. return false;
  626. }
  627. return true;
  628. }
  629. /**
  630. * Retrieve grid reload url
  631. *
  632. * @return string;
  633. */
  634. public function getGridUrl()
  635. {
  636. return $this->hasData('grid_url') ? $this->getData('grid_url') : $this->getAbsoluteGridUrl();
  637. }
  638. /**
  639. * Grid url getter
  640. *
  641. * Version of getGridUrl() but with parameters
  642. *
  643. * @param array $params url parameters
  644. * @return string current grid url
  645. */
  646. public function getAbsoluteGridUrl($params = [])
  647. {
  648. return $this->getCurrentUrl($params);
  649. }
  650. /**
  651. * Retrieve grid
  652. *
  653. * @param string $paramName
  654. * @param mixed $default
  655. * @return mixed
  656. */
  657. public function getParam($paramName, $default = null)
  658. {
  659. $sessionParamName = $this->getId() . $paramName;
  660. if ($this->getRequest()->has($paramName)) {
  661. $param = $this->getRequest()->getParam($paramName);
  662. if ($this->_saveParametersInSession) {
  663. $this->_backendSession->setData($sessionParamName, $param);
  664. }
  665. return $param;
  666. } elseif ($this->_saveParametersInSession && ($param = $this->_backendSession->getData($sessionParamName))) {
  667. return $param;
  668. }
  669. return $default;
  670. }
  671. /**
  672. * Set whether grid parameters should be saved in session
  673. *
  674. * @param bool $flag
  675. * @return $this
  676. */
  677. public function setSaveParametersInSession($flag)
  678. {
  679. $this->_saveParametersInSession = $flag;
  680. return $this;
  681. }
  682. /**
  683. * Retrieve grid javascript object name
  684. *
  685. * @return string
  686. */
  687. public function getJsObjectName()
  688. {
  689. return preg_replace("~[^a-z0-9_]*~i", '', $this->getId()) . 'JsObject';
  690. }
  691. /**
  692. * Set count totals
  693. *
  694. * @param bool $count
  695. * @return $this
  696. */
  697. public function setCountTotals($count = true)
  698. {
  699. $this->_countTotals = $count;
  700. return $this;
  701. }
  702. /**
  703. * Return count totals
  704. *
  705. * @return bool
  706. * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  707. */
  708. public function getCountTotals()
  709. {
  710. return $this->_countTotals;
  711. }
  712. /**
  713. * Set totals
  714. *
  715. * @param \Magento\Framework\DataObject $totals
  716. * @return void
  717. */
  718. public function setTotals(\Magento\Framework\DataObject $totals)
  719. {
  720. $this->_varTotals = $totals;
  721. }
  722. /**
  723. * Retrieve totals
  724. *
  725. * @return \Magento\Framework\DataObject
  726. */
  727. public function getTotals()
  728. {
  729. return $this->_varTotals;
  730. }
  731. /**
  732. * Generate list of grid buttons
  733. *
  734. * @return string
  735. */
  736. public function getMainButtonsHtml()
  737. {
  738. $html = '';
  739. if ($this->getColumnSet()->isFilterVisible()) {
  740. $html .= $this->getSearchButtonHtml();
  741. $html .= $this->getResetFilterButtonHtml();
  742. }
  743. return $html;
  744. }
  745. /**
  746. * Generate reset button
  747. *
  748. * @return string
  749. */
  750. public function getResetFilterButtonHtml()
  751. {
  752. return $this->getChildHtml('reset_filter_button');
  753. }
  754. /**
  755. * Generate search button
  756. *
  757. * @return string
  758. */
  759. public function getSearchButtonHtml()
  760. {
  761. return $this->getChildHtml('search_button');
  762. }
  763. }