Add export action to ListController behavior

This commit is contained in:
Samuel Georges 2015-01-27 20:02:20 +11:00
parent 4a81e096fa
commit 7c1de4f728
7 changed files with 90 additions and 17 deletions

View File

@ -1,3 +1,6 @@
* **Build 18x** (2015-01-xx)
- Lists now support exporting to CSV format via the default **export** controller action.
* **Build 183** (2015-01-22) * **Build 183** (2015-01-22)
- Relation Controller now supports *has one* and *belongs to* relations (see Backend > Relations docs). - Relation Controller now supports *has one* and *belongs to* relations (see Backend > Relations docs).

File diff suppressed because one or more lines are too long

View File

@ -404,13 +404,6 @@ table.table.data {
} }
} }
.list-header:first-of-type {
margin-top: -20px;
> .control-toolbar {
padding-top: 20px;
}
}
// //
// Responsive Table // Responsive Table
// //

View File

@ -5,6 +5,8 @@ use Lang;
use Event; use Event;
use System\Classes\SystemException; use System\Classes\SystemException;
use Backend\Classes\ControllerBehavior; use Backend\Classes\ControllerBehavior;
use League\Csv\Writer;
use SplTempFileObject;
/** /**
* List Controller Behavior * List Controller Behavior
@ -246,6 +248,15 @@ class ListController extends ControllerBehavior
$this->makeLists(); $this->makeLists();
} }
/**
* Export Controller action.
* @return void
*/
public function export()
{
return $this->listExportCsv();
}
/** /**
* Renders the widget collection. * Renders the widget collection.
* @param string $definition Optional list definition. * @param string $definition Optional list definition.
@ -307,6 +318,70 @@ class ListController extends ControllerBehavior
return array_get($this->listWidgets, $definition); return array_get($this->listWidgets, $definition);
} }
/**
* Returns the list results as a CSV export.
*/
public function listExportCsv($options = [], $definition = null)
{
/*
* Locate widget
*/
if (!count($this->listWidgets)) {
$this->makeLists();
}
if (!$definition || !isset($this->listDefinitions[$definition])) {
$definition = $this->primaryDefinition;
}
$widget = $this->listWidgets[$definition];
/*
* Parse options
*/
$defaultOptions = [
'filename' => 'export.csv'
];
$options = array_merge($defaultOptions, $options);
extract($options);
/*
* Prepare CSV
*/
$csv = Writer::createFromFileObject(new SplTempFileObject);
$csv->setNullHandlingMode(Writer::NULL_AS_EMPTY);
/*
* Add headers
*/
$headers = [];
$columns = $widget->getVisibleColumns();
foreach ($columns as $column) {
$headers[] = $column->label;
}
$csv->insertOne($headers);
/*
* Add records
*/
$model = $widget->prepareModel();
$results = $model->get();
foreach ($results as $result) {
$record = [];
foreach ($columns as $column) {
$record[] = $widget->getColumnValue($result, $column);
}
$csv->insertOne($record);
}
/*
* Output
*/
$csv->output($filename);
exit;
}
// //
// Overrides // Overrides
// //

View File

@ -2,6 +2,6 @@
data-control="popup" data-control="popup"
data-handler="onRelationButtonCreate" data-handler="onRelationButtonCreate"
href="javascript:;" href="javascript:;"
class="btn btn-sm btn-primary oc-icon-file-o"> class="btn btn-sm btn-primary oc-icon-file">
<?= e(trans('backend::lang.relation.create_name', ['name'=>trans($relationLabel)])) ?> <?= e(trans('backend::lang.relation.create_name', ['name'=>trans($relationLabel)])) ?>
</a> </a>

View File

