2015-08-22 16:33:00 +10:00
|
|
|
<?php namespace Backend\Behaviors;
|
|
|
|
|
|
|
|
use Lang;
|
|
|
|
use Backend;
|
2015-09-29 14:09:23 +02:00
|
|
|
use ApplicationException;
|
2015-08-22 16:33:00 +10:00
|
|
|
use Backend\Classes\ControllerBehavior;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used for reordering and sorting records.
|
|
|
|
*
|
2017-03-23 08:48:26 +11:00
|
|
|
* This behavior is implemented in the controller like so:
|
|
|
|
*
|
|
|
|
* public $implement = [
|
|
|
|
* 'Backend.Behaviors.ReorderController',
|
|
|
|
* ];
|
|
|
|
*
|
|
|
|
* public $reorderConfig = 'config_reorder.yaml';
|
|
|
|
*
|
|
|
|
* The `$reorderConfig` property makes reference to the configuration
|
|
|
|
* values as either a YAML file, located in the controller view directory,
|
|
|
|
* or directly as a PHP array.
|
|
|
|
*
|
2015-08-22 16:33:00 +10:00
|
|
|
* @package october\backend
|
|
|
|
* @author Alexey Bobkov, Samuel Georges
|
|
|
|
*/
|
|
|
|
class ReorderController extends ControllerBehavior
|
|
|
|
{
|
|
|
|
/**
|
2017-03-16 06:26:14 +11:00
|
|
|
* @inheritDoc
|
2015-08-22 16:33:00 +10:00
|
|
|
*/
|
|
|
|
protected $requiredProperties = ['reorderConfig'];
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var array Configuration values that must exist when applying the primary config file.
|
|
|
|
*/
|
|
|
|
protected $requiredConfig = ['modelClass'];
|
|
|
|
|
2019-04-19 14:01:01 -06:00
|
|
|
/**
|
|
|
|
* @var array Visible actions in context of the controller
|
|
|
|
*/
|
|
|
|
protected $actions = ['reorder'];
|
|
|
|
|
2015-08-22 16:33:00 +10:00
|
|
|
/**
|
|
|
|
* @var Model Import model
|
|
|
|
*/
|
|
|
|
public $model;
|
|
|
|
|
2015-08-22 16:39:09 +10:00
|
|
|
/**
|
|
|
|
* @var string Model attribute to use for the display name
|
|
|
|
*/
|
|
|
|
public $nameFrom = 'name';
|
|
|
|
|
2015-08-22 16:33:00 +10:00
|
|
|
/**
|
|
|
|
* @var bool Display parent/child relationships in the list.
|
|
|
|
*/
|
|
|
|
protected $showTree = false;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @var string Reordering mode:
|
|
|
|
* - simple: October\Rain\Database\Traits\Sortable
|
|
|
|
* - nested: October\Rain\Database\Traits\NestedTree
|
|
|
|
*/
|
2018-08-15 18:33:24 +02:00
|
|
|
protected $sortMode;
|
2015-08-22 16:33:00 +10:00
|
|
|
|
|
|
|
/**
|
|
|
|
* @var Backend\Classes\WidgetBase Reference to the widget used for the toolbar.
|
|
|
|
*/
|
|
|
|
protected $toolbarWidget;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Behavior constructor
|
|
|
|
* @param Backend\Classes\Controller $controller
|
|
|
|
*/
|
|
|
|
public function __construct($controller)
|
|
|
|
{
|
|
|
|
parent::__construct($controller);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Build configuration
|
|
|
|
*/
|
|
|
|
$this->config = $this->makeConfig($controller->reorderConfig, $this->requiredConfig);
|
|
|
|
|
|
|
|
/*
|
2015-08-22 16:39:09 +10:00
|
|
|
* Widgets
|
2015-08-22 16:33:00 +10:00
|
|
|
*/
|
|
|
|
if ($this->toolbarWidget = $this->makeToolbarWidget()) {
|
|
|
|
$this->toolbarWidget->bindToController();
|
|
|
|
}
|
2015-08-22 16:39:09 +10:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Populate from config
|
|
|
|
*/
|
|
|
|
$this->nameFrom = $this->getConfig('nameFrom', $this->nameFrom);
|
2015-08-22 16:33:00 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Controller actions
|
|
|
|
//
|
|
|
|
|
|
|
|
public function reorder()
|
|
|
|
{
|
|
|
|
$this->addJs('js/october.reorder.js', 'core');
|
|
|
|
|
2017-04-24 13:38:19 +02:00
|
|
|
$this->controller->pageTitle = $this->controller->pageTitle
|
2015-08-22 16:33:00 +10:00
|
|
|
?: Lang::get($this->getConfig('title', 'backend::lang.reorder.default_title'));
|
|
|
|
|
|
|
|
$this->validateModel();
|
|
|
|
$this->prepareVars();
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// AJAX
|
|
|
|
//
|
|
|
|
|
|
|
|
public function onReorder()
|
|
|
|
{
|
|
|
|
$model = $this->validateModel();
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Simple
|
|
|
|
*/
|
|
|
|
if ($this->sortMode == 'simple') {
|
2018-01-13 14:40:44 +11:00
|
|
|
if (
|
|
|
|
(!$ids = post('record_ids')) ||
|
|
|
|
(!$orders = post('sort_orders'))
|
|
|
|
) {
|
|
|
|
return;
|
|
|
|
}
|
2015-08-22 16:33:00 +10:00
|
|
|
|
|
|
|
$model->setSortableOrder($ids, $orders);
|
|
|
|
}
|
|
|
|
/*
|
|
|
|
* Nested set
|
|
|
|
*/
|
|
|
|
elseif ($this->sortMode == 'nested') {
|
|
|
|
$sourceNode = $model->find(post('sourceNode'));
|
|
|
|
$targetNode = post('targetNode') ? $model->find(post('targetNode')) : null;
|
|
|
|
|
2018-01-13 14:40:44 +11:00
|
|
|
if ($sourceNode == $targetNode) {
|
|
|
|
return;
|
|
|
|
}
|
2015-08-22 16:33:00 +10:00
|
|
|
|
|
|
|
switch (post('position')) {
|
|
|
|
case 'before':
|
|
|
|
$sourceNode->moveBefore($targetNode);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'after':
|
|
|
|
$sourceNode->moveAfter($targetNode);
|
|
|
|
break;
|
|
|
|
|
|
|
|
case 'child':
|
|
|
|
$sourceNode->makeChildOf($targetNode);
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
|
|
|
$sourceNode->makeRoot();
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Reordering
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Prepares common form data
|
|
|
|
*/
|
|
|
|
protected function prepareVars()
|
|
|
|
{
|
|
|
|
$this->vars['reorderRecords'] = $this->getRecords();
|
|
|
|
$this->vars['reorderModel'] = $this->model;
|
|
|
|
$this->vars['reorderSortMode'] = $this->sortMode;
|
|
|
|
$this->vars['reorderShowTree'] = $this->showTree;
|
|
|
|
$this->vars['reorderToolbarWidget'] = $this->toolbarWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function reorderRender()
|
|
|
|
{
|
|
|
|
return $this->reorderMakePartial('container');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function reorderGetModel()
|
|
|
|
{
|
|
|
|
if ($this->model !== null) {
|
|
|
|
return $this->model;
|
|
|
|
}
|
|
|
|
|
|
|
|
$modelClass = $this->getConfig('modelClass');
|
2018-01-13 14:40:44 +11:00
|
|
|
|
2015-08-22 16:33:00 +10:00
|
|
|
if (!$modelClass) {
|
|
|
|
throw new ApplicationException('Please specify the modelClass property for reordering');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $this->model = new $modelClass;
|
|
|
|
}
|
|
|
|
|
2015-08-22 16:39:09 +10:00
|
|
|
/**
|
|
|
|
* Returns the display name for a record.
|
|
|
|
* @return string
|
|
|
|
*/
|
|
|
|
public function reorderGetRecordName($record)
|
|
|
|
{
|
|
|
|
return $record->{$this->nameFrom};
|
|
|
|
}
|
|
|
|
|
2015-08-22 16:33:00 +10:00
|
|
|
/**
|
|
|
|
* Validate the supplied form model.
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
protected function validateModel()
|
|
|
|
{
|
|
|
|
$model = $this->controller->reorderGetModel();
|
|
|
|
$modelTraits = class_uses($model);
|
|
|
|
|
2018-01-13 14:40:44 +11:00
|
|
|
if (isset($modelTraits[\October\Rain\Database\Traits\Sortable::class])) {
|
2015-08-22 16:33:00 +10:00
|
|
|
$this->sortMode = 'simple';
|
|
|
|
}
|
2018-01-13 14:40:44 +11:00
|
|
|
elseif (isset($modelTraits[\October\Rain\Database\Traits\NestedTree::class])) {
|
2015-08-22 16:33:00 +10:00
|
|
|
$this->sortMode = 'nested';
|
|
|
|
$this->showTree = true;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
throw new ApplicationException('The model must implement the NestedTree or Sortable traits.');
|
|
|
|
}
|
|
|
|
|
|
|
|
return $model;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Returns all the records from the supplied model.
|
|
|
|
* @return Collection
|
|
|
|
*/
|
|
|
|
protected function getRecords()
|
|
|
|
{
|
|
|
|
$records = null;
|
2015-10-17 12:44:16 +11:00
|
|
|
$model = $this->controller->reorderGetModel();
|
|
|
|
$query = $model->newQuery();
|
|
|
|
|
|
|
|
$this->controller->reorderExtendQuery($query);
|
2015-08-22 16:33:00 +10:00
|
|
|
|
|
|
|
if ($this->sortMode == 'simple') {
|
2015-10-17 12:44:16 +11:00
|
|
|
$records = $query
|
|
|
|
->orderBy($model->getSortOrderColumn())
|
|
|
|
->get()
|
|
|
|
;
|
2015-08-22 16:33:00 +10:00
|
|
|
}
|
|
|
|
elseif ($this->sortMode == 'nested') {
|
2015-10-17 12:44:16 +11:00
|
|
|
$records = $query->getNested();
|
2015-08-22 16:33:00 +10:00
|
|
|
}
|
|
|
|
|
|
|
|
return $records;
|
|
|
|
}
|
|
|
|
|
2015-10-15 17:01:44 +11:00
|
|
|
/**
|
|
|
|
* Extend the query used for finding reorder records. Extra conditions
|
|
|
|
* can be applied to the query, for example, $query->withTrashed();
|
|
|
|
* @param October\Rain\Database\Builder $query
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function reorderExtendQuery($query)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2015-08-22 16:33:00 +10:00
|
|
|
//
|
|
|
|
// Widgets
|
|
|
|
//
|
|
|
|
|
|
|
|
protected function makeToolbarWidget()
|
|
|
|
{
|
|
|
|
if ($toolbarConfig = $this->getConfig('toolbar')) {
|
|
|
|
$toolbarConfig = $this->makeConfig($toolbarConfig);
|
|
|
|
$toolbarWidget = $this->makeWidget('Backend\Widgets\Toolbar', $toolbarConfig);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
$toolbarWidget = null;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $toolbarWidget;
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Helpers
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Controller accessor for making partials within this behavior.
|
|
|
|
* @param string $partial
|
|
|
|
* @param array $params
|
|
|
|
* @return string Partial contents
|
|
|
|
*/
|
|
|
|
public function reorderMakePartial($partial, $params = [])
|
|
|
|
{
|
2018-01-13 14:40:44 +11:00
|
|
|
$contents = $this->controller->makePartial(
|
|
|
|
'reorder_' . $partial,
|
|
|
|
$params + $this->vars,
|
|
|
|
false
|
|
|
|
);
|
|
|
|
|
2015-08-22 16:33:00 +10:00
|
|
|
if (!$contents) {
|
|
|
|
$contents = $this->makePartial($partial, $params);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $contents;
|
|
|
|
}
|
2015-09-29 14:09:23 +02:00
|
|
|
}
|