Magento 2 Documentation  2.3
Documentation for Magento 2 CMS v2.3 (December 2018)
Extended.php
Go to the documentation of this file.
1 <?php
7 
9 
20 class Extended extends \Magento\Backend\Block\Widget\Grid implements \Magento\Backend\Block\Widget\Grid\ExportInterface
21 {
36  protected $_columns = [];
37 
43  protected $_collection;
44 
50  protected $_isExport = false;
51 
57  protected $_exportTypes = [];
58 
64  protected $_exportPageSize = 1000;
65 
71  protected $_lastColumnId;
72 
79 
86 
92  protected $_massactionBlockName = \Magento\Backend\Block\Widget\Grid\Massaction\Extended::class;
93 
99  protected $_columnsOrder = [];
100 
106  protected $_emptyCellLabel = '';
107 
113  protected $_groupedColumn = [];
114 
120  protected $_headersVisibility = true;
121 
127  protected $_filterVisibility = true;
128 
134  protected $_emptyText;
135 
141  protected $_emptyTextCss = 'empty-text';
142 
146  protected $_isCollapsed;
147 
153  protected $_countSubTotals = false;
154 
160  protected $_subtotals = [];
161 
165  protected $_template = 'Magento_Backend::widget/grid/extended.phtml';
166 
170  protected $_directory;
171 
177  protected $_path = 'export';
178 
182  protected function _construct()
183  {
184  parent::_construct();
185  $this->_emptyText = __('We couldn\'t find any records.');
186 
187  $this->_directory = $this->_filesystem->getDirectoryWrite(DirectoryList::VAR_DIR);
188  }
189 
195  protected function _prepareLayout()
196  {
197  $this->setChild(
198  'export_button',
199  $this->getLayout()->createBlock(\Magento\Backend\Block\Widget\Button::class)->setData(
200  [
201  'label' => __('Export'),
202  'onclick' => $this->getJsObjectName() . '.doExport()',
203  'class' => 'task',
204  ]
205  )
206  );
207  $this->setChild(
208  'reset_filter_button',
209  $this->getLayout()->createBlock(\Magento\Backend\Block\Widget\Button::class)->setData(
210  [
211  'label' => __('Reset Filter'),
212  'onclick' => $this->getJsObjectName() . '.resetFilter()',
213  'class' => 'action-reset action-tertiary'
214  ]
215  )->setDataAttribute(
216  [
217  'action' => 'grid-filter-reset'
218  ]
219  )
220  );
221  $this->setChild(
222  'search_button',
223  $this->getLayout()->createBlock(\Magento\Backend\Block\Widget\Button::class)->setData(
224  [
225  'label' => __('Search'),
226  'onclick' => $this->getJsObjectName() . '.doFilter()',
227  'class' => 'task action-secondary',
228  ]
229  )->setDataAttribute(
230  [
231  'action' => 'grid-filter-apply'
232  ]
233  )
234  );
235  return parent::_prepareLayout();
236  }
237 
243  public function getColumnSet()
244  {
245  if (!$this->getChildBlock('grid.columnSet')) {
246  $this->setChild(
247  'grid.columnSet',
248  $this->getLayout()->createBlock(\Magento\Backend\Block\Widget\Grid\ColumnSet::class)
249  );
250  }
251  return parent::getColumnSet();
252  }
253 
259  public function getExportButtonHtml()
260  {
261  return $this->getChildHtml('export_button');
262  }
263 
271  public function addExportType($url, $label)
272  {
273  $this->_exportTypes[] = new \Magento\Framework\DataObject(
274  ['url' => $this->getUrl($url, ['_current' => true]), 'label' => $label]
275  );
276  return $this;
277  }
278 
287  public function addColumn($columnId, $column)
288  {
289  if (is_array($column)) {
290  $this->getColumnSet()->setChild(
291  $columnId,
292  $this->getLayout()
293  ->createBlock(\Magento\Backend\Block\Widget\Grid\Column\Extended::class)
294  ->setData($column)
295  ->setId($columnId)
296  ->setGrid($this)
297  );
298  $this->getColumnSet()->getChildBlock($columnId)->setGrid($this);
299  } else {
300  throw new \Exception(__('Please correct the column format and try again.'));
301  }
302 
303  $this->_lastColumnId = $columnId;
304  return $this;
305  }
306 
313  public function removeColumn($columnId)
314  {
315  if ($this->getColumnSet()->getChildBlock($columnId)) {
316  $this->getColumnSet()->unsetChild($columnId);
317  if ($this->_lastColumnId == $columnId) {
318  $names = $this->getColumnSet()->getChildNames();
319  $this->_lastColumnId = array_pop($names);
320  }
321  }
322  return $this;
323  }
324 
333  public function addColumnAfter($columnId, $column, $after)
334  {
335  $this->addColumn($columnId, $column);
336  $this->addColumnsOrder($columnId, $after);
337  return $this;
338  }
339 
347  public function addColumnsOrder($columnId, $after)
348  {
349  $this->_columnsOrder[$columnId] = $after;
350  return $this;
351  }
352 
358  public function getColumnsOrder()
359  {
360  return $this->_columnsOrder;
361  }
362 
368  public function sortColumnsByOrder()
369  {
370  foreach ($this->getColumnsOrder() as $columnId => $after) {
371  $this->getLayout()->reorderChild(
372  $this->getColumnSet()->getNameInLayout(),
373  $this->getColumn($columnId)->getNameInLayout(),
374  $this->getColumn($after)->getNameInLayout()
375  );
376  }
377 
378  $columns = $this->getColumnSet()->getChildNames();
379  $this->_lastColumnId = array_pop($columns);
380  return $this;
381  }
382 
388  public function getLastColumnId()
389  {
390  return $this->_lastColumnId;
391  }
392 
398  protected function _prepareColumns()
399  {
400  $this->sortColumnsByOrder();
401  return $this;
402  }
403 
409  protected function _prepareMassactionBlock()
410  {
411  $this->setChild('massaction', $this->getLayout()->createBlock($this->getMassactionBlockName()));
412  $this->_prepareMassaction();
413  if ($this->getMassactionBlock()->isAvailable()) {
414  $this->_prepareMassactionColumn();
415  }
416  return $this;
417  }
418 
424  protected function _prepareMassaction()
425  {
426  return $this;
427  }
428 
434  protected function _prepareMassactionColumn()
435  {
436  $columnId = 'massaction';
437  $massactionColumn = $this->getLayout()
438  ->createBlock(\Magento\Backend\Block\Widget\Grid\Column::class)
439  ->setData(
440  [
441  'index' => $this->getMassactionIdField(),
442  'filter_index' => $this->getMassactionIdFilter(),
443  'type' => 'massaction',
444  'name' => $this->getMassactionBlock()->getFormFieldName(),
445  'is_system' => true,
446  'header_css_class' => 'col-select',
447  'column_css_class' => 'col-select',
448  ]
449  );
450 
451  if ($this->getNoFilterMassactionColumn()) {
452  $massactionColumn->setData('filter', false);
453  }
454 
455  $massactionColumn->setSelected($this->getMassactionBlock()->getSelected())->setGrid($this)->setId($columnId);
456 
457  $this->getColumnSet()->insert(
458  $massactionColumn,
459  count($this->getColumnSet()->getColumns()) + 1,
460  false,
461  $columnId
462  );
463  return $this;
464  }
465 
471  protected function _prepareCollection()
472  {
473  if ($this->getCollection()) {
474  if ($this->getCollection()->isLoaded()) {
475  $this->getCollection()->clear();
476  }
477 
478  parent::_prepareCollection();
479 
480  if (!$this->_isExport) {
481  $this->getCollection()->load();
482  $this->_afterLoadCollection();
483  }
484  }
485 
486  return $this;
487  }
488 
494  protected function _afterLoadCollection()
495  {
496  return $this;
497  }
498 
504  protected function _prepareGrid()
505  {
506  $this->_prepareColumns();
507  $this->_prepareMassactionBlock();
508  parent::_prepareGrid();
509  return $this;
510  }
511 
517  public function getHtml()
518  {
519  return $this->toHtml();
520  }
521 
527  public function getMassactionIdField()
528  {
530  }
531 
538  public function setMassactionIdField($idField)
539  {
540  $this->_massactionIdField = $idField;
541  return $this;
542  }
543 
549  public function getMassactionIdFilter()
550  {
552  }
553 
560  public function setMassactionIdFilter($idFilter)
561  {
562  $this->_massactionIdFilter = $idFilter;
563  return $this;
564  }
565 
571  public function getMassactionBlockName()
572  {
574  }
575 
582  public function setMassactionBlockName($blockName)
583  {
584  $this->_massactionBlockName = $blockName;
585  return $this;
586  }
587 
593  public function getMassactionBlock()
594  {
595  return $this->getChildBlock('massaction');
596  }
597 
603  public function getMassactionBlockHtml()
604  {
605  return $this->getChildHtml('massaction');
606  }
607 
613  public function getSubTotalColumns()
614  {
615  return $this->getColumns();
616  }
617 
625  public function shouldRenderCell($item, $column)
626  {
627  if ($this->isColumnGrouped($column) && $item->getIsEmpty()) {
628  return true;
629  }
630  if (!$item->getIsEmpty()) {
631  return true;
632  }
633  return false;
634  }
635 
641  public function getEmptyCellLabel()
642  {
643  return $this->_emptyCellLabel;
644  }
645 
652  public function setEmptyCellLabel($label)
653  {
654  $this->_emptyCellLabel = $label;
655  return $this;
656  }
657 
664  public function getRowUrl($item)
665  {
666  $res = parent::getRowUrl($item);
667  return $res ? $res : '#';
668  }
669 
676  public function getMultipleRows($item)
677  {
678  return $item->getChildren();
679  }
680 
685  public function getMultipleRowColumns()
686  {
687  $columns = $this->getColumns();
688  foreach ($this->_groupedColumn as $column) {
689  unset($columns[$column]);
690  }
691  return $columns;
692  }
693 
700  public function shouldRenderSubTotal($item)
701  {
702  return $this->_countSubTotals && count($this->_subtotals) > 0 && count($this->getMultipleRows($item)) > 0;
703  }
704 
712  public function getRowspan($item, $column)
713  {
714  if ($this->isColumnGrouped($column)) {
715  return count($this->getMultipleRows($item)) + count($this->_groupedColumn);
716  }
717  return false;
718  }
719 
727  public function isColumnGrouped($column, $value = null)
728  {
729  if (null === $value) {
730  if (is_object($column)) {
731  return in_array($column->getIndex(), $this->_groupedColumn);
732  }
733  return in_array($column, $this->_groupedColumn);
734  }
735  $this->_groupedColumn[] = $column;
736  return $this;
737  }
738 
746  public function shouldRenderEmptyCell($item, $column)
747  {
748  return $item->getIsEmpty() && in_array($column['index'], $this->_groupedColumn);
749  }
750 
756  public function getEmptyCellColspan()
757  {
758  return $this->getColumnCount() - count($this->_groupedColumn);
759  }
760 
767  public function getSubTotalItem($item)
768  {
769  foreach ($this->_subtotals as $subtotalItem) {
770  foreach ($this->_groupedColumn as $groupedColumn) {
771  if ($subtotalItem->getData($groupedColumn) == $item->getData($groupedColumn)) {
772  return $subtotalItem;
773  }
774  }
775  }
776  return '';
777  }
778 
784  public function getColumnCount()
785  {
786  return count($this->getColumns());
787  }
788 
795  public function setHeadersVisibility($visible = true)
796  {
797  $this->_headersVisibility = $visible;
798  }
799 
806  public function getHeadersVisibility()
807  {
809  }
810 
817  public function setFilterVisibility($visible = true)
818  {
819  $this->_filterVisibility = $visible;
820  }
821 
828  public function getFilterVisibility()
829  {
831  }
832 
839  public function setEmptyText($text)
840  {
841  $this->_emptyText = $text;
842  return $this;
843  }
844 
850  public function getEmptyText()
851  {
852  return $this->_emptyText;
853  }
854 
861  public function setEmptyTextClass($cssClass)
862  {
863  $this->_emptyTextCss = $cssClass;
864  return $this;
865  }
866 
872  public function getEmptyTextClass()
873  {
874  return $this->_emptyTextCss;
875  }
876 
883  public function setIsCollapsed($isCollapsed)
884  {
885  $this->_isCollapsed = $isCollapsed;
886  return $this;
887  }
888 
895  public function getIsCollapsed()
896  {
897  return $this->_isCollapsed;
898  }
899 
906  protected function _getFileContainerContent(array $fileData)
907  {
908  return $this->_directory->readFile('export/' . $fileData['value']);
909  }
910 
916  protected function _getExportHeaders()
917  {
918  $row = [];
919  foreach ($this->getColumns() as $column) {
920  if (!$column->getIsSystem()) {
921  $row[] = $column->getExportHeader();
922  }
923  }
924  return $row;
925  }
926 
932  protected function _getExportTotals()
933  {
934  $totals = $this->getTotals();
935  $row = [];
936  foreach ($this->getColumns() as $column) {
937  if (!$column->getIsSystem()) {
938  $row[] = $column->hasTotalsLabel() ? $column->getTotalsLabel() : $column->getRowFieldExport($totals);
939  }
940  }
941  return $row;
942  }
943 
952  public function _exportIterateCollection($callback, array $args)
953  {
954  $originalCollection = $this->getCollection();
955  $count = null;
956  $page = 1;
957  $lPage = null;
958  $break = false;
959 
960  while ($break !== true) {
961  $collection = clone $originalCollection;
962  $collection->setPageSize($this->_exportPageSize);
963  $collection->setCurPage($page);
964  $collection->load();
965  if ($count === null) {
966  $count = $collection->getSize();
967  $lPage = $collection->getLastPageNumber();
968  }
969  if ($lPage == $page) {
970  $break = true;
971  }
972  $page++;
973 
974  foreach ($collection as $item) {
975  call_user_func_array([$this, $callback], array_merge([$item], $args));
976  }
977  }
978  }
979 
987  protected function _exportCsvItem(
988  \Magento\Framework\DataObject $item,
989  \Magento\Framework\Filesystem\File\WriteInterface $stream
990  ) {
991  $row = [];
992  foreach ($this->getColumns() as $column) {
993  if (!$column->getIsSystem()) {
994  $row[] = $column->getRowFieldExport($item);
995  }
996  }
997  $stream->writeCsv($row);
998  }
999 
1007  public function getCsvFile()
1008  {
1009  $this->_isExport = true;
1010  $this->_prepareGrid();
1011 
1012  $name = md5(microtime());
1013  $file = $this->_path . '/' . $name . '.csv';
1014 
1015  $this->_directory->create($this->_path);
1016  $stream = $this->_directory->openFile($file, 'w+');
1017 
1018  $stream->lock();
1019  $stream->writeCsv($this->_getExportHeaders());
1020  $this->_exportIterateCollection('_exportCsvItem', [$stream]);
1021 
1022  if ($this->getCountTotals()) {
1023  $stream->writeCsv($this->_getExportTotals());
1024  }
1025 
1026  $stream->unlock();
1027  $stream->close();
1028 
1029  return [
1030  'type' => 'filename',
1031  'value' => $file,
1032  'rm' => true // can delete file after use
1033  ];
1034  }
1035 
1041  public function getCsv()
1042  {
1043  $csv = '';
1044  $this->_isExport = true;
1045  $this->_prepareGrid();
1046  $this->getCollection()->getSelect()->limit();
1047  $this->getCollection()->setPageSize(0);
1048  $this->getCollection()->load();
1049  $this->_afterLoadCollection();
1050 
1051  $data = [];
1052  foreach ($this->getColumns() as $column) {
1053  if (!$column->getIsSystem()) {
1054  $data[] = '"' . $column->getExportHeader() . '"';
1055  }
1056  }
1057  $csv .= implode(',', $data) . "\n";
1058 
1059  foreach ($this->getCollection() as $item) {
1060  $data = [];
1061  foreach ($this->getColumns() as $column) {
1062  if (!$column->getIsSystem()) {
1063  $data[] = '"' . str_replace(
1064  ['"', '\\'],
1065  ['""', '\\\\'],
1066  $column->getRowFieldExport($item)
1067  ) . '"';
1068  }
1069  }
1070  $csv .= implode(',', $data) . "\n";
1071  }
1072 
1073  if ($this->getCountTotals()) {
1074  $data = [];
1075  foreach ($this->getColumns() as $column) {
1076  if (!$column->getIsSystem()) {
1077  $data[] = '"' . str_replace(
1078  ['"', '\\'],
1079  ['""', '\\\\'],
1080  $column->getRowFieldExport($this->getTotals())
1081  ) . '"';
1082  }
1083  }
1084  $csv .= implode(',', $data) . "\n";
1085  }
1086 
1087  return $csv;
1088  }
1089 
1095  public function getXml()
1096  {
1097  $this->_isExport = true;
1098  $this->_prepareGrid();
1099  $this->getCollection()->getSelect()->limit();
1100  $this->getCollection()->setPageSize(0);
1101  $this->getCollection()->load();
1102  $this->_afterLoadCollection();
1103  $indexes = [];
1104  foreach ($this->getColumns() as $column) {
1105  if (!$column->getIsSystem()) {
1106  $indexes[] = $column->getIndex();
1107  }
1108  }
1109  $xml = '<?xml version="1.0" encoding="UTF-8"?>';
1110  $xml .= '<items>';
1111  foreach ($this->getCollection() as $item) {
1112  $xml .= $item->toXml($indexes);
1113  }
1114  if ($this->getCountTotals()) {
1115  $xml .= $this->getTotals()->toXml($indexes);
1116  }
1117  $xml .= '</items>';
1118  return $xml;
1119  }
1120 
1127  public function getRowRecord(\Magento\Framework\DataObject $data)
1128  {
1129  $row = [];
1130  foreach ($this->getColumns() as $column) {
1131  if (!$column->getIsSystem()) {
1132  $row[] = $column->getRowFieldExport($data);
1133  }
1134  }
1135  return $row;
1136  }
1137 
1146  public function getExcelFile($sheetName = '')
1147  {
1148  $this->_isExport = true;
1149  $this->_prepareGrid();
1150 
1151  $convert = new \Magento\Framework\Convert\Excel(
1152  $this->getCollection()->getIterator(),
1153  [$this, 'getRowRecord']
1154  );
1155 
1156  $name = md5(microtime());
1157  $file = $this->_path . '/' . $name . '.xml';
1158 
1159  $this->_directory->create($this->_path);
1160  $stream = $this->_directory->openFile($file, 'w+');
1161  $stream->lock();
1162 
1163  $convert->setDataHeader($this->_getExportHeaders());
1164  if ($this->getCountTotals()) {
1165  $convert->setDataFooter($this->_getExportTotals());
1166  }
1167 
1168  $convert->write($stream, $sheetName);
1169  $stream->unlock();
1170  $stream->close();
1171 
1172  return [
1173  'type' => 'filename',
1174  'value' => $file,
1175  'rm' => true // can delete file after use
1176  ];
1177  }
1178 
1184  public function getExcel()
1185  {
1186  $this->_isExport = true;
1187  $this->_prepareGrid();
1188  $this->getCollection()->getSelect()->limit();
1189  $this->getCollection()->setPageSize(0);
1190  $this->getCollection()->load();
1191  $this->_afterLoadCollection();
1192  $headers = [];
1193  $data = [];
1194  foreach ($this->getColumns() as $column) {
1195  if (!$column->getIsSystem()) {
1196  $headers[] = $column->getHeader();
1197  }
1198  }
1199  $data[] = $headers;
1200 
1201  foreach ($this->getCollection() as $item) {
1202  $row = [];
1203  foreach ($this->getColumns() as $column) {
1204  if (!$column->getIsSystem()) {
1205  $row[] = $column->getRowField($item);
1206  }
1207  }
1208  $data[] = $row;
1209  }
1210 
1211  if ($this->getCountTotals()) {
1212  $row = [];
1213  foreach ($this->getColumns() as $column) {
1214  if (!$column->getIsSystem()) {
1215  $row[] = $column->getRowField($this->getTotals());
1216  }
1217  }
1218  $data[] = $row;
1219  }
1220 
1221  $convert = new \Magento\Framework\Convert\Excel(new \ArrayIterator($data));
1222  return $convert->convert('single_sheet');
1223  }
1224 
1230  public function getExportTypes()
1231  {
1232  return empty($this->_exportTypes) ? false : $this->_exportTypes;
1233  }
1234 
1241  public function setCollection($collection)
1242  {
1243  $this->_collection = $collection;
1244  }
1245 
1251  public function getCollection()
1252  {
1253  return $this->_collection;
1254  }
1255 
1262  public function setCountSubTotals($flag = true)
1263  {
1264  $this->_countSubTotals = $flag;
1265  return $this;
1266  }
1267 
1274  public function getCountSubTotals()
1275  {
1276  return $this->_countSubTotals;
1277  }
1278 
1285  public function setSubTotals(array $items)
1286  {
1287  $this->_subtotals = $items;
1288  return $this;
1289  }
1290 
1296  public function getSubTotals()
1297  {
1298  return $this->_subtotals;
1299  }
1300 
1306  public function getMainButtonsHtml()
1307  {
1308  $html = '';
1309  if ($this->getFilterVisibility()) {
1310  $html .= $this->getSearchButtonHtml();
1311  $html .= $this->getResetFilterButtonHtml();
1312  }
1313  return $html;
1314  }
1315 }
_exportIterateCollection($callback, array $args)
Definition: Extended.php:952
return false
Definition: gallery.phtml:36
$count
Definition: recent.phtml:13
__()
Definition: __.php:13
endifif( $block->getLastPageNum()>1)( 'Page') ?></strong >< ul class $text
Definition: pager.phtml:43
getRowRecord(\Magento\Framework\DataObject $data)
Definition: Extended.php:1127
$columns
Definition: default.phtml:15
$label
Definition: details.phtml:21
$value
Definition: gender.phtml:16
$totals
Definition: totalbar.phtml:10
$this _collection
Definition: coupons.php:7
$page
Definition: pages.php:8
if(!isset($advancedLabel)) $cssClass
Definition: fieldset.phtml:25
addColumnAfter($columnId, $column, $after)
Definition: Extended.php:333
setData($key, $value=null)
Definition: DataObject.php:72
_exportCsvItem(\Magento\Framework\DataObject $item, \Magento\Framework\Filesystem\File\WriteInterface $stream)
Definition: Extended.php:987
$items
if(!isset($_GET['name'])) $name
Definition: log.php:14