@ -253,7 +253,9 @@ abstract class WidgetBase
{ {
// Removes Class name and "Controllers" directory // Removes Class name and "Controllers" directory
$rootNamespace = Str::getClassId(Str::getClassNamespace(Str::getClassNamespace($this->controller))); $rootNamespace = Str::getClassId(Str::getClassNamespace(Str::getClassNamespace($this->controller)));
return 'widget.' . $rootNamespace . '-' . $this->controller->getId() . '-' . $this->getId();
// The controller action is intentionally omitted, session should be shared for all actions
return 'widget.' . $rootNamespace . '-' . class_basename($this->controller) . '-' . $this->getId();
} }
/** /**

View File

@ -190,7 +190,7 @@ class Lists extends WidgetBase
public function prepareVars() public function prepareVars()
{ {
$this->vars['cssClasses'] = implode(' ', $this->cssClasses); $this->vars['cssClasses'] = implode(' ', $this->cssClasses);
$this->vars['columns'] = $this->getVisibleListColumns(); $this->vars['columns'] = $this->getVisibleColumns();
$this->vars['columnTotal'] = $this->getTotalColumns(); $this->vars['columnTotal'] = $this->getTotalColumns();
$this->vars['records'] = $this->getRecords(); $this->vars['records'] = $this->getRecords();
$this->vars['noRecordsMessage'] = trans($this->noRecordsMessage); $this->vars['noRecordsMessage'] = trans($this->noRecordsMessage);
@ -323,7 +323,7 @@ class Lists extends WidgetBase
/* /*
* Prepare related eager loads (withs) and custom selects (joins) * Prepare related eager loads (withs) and custom selects (joins)
*/ */
foreach ($this->getVisibleListColumns() as $column) { foreach ($this->getVisibleColumns() as $column) {
if (!$this->isColumnRelated($column) || (!isset($column->sqlSelect) && !isset($column->valueFrom))) { if (!$this->isColumnRelated($column) || (!isset($column->sqlSelect) && !isset($column->valueFrom))) {
continue; continue;
@ -365,7 +365,7 @@ class Lists extends WidgetBase
/* /*
* Custom select queries * Custom select queries
*/ */
foreach ($this->getVisibleListColumns() as $column) { foreach ($this->getVisibleColumns() as $column) {
if (!isset($column->sqlSelect)) { if (!isset($column->sqlSelect)) {
continue; continue;
} }
@ -522,7 +522,7 @@ class Lists extends WidgetBase
/** /**
* Returns the list columns that are visible by list settings or default * Returns the list columns that are visible by list settings or default
*/ */
protected function getVisibleListColumns() public function getVisibleColumns()
{ {
$definitions = $this->defineListColumns(); $definitions = $this->defineListColumns();
$columns = []; $columns = [];
@ -645,7 +645,7 @@ class Lists extends WidgetBase
*/ */
protected function getTotalColumns() protected function getTotalColumns()
{ {
$columns = $this->visibleColumns ?: $this->getVisibleListColumns(); $columns = $this->visibleColumns ?: $this->getVisibleColumns();
$total = count($columns); $total = count($columns);
if ($this->showCheckboxes) { if ($this->showCheckboxes) {
$total++; $total++;
@ -1005,7 +1005,7 @@ class Lists extends WidgetBase
* First available column * First available column
*/ */
if ($this->sortColumn === null || !$this->isSortable($this->sortColumn)) { if ($this->sortColumn === null || !$this->isSortable($this->sortColumn)) {
$columns = $this->visibleColumns ?: $this->getVisibleListColumns(); $columns = $this->visibleColumns ?: $this->getVisibleColumns();
$columns = array_filter($columns, function($column){ return $column->sortable; }); $columns = array_filter($columns, function($column){ return $column->sortable; });
$this->sortColumn = key($columns); $this->sortColumn = key($columns);
$this->sortDirection = 'desc'; $this->sortDirection = 'desc';
@ -1101,7 +1101,7 @@ class Lists extends WidgetBase
$column->invisible = true; $column->invisible = true;
} }
return array_merge($columns, $this->getVisibleListColumns()); return array_merge($columns, $this->getVisibleColumns());
} }
// //