Column.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Backend\Block\Widget\Grid;
  7. use Magento\Backend\Block\Widget;
  8. use Magento\Backend\Block\Widget\Grid\Column\Filter\AbstractFilter;
  9. /**
  10. * Grid column block
  11. *
  12. * @api
  13. * @deprecated 100.2.0 in favour of UI component implementation
  14. * @since 100.0.2
  15. */
  16. class Column extends Widget
  17. {
  18. /**
  19. * Parent grid
  20. *
  21. * @var \Magento\Backend\Block\Widget\Grid
  22. */
  23. protected $_grid;
  24. /**
  25. * Column renderer
  26. *
  27. * @var \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
  28. */
  29. protected $_renderer;
  30. /**
  31. * Column filter
  32. *
  33. * @var AbstractFilter
  34. */
  35. protected $_filter;
  36. /**
  37. * Column css classes
  38. *
  39. * @var string|null
  40. */
  41. protected $_cssClass = null;
  42. /**
  43. * Renderer types
  44. *
  45. * @var array
  46. */
  47. protected $_rendererTypes = [
  48. 'action' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Action::class,
  49. 'button' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Button::class,
  50. 'checkbox' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Checkbox::class,
  51. 'concat' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Concat::class,
  52. 'country' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Country::class,
  53. 'currency' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Currency::class,
  54. 'date' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Date::class,
  55. 'datetime' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Datetime::class,
  56. 'default' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Text::class,
  57. 'draggable-handle' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\DraggableHandle::class,
  58. 'input' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Input::class,
  59. 'massaction' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Massaction::class,
  60. 'number' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Number::class,
  61. 'options' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Options::class,
  62. 'price' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Price::class,
  63. 'radio' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Radio::class,
  64. 'select' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Select::class,
  65. 'store' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Store::class,
  66. 'text' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Longtext::class,
  67. 'wrapline' => \Magento\Backend\Block\Widget\Grid\Column\Renderer\Wrapline::class,
  68. ];
  69. /**
  70. * Filter types
  71. *
  72. * @var array
  73. */
  74. protected $_filterTypes = [
  75. 'datetime' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Datetime::class,
  76. 'date' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Date::class,
  77. 'range' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Range::class,
  78. 'number' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Range::class,
  79. 'currency' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Range::class,
  80. 'price' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Price::class,
  81. 'country' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Country::class,
  82. 'options' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Select::class,
  83. 'massaction' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Massaction::class,
  84. 'checkbox' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Checkbox::class,
  85. 'radio' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Radio::class,
  86. 'skip-list' => \Magento\Backend\Block\Widget\Grid\Column\Filter\SkipList::class,
  87. 'store' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Store::class,
  88. 'theme' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Theme::class,
  89. 'default' => \Magento\Backend\Block\Widget\Grid\Column\Filter\Text::class,
  90. ];
  91. /**
  92. * Column is grouped
  93. * @var bool
  94. */
  95. protected $_isGrouped = false;
  96. /**
  97. * @return void
  98. */
  99. public function _construct()
  100. {
  101. if ($this->hasData('grouped')) {
  102. $this->_isGrouped = (bool)$this->getData('grouped');
  103. }
  104. parent::_construct();
  105. }
  106. /**
  107. * Should column be displayed in grid
  108. *
  109. * @return bool
  110. */
  111. public function isDisplayed()
  112. {
  113. return true;
  114. }
  115. /**
  116. * Set grid block to column
  117. *
  118. * @param \Magento\Backend\Block\Widget\Grid $grid
  119. * @return $this
  120. */
  121. public function setGrid($grid)
  122. {
  123. $this->_grid = $grid;
  124. // Init filter object
  125. $this->getFilter();
  126. return $this;
  127. }
  128. /**
  129. * Get grid block
  130. *
  131. * @return \Magento\Backend\Block\Widget\Grid
  132. */
  133. public function getGrid()
  134. {
  135. return $this->_grid;
  136. }
  137. /**
  138. * Retrieve html id of filter
  139. *
  140. * @return string
  141. */
  142. public function getHtmlId()
  143. {
  144. return $this->getGrid()->getId() . '_' . $this->getGrid()->getVarNameFilter() . '_' . $this->getId();
  145. }
  146. /**
  147. * Get html code for column properties
  148. *
  149. * @return string
  150. */
  151. public function getHtmlProperty()
  152. {
  153. return $this->getRenderer()->renderProperty();
  154. }
  155. /**
  156. * Get Header html
  157. * @return string
  158. */
  159. public function getHeaderHtml()
  160. {
  161. return $this->getRenderer()->renderHeader();
  162. }
  163. /**
  164. * Get column css classes
  165. *
  166. * @return string
  167. */
  168. public function getCssClass()
  169. {
  170. if ($this->_cssClass === null) {
  171. if ($this->getAlign()) {
  172. $this->_cssClass .= 'a-' . $this->getAlign();
  173. }
  174. // Add a custom css class for column
  175. if ($this->hasData('column_css_class')) {
  176. $this->_cssClass .= ' ' . $this->getData('column_css_class');
  177. }
  178. if ($this->getEditable()) {
  179. $this->_cssClass .= ' editable';
  180. }
  181. $this->_cssClass .= ' col-' . $this->getId();
  182. }
  183. return $this->_cssClass;
  184. }
  185. /**
  186. * Get column css property
  187. *
  188. * @return string
  189. */
  190. public function getCssProperty()
  191. {
  192. return $this->getRenderer()->renderCss();
  193. }
  194. /**
  195. * Set is column sortable
  196. *
  197. * @param bool $value
  198. * @return void
  199. */
  200. public function setSortable($value)
  201. {
  202. $this->setData('sortable', $value);
  203. }
  204. /**
  205. * Get header css class name
  206. * @return string
  207. */
  208. public function getHeaderCssClass()
  209. {
  210. $class = $this->getData('header_css_class');
  211. $class .= false === $this->getSortable() ? ' no-link' : '';
  212. $class .= ' col-' . $this->getId();
  213. return $class;
  214. }
  215. /**
  216. * @return bool
  217. * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  218. */
  219. public function getSortable()
  220. {
  221. return $this->hasData('sortable') ? (bool)$this->getData('sortable') : true;
  222. }
  223. /**
  224. * Add css class to column header
  225. *
  226. * @param string $className
  227. * @return void
  228. */
  229. public function addHeaderCssClass($className)
  230. {
  231. $classes = $this->getData('header_css_class') ? $this->getData('header_css_class') . ' ' : '';
  232. $this->setData('header_css_class', $classes . $className);
  233. }
  234. /**
  235. * Get header class names
  236. * @return string
  237. */
  238. public function getHeaderHtmlProperty()
  239. {
  240. $str = '';
  241. if ($class = $this->getHeaderCssClass()) {
  242. $str .= ' class="' . $class . '"';
  243. }
  244. return $str;
  245. }
  246. /**
  247. * Retrieve row column field value for display
  248. *
  249. * @param \Magento\Framework\DataObject $row
  250. * @return string
  251. */
  252. public function getRowField(\Magento\Framework\DataObject $row)
  253. {
  254. $renderedValue = $this->getRenderer()->render($row);
  255. if ($this->getHtmlDecorators()) {
  256. $renderedValue = $this->_applyDecorators($renderedValue, $this->getHtmlDecorators());
  257. }
  258. /*
  259. * if column has determined callback for framing call
  260. * it before give away rendered value
  261. *
  262. * callback_function($renderedValue, $row, $column, $isExport)
  263. * should return new version of rendered value
  264. */
  265. $frameCallback = $this->getFrameCallback();
  266. if (is_array($frameCallback)) {
  267. $this->validateFrameCallback($frameCallback);
  268. $renderedValue = call_user_func($frameCallback, $renderedValue, $row, $this, false);
  269. }
  270. return $renderedValue;
  271. }
  272. /**
  273. * Validate frame callback
  274. *
  275. * @throws \InvalidArgumentException
  276. *
  277. * @param array $callback
  278. * @return void
  279. */
  280. private function validateFrameCallback(array $callback)
  281. {
  282. if (!is_object($callback[0]) || !$callback[0] instanceof Widget) {
  283. throw new \InvalidArgumentException(
  284. "Frame callback host must be instance of Magento\\Backend\\Block\\Widget"
  285. );
  286. }
  287. }
  288. /**
  289. * Retrieve row column field value for export
  290. *
  291. * @param \Magento\Framework\DataObject $row
  292. * @return string
  293. */
  294. public function getRowFieldExport(\Magento\Framework\DataObject $row)
  295. {
  296. $renderedValue = $this->getRenderer()->renderExport($row);
  297. /*
  298. * if column has determined callback for framing call
  299. * it before give away rendered value
  300. *
  301. * callback_function($renderedValue, $row, $column, $isExport)
  302. * should return new version of rendered value
  303. */
  304. $frameCallback = $this->getFrameCallback();
  305. if (is_array($frameCallback)) {
  306. $this->validateFrameCallback($frameCallback);
  307. $renderedValue = call_user_func($frameCallback, $renderedValue, $row, $this, true);
  308. }
  309. return $renderedValue;
  310. }
  311. /**
  312. * Retrieve Header Name for Export
  313. *
  314. * @return string
  315. */
  316. public function getExportHeader()
  317. {
  318. if ($this->getHeaderExport()) {
  319. return $this->getHeaderExport();
  320. }
  321. return $this->getHeader();
  322. }
  323. /**
  324. * Decorate rendered cell value
  325. *
  326. * @param string $value
  327. * @param array|string $decorators
  328. * @return string
  329. */
  330. protected function &_applyDecorators($value, $decorators)
  331. {
  332. if (!is_array($decorators)) {
  333. if (is_string($decorators)) {
  334. $decorators = explode(' ', $decorators);
  335. }
  336. }
  337. if (!is_array($decorators) || empty($decorators)) {
  338. return $value;
  339. }
  340. switch (array_shift($decorators)) {
  341. case 'nobr':
  342. $value = '<span class="nobr">' . $value . '</span>';
  343. break;
  344. }
  345. if (!empty($decorators)) {
  346. return $this->_applyDecorators($value, $decorators);
  347. }
  348. return $value;
  349. }
  350. /**
  351. * Set column renderer
  352. *
  353. * @param \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer $renderer
  354. * @return $this
  355. */
  356. public function setRenderer($renderer)
  357. {
  358. $this->_renderer = $renderer;
  359. return $this;
  360. }
  361. /**
  362. * Set renderer type class name
  363. *
  364. * @param string $type type of renderer
  365. * @param string $className renderer class name
  366. * @return void
  367. */
  368. public function setRendererType($type, $className)
  369. {
  370. $this->_rendererTypes[$type] = $className;
  371. }
  372. /**
  373. * Get renderer class name by renderer type
  374. *
  375. * @return string
  376. */
  377. protected function _getRendererByType()
  378. {
  379. $type = strtolower($this->getType());
  380. $rendererClass = isset(
  381. $this->_rendererTypes[$type]
  382. ) ? $this->_rendererTypes[$type] : $this->_rendererTypes['default'];
  383. return $rendererClass;
  384. }
  385. /**
  386. * Retrieve column renderer
  387. *
  388. * @return \Magento\Backend\Block\Widget\Grid\Column\Renderer\AbstractRenderer
  389. */
  390. public function getRenderer()
  391. {
  392. if ($this->_renderer === null) {
  393. $rendererClass = $this->getData('renderer');
  394. if (empty($rendererClass)) {
  395. $rendererClass = $this->_getRendererByType();
  396. }
  397. $this->_renderer = $this->getLayout()->createBlock($rendererClass)->setColumn($this);
  398. }
  399. return $this->_renderer;
  400. }
  401. /**
  402. * Set column filter
  403. *
  404. * @param string $filterClass filter class name
  405. * @return void
  406. */
  407. public function setFilter($filterClass)
  408. {
  409. $filterBlock = $this->getLayout()->createBlock($filterClass);
  410. $filterBlock->setColumn($this);
  411. $this->_filter = $filterBlock;
  412. }
  413. /**
  414. * Set filter type class name
  415. *
  416. * @param string $type type of filter
  417. * @param string $className filter class name
  418. * @return void
  419. */
  420. public function setFilterType($type, $className)
  421. {
  422. $this->_filterTypes[$type] = $className;
  423. }
  424. /**
  425. * Get column filter class name by filter type
  426. *
  427. * @return string
  428. */
  429. protected function _getFilterByType()
  430. {
  431. $type = $this->getFilterType() ? strtolower($this->getFilterType()) : strtolower($this->getType());
  432. $filterClass = isset($this->_filterTypes[$type]) ? $this->_filterTypes[$type] : $this->_filterTypes['default'];
  433. return $filterClass;
  434. }
  435. /**
  436. * Get filter block
  437. *
  438. * @return AbstractFilter|false
  439. */
  440. public function getFilter()
  441. {
  442. if ($this->_filter === null) {
  443. $filterClass = $this->getData('filter');
  444. if (false === (bool)$filterClass && false === ($filterClass === null)) {
  445. return false;
  446. }
  447. if (!$filterClass) {
  448. $filterClass = $this->_getFilterByType();
  449. if ($filterClass === false) {
  450. return false;
  451. }
  452. }
  453. $this->_filter = $this->getLayout()->createBlock($filterClass)->setColumn($this);
  454. }
  455. return $this->_filter;
  456. }
  457. /**
  458. * Get filter html code
  459. *
  460. * @return null|string
  461. */
  462. public function getFilterHtml()
  463. {
  464. $filter = $this->getFilter();
  465. $output = $filter ? $filter->getHtml() : '&nbsp;';
  466. return $output;
  467. }
  468. /**
  469. * Check if column is grouped
  470. *
  471. * @return bool
  472. */
  473. public function isGrouped()
  474. {
  475. return $this->_isGrouped;
  476. }
  477. }