Hi,
I want to share my latest plugin creation work. The client needs to export records based on a filter from the list of records to csv. It needs to export the total records, based on the filter and based on the filter the given page of records.
My springboard for this issue was topic Select all record on filtered list [resolved] - October CMS. Thanks to the author of the solution. I needed to extend it with a few options. I also added an option to export only records that are checked.
The first thing you need to do is create a plugin with models, a controller, and also a model for export. Then add the following function to the controller for the list of records, name it as you wish.
path: AuthorPlugin\NamePlugin\Controllers\ExampleController.php
# add new function
public function onGetFilteredRecords(){
$this->makeLists();
# get ListWidget
$listWidget = $this->asExtension('ListController')->listGetWidget();
# query params - page number
$page = get('page');
# get filename from data attribute
$filename = post('filename');
# post payload data - list of checked records
$checked = post('checked');
# how many records on page
$recordsPerPage = $listWidget->recordsPerPage;
# prepare query FilterScope from listWidget
$query = $listWidget->prepareQuery();
# need visible columns on list
$columns = $listWidget->getVisibleColumns();
# prepare simple columns array column_key => column_label to export
$columnList = [];
foreach ($columns as $attribute => $column) {
$columnList[$attribute] = $column->label;
}
# if specific records are selected
if(isset($checked)) {
$query->whereIn('id', $checked);
# then no need query GET param Page
$page = null;
}
# if only query GET param Page
if(isset($page) && !empty($page)) {
$query->forPage($page, $recordsPerPage);
}
# get all records
$records = $query->get();
# using Export model
$modelExport = new \AuthorPlugin\NamePlugin\Models\ExampleExport();
# set records to process export
$modelExport->setModelRecords($records);
# need know file extension
$ext = pathinfo($filename, PATHINFO_EXTENSION);
# set extension to model Export
$exportOptions['fileFormat'] = $ext;
# set file format
$modelExport->file_format = $exportOptions['fileFormat'];
# need create file reference to download
$reference = $modelExport->export($columnList, $exportOptions);
# create download full link to file
$fileUrl = $this->actionUrl('download',$reference.'/'.$filename);
return [
'fileUrl' => $fileUrl
];
}
The second thing what you need is edit your model ExampleExport to add custom function to set your model records to process.
path: AuthorPlugin\NamePlugin\Models\ExampleExport.php
class ExampleExport extends \Backend\Models\ExportModel
{
protected $_records;
# new function
public function setModelRecords($records)
{
$this->_records = $records;
}
public function exportData($columns, $sessionKey = null)
{
# edit this line
$records = (isset($this->_records)) ? $this->_records : Example::all();
$records->each(function($record) use ($columns) {
$record->addVisible($columns);
});
return $records->toArray();
}
}
The third thing what you need add button to list toolbar.
path: AuthorPlugin\NamePlugin\Controllers\example\_list_toolbar.php
..buttons before...
<button
class="btn btn-default"
data-request-data="{filename:'export.csv'}"
data-list-checked-request
data-request-success="window.location = data.fileUrl; setTimeout(function(){ window.location.reload() },500)"
data-stripe-load-indicator
data-request="onGetFilteredRecords">
Get Filtered Records
</button>
..buttons after...
Data attributes:
data-request-data=“{filename:‘export.csv’}” - this defines the filename with the extension, if you want to change the format to json, rewrite the extension
data-request-success=“window.location = data.fileUrl; setTimeout(function(){ window.location.reload() },500)” - function onGetFilteredRecords return object with fileUrl to download file, setTimeout needed because if some records is checked we need to reset table after download file
Change path: AuthorPlugin\NamePlugin to your path to plugin, also name of ListController and ExampleExport model
I will be very happy if you send any suggestions on how to make even better use of the original export model for exporting filtered records.