mirror of
https://github.com/symbiote/silverstripe-gridfieldextensions.git
synced 2024-06-14 16:51:53 +02:00
PSR-2 code style guidelines
This commit is contained in:
parent
4ee047b591
commit
2acf6dee47
|
@ -11,95 +11,105 @@ use SilverStripe\View\ArrayData;
|
||||||
* A modal search dialog which uses search context to search for and add
|
* A modal search dialog which uses search context to search for and add
|
||||||
* existing records to a grid field.
|
* existing records to a grid field.
|
||||||
*/
|
*/
|
||||||
class GridFieldAddExistingSearchButton implements GridField_HTMLProvider, GridField_URLHandler {
|
class GridFieldAddExistingSearchButton implements GridField_HTMLProvider, GridField_URLHandler
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'handleSearch'
|
'handleSearch'
|
||||||
);
|
);
|
||||||
|
|
||||||
protected $title;
|
protected $title;
|
||||||
protected $fragment;
|
protected $fragment;
|
||||||
protected $searchList;
|
protected $searchList;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $fragment
|
* @param string $fragment
|
||||||
*/
|
*/
|
||||||
public function __construct($fragment = 'buttons-before-left') {
|
public function __construct($fragment = 'buttons-before-left')
|
||||||
$this->fragment = $fragment;
|
{
|
||||||
$this->title = _t('GridFieldExtensions.ADDEXISTING', 'Add Existing');
|
$this->fragment = $fragment;
|
||||||
}
|
$this->title = _t('GridFieldExtensions.ADDEXISTING', 'Add Existing');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTitle() {
|
public function getTitle()
|
||||||
return $this->title;
|
{
|
||||||
}
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $title
|
* @param string $title
|
||||||
* @return GridFieldAddExistingSearchButton $this
|
* @return GridFieldAddExistingSearchButton $this
|
||||||
*/
|
*/
|
||||||
public function setTitle($title) {
|
public function setTitle($title)
|
||||||
$this->title = $title;
|
{
|
||||||
return $this;
|
$this->title = $title;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFragment() {
|
public function getFragment()
|
||||||
return $this->fragment;
|
{
|
||||||
}
|
return $this->fragment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $fragment
|
* @param string $fragment
|
||||||
* @return GridFieldAddExistingSearchButton $this
|
* @return GridFieldAddExistingSearchButton $this
|
||||||
*/
|
*/
|
||||||
public function setFragment($fragment) {
|
public function setFragment($fragment)
|
||||||
$this->fragment = $fragment;
|
{
|
||||||
return $this;
|
$this->fragment = $fragment;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets a custom list to use to provide the searchable items.
|
* Sets a custom list to use to provide the searchable items.
|
||||||
*
|
*
|
||||||
* @param SS_List $list
|
* @param SS_List $list
|
||||||
* @return GridFieldAddExistingSearchButton $this
|
* @return GridFieldAddExistingSearchButton $this
|
||||||
*/
|
*/
|
||||||
public function setSearchList(SS_List $list) {
|
public function setSearchList(SS_List $list)
|
||||||
$this->searchList = $list;
|
{
|
||||||
return $this;
|
$this->searchList = $list;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return SS_List|null
|
* @return SS_List|null
|
||||||
*/
|
*/
|
||||||
public function getSearchList() {
|
public function getSearchList()
|
||||||
return $this->searchList;
|
{
|
||||||
}
|
return $this->searchList;
|
||||||
|
}
|
||||||
|
|
||||||
public function getHTMLFragments($grid) {
|
public function getHTMLFragments($grid)
|
||||||
GridFieldExtensions::include_requirements();
|
{
|
||||||
|
GridFieldExtensions::include_requirements();
|
||||||
|
|
||||||
$data = new ArrayData(array(
|
$data = new ArrayData(array(
|
||||||
'Title' => $this->getTitle(),
|
'Title' => $this->getTitle(),
|
||||||
'Link' => $grid->Link('add-existing-search')
|
'Link' => $grid->Link('add-existing-search')
|
||||||
));
|
));
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$this->fragment => $data->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldAddExistingSearchButton'),
|
$this->fragment => $data->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldAddExistingSearchButton'),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getURLHandlers($grid) {
|
public function getURLHandlers($grid)
|
||||||
return array(
|
{
|
||||||
'add-existing-search' => 'handleSearch'
|
return array(
|
||||||
);
|
'add-existing-search' => 'handleSearch'
|
||||||
}
|
);
|
||||||
|
}
|
||||||
public function handleSearch($grid, $request) {
|
|
||||||
return new GridFieldAddExistingSearchHandler($grid, $this);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public function handleSearch($grid, $request)
|
||||||
|
{
|
||||||
|
return new GridFieldAddExistingSearchHandler($grid, $this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,107 +14,115 @@ use SilverStripe\ORM\PaginatedList;
|
||||||
* Used by {@link GridFieldAddExistingSearchButton} to provide the searching
|
* Used by {@link GridFieldAddExistingSearchButton} to provide the searching
|
||||||
* functionality.
|
* functionality.
|
||||||
*/
|
*/
|
||||||
class GridFieldAddExistingSearchHandler extends RequestHandler {
|
class GridFieldAddExistingSearchHandler extends RequestHandler
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'index',
|
'index',
|
||||||
'add',
|
'add',
|
||||||
'SearchForm'
|
'SearchForm'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var GridField
|
* @var GridField
|
||||||
*/
|
*/
|
||||||
protected $grid;
|
protected $grid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var GridFieldAddExistingSearchButton
|
* @var GridFieldAddExistingSearchButton
|
||||||
*/
|
*/
|
||||||
protected $button;
|
protected $button;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var SearchContext
|
* @var SearchContext
|
||||||
*/
|
*/
|
||||||
protected $context;
|
protected $context;
|
||||||
|
|
||||||
public function __construct($grid, $button) {
|
public function __construct($grid, $button)
|
||||||
$this->grid = $grid;
|
{
|
||||||
$this->button = $button;
|
$this->grid = $grid;
|
||||||
$this->context = singleton($grid->getModelClass())->getDefaultSearchContext();
|
$this->button = $button;
|
||||||
|
$this->context = singleton($grid->getModelClass())->getDefaultSearchContext();
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index() {
|
public function index()
|
||||||
return $this->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldAddExistingSearchHandler');
|
{
|
||||||
}
|
return $this->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldAddExistingSearchHandler');
|
||||||
|
}
|
||||||
|
|
||||||
public function add($request) {
|
public function add($request)
|
||||||
if(!$id = $request->postVar('id')) {
|
{
|
||||||
$this->httpError(400);
|
if (!$id = $request->postVar('id')) {
|
||||||
}
|
$this->httpError(400);
|
||||||
|
}
|
||||||
|
|
||||||
$list = $this->grid->getList();
|
$list = $this->grid->getList();
|
||||||
$item = DataList::create($list->dataClass())->byID($id);
|
$item = DataList::create($list->dataClass())->byID($id);
|
||||||
|
|
||||||
if(!$item) {
|
if (!$item) {
|
||||||
$this->httpError(400);
|
$this->httpError(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$list->add($item);
|
$list->add($item);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Form
|
* @return Form
|
||||||
*/
|
*/
|
||||||
public function SearchForm() {
|
public function SearchForm()
|
||||||
$form = new Form(
|
{
|
||||||
$this,
|
$form = new Form(
|
||||||
'SilverStripe\\CMS\\Search\\SearchForm',
|
$this,
|
||||||
$this->context->getFields(),
|
'SilverStripe\\CMS\\Search\\SearchForm',
|
||||||
new FieldList(
|
$this->context->getFields(),
|
||||||
FormAction::create('doSearch', _t('GridFieldExtensions.SEARCH', 'Search'))
|
new FieldList(
|
||||||
->setUseButtonTag(true)
|
FormAction::create('doSearch', _t('GridFieldExtensions.SEARCH', 'Search'))
|
||||||
->addExtraClass('ss-ui-button')
|
->setUseButtonTag(true)
|
||||||
->setAttribute('data-icon', 'magnifier')
|
->addExtraClass('ss-ui-button')
|
||||||
)
|
->setAttribute('data-icon', 'magnifier')
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
$form->addExtraClass('stacked add-existing-search-form');
|
$form->addExtraClass('stacked add-existing-search-form');
|
||||||
$form->setFormMethod('GET');
|
$form->setFormMethod('GET');
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function doSearch($data, $form) {
|
public function doSearch($data, $form)
|
||||||
$list = $this->context->getQuery($data, false, false, $this->getSearchList());
|
{
|
||||||
$list = $list->subtract($this->grid->getList());
|
$list = $this->context->getQuery($data, false, false, $this->getSearchList());
|
||||||
$list = new PaginatedList($list, $this->request);
|
$list = $list->subtract($this->grid->getList());
|
||||||
|
$list = new PaginatedList($list, $this->request);
|
||||||
|
|
||||||
$data = $this->customise(array(
|
$data = $this->customise(array(
|
||||||
'SearchForm' => $form,
|
'SearchForm' => $form,
|
||||||
'Items' => $list
|
'Items' => $list
|
||||||
));
|
));
|
||||||
return $data->index();
|
return $data->index();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Items() {
|
public function Items()
|
||||||
$list = $this->getSearchList();
|
{
|
||||||
$list = $list->subtract($this->grid->getList());
|
$list = $this->getSearchList();
|
||||||
$list = new PaginatedList($list, $this->request);
|
$list = $list->subtract($this->grid->getList());
|
||||||
|
$list = new PaginatedList($list, $this->request);
|
||||||
|
|
||||||
return $list;
|
return $list;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Link($action = null) {
|
public function Link($action = null)
|
||||||
return Controller::join_links($this->grid->Link(), 'add-existing-search', $action);
|
{
|
||||||
}
|
return Controller::join_links($this->grid->Link(), 'add-existing-search', $action);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @return DataList
|
|
||||||
*/
|
|
||||||
protected function getSearchList() {
|
|
||||||
return $this->button->getSearchList() ?: DataList::create($this->grid->getList()->dataClass());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DataList
|
||||||
|
*/
|
||||||
|
protected function getSearchList()
|
||||||
|
{
|
||||||
|
return $this->button->getSearchList() ?: DataList::create($this->grid->getList()->dataClass());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,170 +17,181 @@ use SilverStripe\View\Requirements;
|
||||||
/**
|
/**
|
||||||
* Builds on the {@link GridFieldEditableColumns} component to allow creating new records.
|
* Builds on the {@link GridFieldEditableColumns} component to allow creating new records.
|
||||||
*/
|
*/
|
||||||
class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler {
|
class GridFieldAddNewInlineButton implements GridField_HTMLProvider, GridField_SaveHandler
|
||||||
|
{
|
||||||
|
|
||||||
private $fragment;
|
private $fragment;
|
||||||
|
|
||||||
private $title;
|
private $title;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $fragment the fragment to render the button in
|
* @param string $fragment the fragment to render the button in
|
||||||
*/
|
*/
|
||||||
public function __construct($fragment = 'buttons-before-left') {
|
public function __construct($fragment = 'buttons-before-left')
|
||||||
$this->setFragment($fragment);
|
{
|
||||||
$this->setTitle(_t('GridFieldExtensions.ADD', 'Add'));
|
$this->setFragment($fragment);
|
||||||
}
|
$this->setTitle(_t('GridFieldExtensions.ADD', 'Add'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the fragment name this button is rendered into.
|
* Gets the fragment name this button is rendered into.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFragment() {
|
public function getFragment()
|
||||||
return $this->fragment;
|
{
|
||||||
}
|
return $this->fragment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the fragment name this button is rendered into.
|
* Sets the fragment name this button is rendered into.
|
||||||
*
|
*
|
||||||
* @param string $fragment
|
* @param string $fragment
|
||||||
* @return GridFieldAddNewInlineButton $this
|
* @return GridFieldAddNewInlineButton $this
|
||||||
*/
|
*/
|
||||||
public function setFragment($fragment) {
|
public function setFragment($fragment)
|
||||||
$this->fragment = $fragment;
|
{
|
||||||
return $this;
|
$this->fragment = $fragment;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the button title text.
|
* Gets the button title text.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTitle() {
|
public function getTitle()
|
||||||
return $this->title;
|
{
|
||||||
}
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the button title text.
|
* Sets the button title text.
|
||||||
*
|
*
|
||||||
* @param string $title
|
* @param string $title
|
||||||
* @return GridFieldAddNewInlineButton $this
|
* @return GridFieldAddNewInlineButton $this
|
||||||
*/
|
*/
|
||||||
public function setTitle($title) {
|
public function setTitle($title)
|
||||||
$this->title = $title;
|
{
|
||||||
return $this;
|
$this->title = $title;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
public function getHTMLFragments($grid) {
|
public function getHTMLFragments($grid)
|
||||||
if($grid->getList() && !singleton($grid->getModelClass())->canCreate()) {
|
{
|
||||||
return array();
|
if ($grid->getList() && !singleton($grid->getModelClass())->canCreate()) {
|
||||||
}
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
$fragment = $this->getFragment();
|
$fragment = $this->getFragment();
|
||||||
|
|
||||||
if(!$editable = $grid->getConfig()->getComponentByType('GridFieldEditableColumns')) {
|
if (!$editable = $grid->getConfig()->getComponentByType('GridFieldEditableColumns')) {
|
||||||
throw new Exception('Inline adding requires the editable columns component');
|
throw new Exception('Inline adding requires the editable columns component');
|
||||||
}
|
}
|
||||||
|
|
||||||
Requirements::javascript(THIRDPARTY_DIR . '/javascript-templates/tmpl.js');
|
Requirements::javascript(THIRDPARTY_DIR . '/javascript-templates/tmpl.js');
|
||||||
GridFieldExtensions::include_requirements();
|
GridFieldExtensions::include_requirements();
|
||||||
|
|
||||||
$data = new ArrayData(array(
|
$data = new ArrayData(array(
|
||||||
'Title' => $this->getTitle(),
|
'Title' => $this->getTitle(),
|
||||||
));
|
));
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$fragment => $data->renderWith(__CLASS__),
|
$fragment => $data->renderWith(__CLASS__),
|
||||||
'after' => $this->getRowTemplate($grid, $editable)
|
'after' => $this->getRowTemplate($grid, $editable)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getRowTemplate(GridField $grid, GridFieldEditableColumns $editable) {
|
private function getRowTemplate(GridField $grid, GridFieldEditableColumns $editable)
|
||||||
$columns = new ArrayList();
|
{
|
||||||
$handled = array_keys($editable->getDisplayFields($grid));
|
$columns = new ArrayList();
|
||||||
|
$handled = array_keys($editable->getDisplayFields($grid));
|
||||||
|
|
||||||
if($grid->getList()) {
|
if ($grid->getList()) {
|
||||||
$record = Object::create($grid->getModelClass());
|
$record = Object::create($grid->getModelClass());
|
||||||
} else {
|
} else {
|
||||||
$record = null;
|
$record = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
$fields = $editable->getFields($grid, $record);
|
$fields = $editable->getFields($grid, $record);
|
||||||
|
|
||||||
foreach($grid->getColumns() as $column) {
|
foreach ($grid->getColumns() as $column) {
|
||||||
if(in_array($column, $handled)) {
|
if (in_array($column, $handled)) {
|
||||||
$field = $fields->dataFieldByName($column);
|
$field = $fields->dataFieldByName($column);
|
||||||
$field->setName(sprintf(
|
$field->setName(sprintf(
|
||||||
'%s[%s][{%%=o.num%%}][%s]', $grid->getName(), __CLASS__, $field->getName()
|
'%s[%s][{%%=o.num%%}][%s]',
|
||||||
));
|
$grid->getName(),
|
||||||
|
__CLASS__,
|
||||||
|
$field->getName()
|
||||||
|
));
|
||||||
|
|
||||||
$content = $field->Field();
|
$content = $field->Field();
|
||||||
} else {
|
} else {
|
||||||
$content = $grid->getColumnContent($record, $column);
|
$content = $grid->getColumnContent($record, $column);
|
||||||
|
|
||||||
// Convert GridFieldEditableColumns to the template format
|
// Convert GridFieldEditableColumns to the template format
|
||||||
$content = str_replace(
|
$content = str_replace(
|
||||||
'[GridFieldEditableColumns][0]',
|
'[GridFieldEditableColumns][0]',
|
||||||
'[GridFieldAddNewInlineButton][{%=o.num%}]',
|
'[GridFieldAddNewInlineButton][{%=o.num%}]',
|
||||||
$content
|
$content
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$attrs = '';
|
$attrs = '';
|
||||||
|
|
||||||
foreach($grid->getColumnAttributes($record, $column) as $attr => $val) {
|
foreach ($grid->getColumnAttributes($record, $column) as $attr => $val) {
|
||||||
$attrs .= sprintf(' %s="%s"', $attr, Convert::raw2att($val));
|
$attrs .= sprintf(' %s="%s"', $attr, Convert::raw2att($val));
|
||||||
}
|
}
|
||||||
|
|
||||||
$columns->push(new ArrayData(array(
|
$columns->push(new ArrayData(array(
|
||||||
'Content' => $content,
|
'Content' => $content,
|
||||||
'Attributes' => $attrs,
|
'Attributes' => $attrs,
|
||||||
'IsActions' => $column == 'Actions'
|
'IsActions' => $column == 'Actions'
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $columns->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldAddNewInlineRow');
|
return $columns->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldAddNewInlineRow');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handleSave(GridField $grid, DataObjectInterface $record) {
|
public function handleSave(GridField $grid, DataObjectInterface $record)
|
||||||
$list = $grid->getList();
|
{
|
||||||
$value = $grid->Value();
|
$list = $grid->getList();
|
||||||
|
$value = $grid->Value();
|
||||||
|
|
||||||
if(!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) {
|
if (!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$class = $grid->getModelClass();
|
$class = $grid->getModelClass();
|
||||||
/** @var GridFieldEditableColumns $editable */
|
/** @var GridFieldEditableColumns $editable */
|
||||||
$editable = $grid->getConfig()->getComponentByType('SilverStripe\\GridFieldExtensions\\GridFieldEditableColumns');
|
$editable = $grid->getConfig()->getComponentByType('SilverStripe\\GridFieldExtensions\\GridFieldEditableColumns');
|
||||||
/** @var GridFieldOrderableRows $sortable */
|
/** @var GridFieldOrderableRows $sortable */
|
||||||
$sortable = $grid->getConfig()->getComponentByType('SilverStripe\\GridFieldExtensions\\GridFieldOrderableRows');
|
$sortable = $grid->getConfig()->getComponentByType('SilverStripe\\GridFieldExtensions\\GridFieldOrderableRows');
|
||||||
$form = $editable->getForm($grid, $record);
|
$form = $editable->getForm($grid, $record);
|
||||||
|
|
||||||
if(!singleton($class)->canCreate()) {
|
if (!singleton($class)->canCreate()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach($value[__CLASS__] as $fields) {
|
foreach ($value[__CLASS__] as $fields) {
|
||||||
$item = $class::create();
|
$item = $class::create();
|
||||||
$extra = array();
|
$extra = array();
|
||||||
|
|
||||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||||
$form->saveInto($item);
|
$form->saveInto($item);
|
||||||
|
|
||||||
// Check if we are also sorting these records
|
// Check if we are also sorting these records
|
||||||
if ($sortable) {
|
if ($sortable) {
|
||||||
$sortField = $sortable->getSortField();
|
$sortField = $sortable->getSortField();
|
||||||
$item->setField($sortField, $fields[$sortField]);
|
$item->setField($sortField, $fields[$sortField]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($list instanceof ManyManyList) {
|
if ($list instanceof ManyManyList) {
|
||||||
$extra = array_intersect_key($form->getData(), (array) $list->getExtraFields());
|
$extra = array_intersect_key($form->getData(), (array) $list->getExtraFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
$item->write();
|
|
||||||
$list->add($item, $extra);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$item->write();
|
||||||
|
$list->add($item, $extra);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,217 +20,237 @@ use ReflectionClass;
|
||||||
* By default the list of classes that are createable is the grid field's model class, and any
|
* By default the list of classes that are createable is the grid field's model class, and any
|
||||||
* subclasses. This can be customised using {@link setClasses()}.
|
* subclasses. This can be customised using {@link setClasses()}.
|
||||||
*/
|
*/
|
||||||
class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URLHandler {
|
class GridFieldAddNewMultiClass implements GridField_HTMLProvider, GridField_URLHandler
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'handleAdd'
|
'handleAdd'
|
||||||
);
|
);
|
||||||
|
|
||||||
// Should we add an empty string to the add class dropdown?
|
// Should we add an empty string to the add class dropdown?
|
||||||
private static $showEmptyString = true;
|
private static $showEmptyString = true;
|
||||||
|
|
||||||
private $fragment;
|
private $fragment;
|
||||||
|
|
||||||
private $title;
|
private $title;
|
||||||
|
|
||||||
private $classes;
|
private $classes;
|
||||||
|
|
||||||
private $defaultClass;
|
private $defaultClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $itemRequestClass = 'SilverStripe\\Forms\\GridField\\GridFieldAddNewMultiClassHandler';
|
protected $itemRequestClass = 'SilverStripe\\Forms\\GridField\\GridFieldAddNewMultiClassHandler';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $fragment the fragment to render the button in
|
* @param string $fragment the fragment to render the button in
|
||||||
*/
|
*/
|
||||||
public function __construct($fragment = 'before') {
|
public function __construct($fragment = 'before')
|
||||||
$this->setFragment($fragment);
|
{
|
||||||
$this->setTitle(_t('GridFieldExtensions.ADD', 'Add'));
|
$this->setFragment($fragment);
|
||||||
}
|
$this->setTitle(_t('GridFieldExtensions.ADD', 'Add'));
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the fragment name this button is rendered into.
|
* Gets the fragment name this button is rendered into.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getFragment() {
|
public function getFragment()
|
||||||
return $this->fragment;
|
{
|
||||||
}
|
return $this->fragment;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the fragment name this button is rendered into.
|
* Sets the fragment name this button is rendered into.
|
||||||
*
|
*
|
||||||
* @param string $fragment
|
* @param string $fragment
|
||||||
* @return GridFieldAddNewMultiClass $this
|
* @return GridFieldAddNewMultiClass $this
|
||||||
*/
|
*/
|
||||||
public function setFragment($fragment) {
|
public function setFragment($fragment)
|
||||||
$this->fragment = $fragment;
|
{
|
||||||
return $this;
|
$this->fragment = $fragment;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the button title text.
|
* Gets the button title text.
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTitle() {
|
public function getTitle()
|
||||||
return $this->title;
|
{
|
||||||
}
|
return $this->title;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the button title text.
|
* Sets the button title text.
|
||||||
*
|
*
|
||||||
* @param string $title
|
* @param string $title
|
||||||
* @return GridFieldAddNewMultiClass $this
|
* @return GridFieldAddNewMultiClass $this
|
||||||
*/
|
*/
|
||||||
public function setTitle($title) {
|
public function setTitle($title)
|
||||||
$this->title = $title;
|
{
|
||||||
return $this;
|
$this->title = $title;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the classes that can be created using this button, defaulting to the model class and
|
* Gets the classes that can be created using this button, defaulting to the model class and
|
||||||
* its subclasses.
|
* its subclasses.
|
||||||
*
|
*
|
||||||
* @param GridField $grid
|
* @param GridField $grid
|
||||||
* @return array a map of class name to title
|
* @return array a map of class name to title
|
||||||
*/
|
*/
|
||||||
public function getClasses(GridField $grid) {
|
public function getClasses(GridField $grid)
|
||||||
$result = array();
|
{
|
||||||
|
$result = array();
|
||||||
|
|
||||||
if(is_null($this->classes)) {
|
if (is_null($this->classes)) {
|
||||||
$classes = array_values(ClassInfo::subclassesFor($grid->getModelClass()));
|
$classes = array_values(ClassInfo::subclassesFor($grid->getModelClass()));
|
||||||
sort($classes);
|
sort($classes);
|
||||||
} else {
|
} else {
|
||||||
$classes = $this->classes;
|
$classes = $this->classes;
|
||||||
}
|
}
|
||||||
|
|
||||||
$kill_ancestors = array();
|
$kill_ancestors = array();
|
||||||
foreach($classes as $class => $title) {
|
foreach ($classes as $class => $title) {
|
||||||
if(!is_string($class)) {
|
if (!is_string($class)) {
|
||||||
$class = $title;
|
$class = $title;
|
||||||
}
|
}
|
||||||
if (!class_exists($class)) {
|
if (!class_exists($class)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
$is_abstract = (($reflection = new ReflectionClass($class)) && $reflection->isAbstract());
|
$is_abstract = (($reflection = new ReflectionClass($class)) && $reflection->isAbstract());
|
||||||
if (!$is_abstract && $class === $title) {
|
if (!$is_abstract && $class === $title) {
|
||||||
$title = singleton($class)->i18n_singular_name();
|
$title = singleton($class)->i18n_singular_name();
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($ancestor_to_hide = Config::inst()->get($class, 'hide_ancestor', Config::FIRST_SET)) {
|
if ($ancestor_to_hide = Config::inst()->get($class, 'hide_ancestor', Config::FIRST_SET)) {
|
||||||
$kill_ancestors[$ancestor_to_hide] = true;
|
$kill_ancestors[$ancestor_to_hide] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($is_abstract || !singleton($class)->canCreate()) {
|
if ($is_abstract || !singleton($class)->canCreate()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$result[$class] = $title;
|
$result[$class] = $title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if($kill_ancestors) {
|
if ($kill_ancestors) {
|
||||||
foreach($kill_ancestors as $class => $bool) {
|
foreach ($kill_ancestors as $class => $bool) {
|
||||||
unset($result[$class]);
|
unset($result[$class]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $result;
|
return $result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the classes that can be created using this button.
|
* Sets the classes that can be created using this button.
|
||||||
*
|
*
|
||||||
* @param array $classes a set of class names, optionally mapped to titles
|
* @param array $classes a set of class names, optionally mapped to titles
|
||||||
* @return GridFieldAddNewMultiClass $this
|
* @return GridFieldAddNewMultiClass $this
|
||||||
*/
|
*/
|
||||||
public function setClasses(array $classes, $default = null) {
|
public function setClasses(array $classes, $default = null)
|
||||||
$this->classes = $classes;
|
{
|
||||||
if($default) $this->defaultClass = $default;
|
$this->classes = $classes;
|
||||||
return $this;
|
if ($default) {
|
||||||
}
|
$this->defaultClass = $default;
|
||||||
|
}
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sets the default class that is selected automatically.
|
* Sets the default class that is selected automatically.
|
||||||
*
|
*
|
||||||
* @param string $default the class name to use as default
|
* @param string $default the class name to use as default
|
||||||
* @return GridFieldAddNewMultiClass $this
|
* @return GridFieldAddNewMultiClass $this
|
||||||
*/
|
*/
|
||||||
public function setDefaultClass($default) {
|
public function setDefaultClass($default)
|
||||||
$this->defaultClass = $default;
|
{
|
||||||
return $this;
|
$this->defaultClass = $default;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles adding a new instance of a selected class.
|
* Handles adding a new instance of a selected class.
|
||||||
*
|
*
|
||||||
* @param GridField $grid
|
* @param GridField $grid
|
||||||
* @param SS_HTTPRequest $request
|
* @param SS_HTTPRequest $request
|
||||||
* @return GridFieldAddNewMultiClassHandler
|
* @return GridFieldAddNewMultiClassHandler
|
||||||
*/
|
*/
|
||||||
public function handleAdd($grid, $request) {
|
public function handleAdd($grid, $request)
|
||||||
$class = $request->param('ClassName');
|
{
|
||||||
$classes = $this->getClasses($grid);
|
$class = $request->param('ClassName');
|
||||||
$component = $grid->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDetailForm');
|
$classes = $this->getClasses($grid);
|
||||||
|
$component = $grid->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldDetailForm');
|
||||||
|
|
||||||
if(!$component) {
|
if (!$component) {
|
||||||
throw new Exception('The add new multi class component requires the detail form component.');
|
throw new Exception('The add new multi class component requires the detail form component.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$class || !array_key_exists($class, $classes)) {
|
if (!$class || !array_key_exists($class, $classes)) {
|
||||||
throw new HTTPResponse_Exception(400);
|
throw new HTTPResponse_Exception(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
$handler = Object::create($this->itemRequestClass,
|
$handler = Object::create(
|
||||||
$grid, $component, new $class(), $grid->getForm()->getController(), 'add-multi-class'
|
$this->itemRequestClass,
|
||||||
);
|
$grid,
|
||||||
$handler->setTemplate($component->getTemplate());
|
$component,
|
||||||
|
new $class(),
|
||||||
|
$grid->getForm()->getController(),
|
||||||
|
'add-multi-class'
|
||||||
|
);
|
||||||
|
$handler->setTemplate($component->getTemplate());
|
||||||
|
|
||||||
return $handler;
|
return $handler;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function getHTMLFragments($grid) {
|
public function getHTMLFragments($grid)
|
||||||
$classes = $this->getClasses($grid);
|
{
|
||||||
|
$classes = $this->getClasses($grid);
|
||||||
|
|
||||||
if(!count($classes)) {
|
if (!count($classes)) {
|
||||||
return array();
|
return array();
|
||||||
}
|
}
|
||||||
|
|
||||||
GridFieldExtensions::include_requirements();
|
GridFieldExtensions::include_requirements();
|
||||||
|
|
||||||
$field = new DropdownField(sprintf('%s[ClassName]', __CLASS__), '', $classes, $this->defaultClass);
|
$field = new DropdownField(sprintf('%s[ClassName]', __CLASS__), '', $classes, $this->defaultClass);
|
||||||
if (Config::inst()->get(__CLASS__, 'showEmptyString')) {
|
if (Config::inst()->get(__CLASS__, 'showEmptyString')) {
|
||||||
$field->setEmptyString(_t('GridFieldExtensions.SELECTTYPETOCREATE', '(Select type to create)'));
|
$field->setEmptyString(_t('GridFieldExtensions.SELECTTYPETOCREATE', '(Select type to create)'));
|
||||||
}
|
}
|
||||||
$field->addExtraClass('no-change-track');
|
$field->addExtraClass('no-change-track');
|
||||||
|
|
||||||
$data = new ArrayData(array(
|
$data = new ArrayData(array(
|
||||||
'Title' => $this->getTitle(),
|
'Title' => $this->getTitle(),
|
||||||
'Link' => Controller::join_links($grid->Link(), 'add-multi-class', '{class}'),
|
'Link' => Controller::join_links($grid->Link(), 'add-multi-class', '{class}'),
|
||||||
'ClassField' => $field
|
'ClassField' => $field
|
||||||
));
|
));
|
||||||
|
|
||||||
return array(
|
return array(
|
||||||
$this->getFragment() => $data->renderWith(__CLASS__)
|
$this->getFragment() => $data->renderWith(__CLASS__)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritDoc}
|
* {@inheritDoc}
|
||||||
*/
|
*/
|
||||||
public function getURLHandlers($grid) {
|
public function getURLHandlers($grid)
|
||||||
return array(
|
{
|
||||||
'add-multi-class/$ClassName!' => 'handleAdd'
|
return array(
|
||||||
);
|
'add-multi-class/$ClassName!' => 'handleAdd'
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public function setItemRequestClass($class) {
|
public function setItemRequestClass($class)
|
||||||
$this->itemRequestClass = $class;
|
{
|
||||||
return $this;
|
$this->itemRequestClass = $class;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,16 +8,19 @@ use SilverStripe\Forms\GridField\GridFieldDetailForm_ItemRequest;
|
||||||
/**
|
/**
|
||||||
* A custom grid field request handler that allows interacting with form fields when adding records.
|
* A custom grid field request handler that allows interacting with form fields when adding records.
|
||||||
*/
|
*/
|
||||||
class GridFieldAddNewMultiClassHandler extends GridFieldDetailForm_ItemRequest {
|
class GridFieldAddNewMultiClassHandler extends GridFieldDetailForm_ItemRequest
|
||||||
|
{
|
||||||
public function Link($action = null) {
|
|
||||||
if($this->record->ID) {
|
|
||||||
return parent::Link($action);
|
|
||||||
} else {
|
|
||||||
return Controller::join_links(
|
|
||||||
$this->gridField->Link(), 'add-multi-class', get_class($this->record)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public function Link($action = null)
|
||||||
|
{
|
||||||
|
if ($this->record->ID) {
|
||||||
|
return parent::Link($action);
|
||||||
|
} else {
|
||||||
|
return Controller::join_links(
|
||||||
|
$this->gridField->Link(),
|
||||||
|
'add-multi-class',
|
||||||
|
get_class($this->record)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,260 +29,271 @@ use SilverStripe\ORM\ManyManyList;
|
||||||
* - An array with a `field` key->response specifying the field class to use.
|
* - An array with a `field` key->response specifying the field class to use.
|
||||||
*/
|
*/
|
||||||
class GridFieldEditableColumns extends GridFieldDataColumns implements
|
class GridFieldEditableColumns extends GridFieldDataColumns implements
|
||||||
GridField_HTMLProvider,
|
GridField_HTMLProvider,
|
||||||
GridField_SaveHandler,
|
GridField_SaveHandler,
|
||||||
GridField_URLHandler {
|
GridField_URLHandler
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'handleForm'
|
'handleForm'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var Form[]
|
* @var Form[]
|
||||||
*/
|
*/
|
||||||
protected $forms = array();
|
protected $forms = array();
|
||||||
|
|
||||||
public function getColumnContent($grid, $record, $col) {
|
public function getColumnContent($grid, $record, $col)
|
||||||
if(!$record->canEdit()) {
|
{
|
||||||
return parent::getColumnContent($grid, $record, $col);
|
if (!$record->canEdit()) {
|
||||||
}
|
return parent::getColumnContent($grid, $record, $col);
|
||||||
|
}
|
||||||
|
|
||||||
$fields = $this->getForm($grid, $record)->Fields();
|
$fields = $this->getForm($grid, $record)->Fields();
|
||||||
|
|
||||||
if (!$this->displayFields)
|
if (!$this->displayFields) {
|
||||||
{
|
// If setDisplayFields() not used, utilize $summary_fields
|
||||||
// If setDisplayFields() not used, utilize $summary_fields
|
// in a way similar to base class
|
||||||
// in a way similar to base class
|
$colRelation = explode('.', $col);
|
||||||
$colRelation = explode('.', $col);
|
$value = $grid->getDataFieldValue($record, $colRelation[0]);
|
||||||
$value = $grid->getDataFieldValue($record, $colRelation[0]);
|
$field = $fields->fieldByName($colRelation[0]);
|
||||||
$field = $fields->fieldByName($colRelation[0]);
|
if (!$field || $field->isReadonly() || $field->isDisabled()) {
|
||||||
if (!$field || $field->isReadonly() || $field->isDisabled()) {
|
return parent::getColumnContent($grid, $record, $col);
|
||||||
return parent::getColumnContent($grid, $record, $col);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure this field is available to edit on the record
|
// Ensure this field is available to edit on the record
|
||||||
// (ie. Maybe its readonly due to certain circumstances, or removed and not editable)
|
// (ie. Maybe its readonly due to certain circumstances, or removed and not editable)
|
||||||
$cmsFields = $record->getCMSFields();
|
$cmsFields = $record->getCMSFields();
|
||||||
$cmsField = $cmsFields->dataFieldByName($colRelation[0]);
|
$cmsField = $cmsFields->dataFieldByName($colRelation[0]);
|
||||||
if (!$cmsField || $cmsField->isReadonly() || $cmsField->isDisabled())
|
if (!$cmsField || $cmsField->isReadonly() || $cmsField->isDisabled()) {
|
||||||
{
|
return parent::getColumnContent($grid, $record, $col);
|
||||||
return parent::getColumnContent($grid, $record, $col);
|
}
|
||||||
}
|
$field = clone $field;
|
||||||
$field = clone $field;
|
} else {
|
||||||
}
|
$value = $grid->getDataFieldValue($record, $col);
|
||||||
else
|
$rel = (strpos($col, '.') === false); // field references a relation value
|
||||||
{
|
$field = ($rel) ? clone $fields->fieldByName($col) : new ReadonlyField($col);
|
||||||
$value = $grid->getDataFieldValue($record, $col);
|
|
||||||
$rel = (strpos($col,'.') === false); // field references a relation value
|
|
||||||
$field = ($rel) ? clone $fields->fieldByName($col) : new ReadonlyField($col);
|
|
||||||
|
|
||||||
if(!$field) {
|
if (!$field) {
|
||||||
throw new Exception("Could not find the field '$col'");
|
throw new Exception("Could not find the field '$col'");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(array_key_exists($col, $this->fieldCasting)) {
|
if (array_key_exists($col, $this->fieldCasting)) {
|
||||||
$value = $grid->getCastedValue($value, $this->fieldCasting[$col]);
|
$value = $grid->getCastedValue($value, $this->fieldCasting[$col]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$value = $this->formatValue($grid, $record, $col, $value);
|
$value = $this->formatValue($grid, $record, $col, $value);
|
||||||
|
|
||||||
$field->setName($this->getFieldName($field->getName(), $grid, $record));
|
$field->setName($this->getFieldName($field->getName(), $grid, $record));
|
||||||
$field->setValue($value);
|
$field->setValue($value);
|
||||||
|
|
||||||
if ($field instanceof HtmlEditorField) {
|
if ($field instanceof HtmlEditorField) {
|
||||||
return $field->FieldHolder();
|
return $field->FieldHolder();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $field->forTemplate();
|
return $field->forTemplate();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getHTMLFragments($grid) {
|
public function getHTMLFragments($grid)
|
||||||
GridFieldExtensions::include_requirements();
|
{
|
||||||
$grid->addExtraClass('ss-gridfield-editable');
|
GridFieldExtensions::include_requirements();
|
||||||
}
|
$grid->addExtraClass('ss-gridfield-editable');
|
||||||
|
}
|
||||||
|
|
||||||
public function handleSave(GridField $grid, DataObjectInterface $record) {
|
public function handleSave(GridField $grid, DataObjectInterface $record)
|
||||||
$list = $grid->getList();
|
{
|
||||||
$value = $grid->Value();
|
$list = $grid->getList();
|
||||||
|
$value = $grid->Value();
|
||||||
|
|
||||||
if(!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) {
|
if (!isset($value[__CLASS__]) || !is_array($value[__CLASS__])) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @var GridFieldOrderableRows $sortable */
|
/** @var GridFieldOrderableRows $sortable */
|
||||||
$sortable = $grid->getConfig()->getComponentByType('SilverStripe\\GridFieldExtensions\\GridFieldOrderableRows');
|
$sortable = $grid->getConfig()->getComponentByType('SilverStripe\\GridFieldExtensions\\GridFieldOrderableRows');
|
||||||
|
|
||||||
$form = $this->getForm($grid, $record);
|
$form = $this->getForm($grid, $record);
|
||||||
|
|
||||||
foreach($value[__CLASS__] as $id => $fields) {
|
foreach ($value[__CLASS__] as $id => $fields) {
|
||||||
if(!is_numeric($id) || !is_array($fields)) {
|
if (!is_numeric($id) || !is_array($fields)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$item = $list->byID($id);
|
$item = $list->byID($id);
|
||||||
|
|
||||||
if(!$item || !$item->canEdit()) {
|
if (!$item || !$item->canEdit()) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
$extra = array();
|
$extra = array();
|
||||||
|
|
||||||
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
$form->loadDataFrom($fields, Form::MERGE_CLEAR_MISSING);
|
||||||
$form->saveInto($item);
|
$form->saveInto($item);
|
||||||
|
|
||||||
// Check if we are also sorting these records
|
// Check if we are also sorting these records
|
||||||
if ($sortable) {
|
if ($sortable) {
|
||||||
$sortField = $sortable->getSortField();
|
$sortField = $sortable->getSortField();
|
||||||
$item->setField($sortField, $fields[$sortField]);
|
$item->setField($sortField, $fields[$sortField]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if($list instanceof ManyManyList) {
|
if ($list instanceof ManyManyList) {
|
||||||
$extra = array_intersect_key($form->getData(), (array) $list->getExtraFields());
|
$extra = array_intersect_key($form->getData(), (array) $list->getExtraFields());
|
||||||
}
|
}
|
||||||
|
|
||||||
$item->write();
|
$item->write();
|
||||||
$list->add($item, $extra);
|
$list->add($item, $extra);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function handleForm(GridField $grid, $request) {
|
public function handleForm(GridField $grid, $request)
|
||||||
$id = $request->param('ID');
|
{
|
||||||
$list = $grid->getList();
|
$id = $request->param('ID');
|
||||||
|
$list = $grid->getList();
|
||||||
|
|
||||||
if(!ctype_digit($id)) {
|
if (!ctype_digit($id)) {
|
||||||
throw new HTTPResponse_Exception(null, 400);
|
throw new HTTPResponse_Exception(null, 400);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$record = $list->byID($id)) {
|
if (!$record = $list->byID($id)) {
|
||||||
throw new HTTPResponse_Exception(null, 404);
|
throw new HTTPResponse_Exception(null, 404);
|
||||||
}
|
}
|
||||||
|
|
||||||
$form = $this->getForm($grid, $record);
|
$form = $this->getForm($grid, $record);
|
||||||
|
|
||||||
foreach($form->Fields() as $field) {
|
foreach ($form->Fields() as $field) {
|
||||||
$field->setName($this->getFieldName($field->getName(), $grid, $record));
|
$field->setName($this->getFieldName($field->getName(), $grid, $record));
|
||||||
}
|
}
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getURLHandlers($grid) {
|
public function getURLHandlers($grid)
|
||||||
return array(
|
{
|
||||||
'editable/form/$ID' => 'handleForm'
|
return array(
|
||||||
);
|
'editable/form/$ID' => 'handleForm'
|
||||||
}
|
);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the field list for a record.
|
* Gets the field list for a record.
|
||||||
*
|
*
|
||||||
* @param GridField $grid
|
* @param GridField $grid
|
||||||
* @param DataObjectInterface $record
|
* @param DataObjectInterface $record
|
||||||
* @return FieldList
|
* @return FieldList
|
||||||
*/
|
*/
|
||||||
public function getFields(GridField $grid, DataObjectInterface $record) {
|
public function getFields(GridField $grid, DataObjectInterface $record)
|
||||||
$cols = $this->getDisplayFields($grid);
|
{
|
||||||
$fields = new FieldList();
|
$cols = $this->getDisplayFields($grid);
|
||||||
|
$fields = new FieldList();
|
||||||
|
|
||||||
$list = $grid->getList();
|
$list = $grid->getList();
|
||||||
$class = $list ? $list->dataClass() : null;
|
$class = $list ? $list->dataClass() : null;
|
||||||
|
|
||||||
foreach($cols as $col => $info) {
|
foreach ($cols as $col => $info) {
|
||||||
$field = null;
|
$field = null;
|
||||||
|
|
||||||
if($info instanceof Closure) {
|
if ($info instanceof Closure) {
|
||||||
$field = call_user_func($info, $record, $col, $grid);
|
$field = call_user_func($info, $record, $col, $grid);
|
||||||
} elseif(is_array($info)) {
|
} elseif (is_array($info)) {
|
||||||
if(isset($info['callback'])) {
|
if (isset($info['callback'])) {
|
||||||
$field = call_user_func($info['callback'], $record, $col, $grid);
|
$field = call_user_func($info['callback'], $record, $col, $grid);
|
||||||
} elseif(isset($info['field'])) {
|
} elseif (isset($info['field'])) {
|
||||||
if ($info['field'] == 'SilverStripe\\Forms\\LiteralField') {
|
if ($info['field'] == 'SilverStripe\\Forms\\LiteralField') {
|
||||||
$field = new $info['field']($col, null);
|
$field = new $info['field']($col, null);
|
||||||
} else {
|
} else {
|
||||||
$field = new $info['field']($col);
|
$field = new $info['field']($col);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$field instanceof FormField) {
|
if (!$field instanceof FormField) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
'The field for column "%s" is not a valid form field',
|
'The field for column "%s" is not a valid form field',
|
||||||
$col
|
$col
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$field && $list instanceof ManyManyList) {
|
if (!$field && $list instanceof ManyManyList) {
|
||||||
$extra = $list->getExtraFields();
|
$extra = $list->getExtraFields();
|
||||||
|
|
||||||
if($extra && array_key_exists($col, $extra)) {
|
if ($extra && array_key_exists($col, $extra)) {
|
||||||
$field = Object::create_from_string($extra[$col], $col)->scaffoldFormField();
|
$field = Object::create_from_string($extra[$col], $col)->scaffoldFormField();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!$field) {
|
if (!$field) {
|
||||||
if (!$this->displayFields)
|
if (!$this->displayFields) {
|
||||||
{
|
// If setDisplayFields() not used, utilize $summary_fields
|
||||||
// If setDisplayFields() not used, utilize $summary_fields
|
// in a way similar to base class
|
||||||
// in a way similar to base class
|
//
|
||||||
//
|
// Allows use of 'MyBool.Nice' and 'MyHTML.NoHTML' so that
|
||||||
// Allows use of 'MyBool.Nice' and 'MyHTML.NoHTML' so that
|
// GridFields not using inline editing still look good or
|
||||||
// GridFields not using inline editing still look good or
|
// revert to looking good in cases where the field isn't
|
||||||
// revert to looking good in cases where the field isn't
|
// available or is readonly
|
||||||
// available or is readonly
|
//
|
||||||
//
|
$colRelation = explode('.', $col);
|
||||||
$colRelation = explode('.', $col);
|
if ($class && $obj = singleton($class)->dbObject($colRelation[0])) {
|
||||||
if($class && $obj = singleton($class)->dbObject($colRelation[0])) {
|
$field = $obj->scaffoldFormField();
|
||||||
$field = $obj->scaffoldFormField();
|
} else {
|
||||||
} else {
|
$field = new ReadonlyField($colRelation[0]);
|
||||||
$field = new ReadonlyField($colRelation[0]);
|
}
|
||||||
}
|
} elseif ($class && $obj = singleton($class)->dbObject($col)) {
|
||||||
}
|
$field = $obj->scaffoldFormField();
|
||||||
else if($class && $obj = singleton($class)->dbObject($col)) {
|
} else {
|
||||||
$field = $obj->scaffoldFormField();
|
$field = new ReadonlyField($col);
|
||||||
} else {
|
}
|
||||||
$field = new ReadonlyField($col);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!$field instanceof FormField) {
|
if (!$field instanceof FormField) {
|
||||||
throw new Exception(sprintf(
|
throw new Exception(sprintf(
|
||||||
'Invalid form field instance for column "%s"', $col
|
'Invalid form field instance for column "%s"',
|
||||||
));
|
$col
|
||||||
}
|
));
|
||||||
|
}
|
||||||
|
|
||||||
// Add CSS class for interactive fields
|
// Add CSS class for interactive fields
|
||||||
if (!($field->isReadOnly() || $field instanceof LiteralField)) $field->addExtraClass('editable-column-field');
|
if (!($field->isReadOnly() || $field instanceof LiteralField)) {
|
||||||
|
$field->addExtraClass('editable-column-field');
|
||||||
|
}
|
||||||
|
|
||||||
$fields->push($field);
|
$fields->push($field);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $fields;
|
return $fields;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the form instance for a record.
|
* Gets the form instance for a record.
|
||||||
*
|
*
|
||||||
* @param GridField $grid
|
* @param GridField $grid
|
||||||
* @param DataObjectInterface $record
|
* @param DataObjectInterface $record
|
||||||
* @return Form
|
* @return Form
|
||||||
*/
|
*/
|
||||||
public function getForm(GridField $grid, DataObjectInterface $record) {
|
public function getForm(GridField $grid, DataObjectInterface $record)
|
||||||
$fields = $this->getFields($grid, $record);
|
{
|
||||||
|
$fields = $this->getFields($grid, $record);
|
||||||
|
|
||||||
$form = new Form($this, null, $fields, new FieldList());
|
$form = new Form($this, null, $fields, new FieldList());
|
||||||
$form->loadDataFrom($record);
|
$form->loadDataFrom($record);
|
||||||
|
|
||||||
$form->setFormAction(Controller::join_links(
|
$form->setFormAction(Controller::join_links(
|
||||||
$grid->Link(), 'editable/form', $record->ID
|
$grid->Link(),
|
||||||
));
|
'editable/form',
|
||||||
|
$record->ID
|
||||||
|
));
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getFieldName($name, GridField $grid, DataObjectInterface $record) {
|
|
||||||
return sprintf(
|
|
||||||
'%s[%s][%s][%s]', $grid->getName(), __CLASS__, $record->ID, $name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
protected function getFieldName($name, GridField $grid, DataObjectInterface $record)
|
||||||
|
{
|
||||||
|
return sprintf(
|
||||||
|
'%s[%s][%s][%s]',
|
||||||
|
$grid->getName(),
|
||||||
|
__CLASS__,
|
||||||
|
$record->ID,
|
||||||
|
$name
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,18 @@ use SilverStripe\View\Requirements;
|
||||||
/**
|
/**
|
||||||
* Utility functions for the grid fields extension module.
|
* Utility functions for the grid fields extension module.
|
||||||
*/
|
*/
|
||||||
class GridFieldExtensions {
|
class GridFieldExtensions
|
||||||
|
{
|
||||||
|
|
||||||
public static function include_requirements() {
|
public static function include_requirements()
|
||||||
$moduleDir = self::get_module_dir();
|
{
|
||||||
Requirements::css($moduleDir.'/css/GridFieldExtensions.css');
|
$moduleDir = self::get_module_dir();
|
||||||
Requirements::javascript($moduleDir.'/javascript/GridFieldExtensions.js');
|
Requirements::css($moduleDir.'/css/GridFieldExtensions.css');
|
||||||
}
|
Requirements::javascript($moduleDir.'/javascript/GridFieldExtensions.js');
|
||||||
|
}
|
||||||
public static function get_module_dir() {
|
|
||||||
return basename(dirname(__DIR__));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public static function get_module_dir()
|
||||||
|
{
|
||||||
|
return basename(dirname(__DIR__));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,67 +8,75 @@ use SilverStripe\View\ArrayData;
|
||||||
/**
|
/**
|
||||||
* Displays a link to an external source referenced 'external link'
|
* Displays a link to an external source referenced 'external link'
|
||||||
*/
|
*/
|
||||||
class GridFieldExternalLink extends GridFieldDataColumns {
|
class GridFieldExternalLink extends GridFieldDataColumns
|
||||||
|
{
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a column for the actions
|
* Add a column for the actions
|
||||||
*
|
*
|
||||||
* @param type $gridField
|
* @param type $gridField
|
||||||
* @param array $columns
|
* @param array $columns
|
||||||
*/
|
*/
|
||||||
public function augmentColumns($gridField, &$columns) {
|
public function augmentColumns($gridField, &$columns)
|
||||||
if(!in_array('Actions', $columns)) $columns[] = 'Actions';
|
{
|
||||||
}
|
if (!in_array('Actions', $columns)) {
|
||||||
|
$columns[] = 'Actions';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return any special attributes that will be used for FormField::create_tag()
|
* Return any special attributes that will be used for FormField::create_tag()
|
||||||
*
|
*
|
||||||
* @param GridField $gridField
|
* @param GridField $gridField
|
||||||
* @param DataObject $record
|
* @param DataObject $record
|
||||||
* @param string $columnName
|
* @param string $columnName
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getColumnAttributes($gridField, $record, $columnName) {
|
public function getColumnAttributes($gridField, $record, $columnName)
|
||||||
return array('class' => 'col-buttons');
|
{
|
||||||
}
|
return array('class' => 'col-buttons');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the title
|
* Add the title
|
||||||
*
|
*
|
||||||
* @param GridField $gridField
|
* @param GridField $gridField
|
||||||
* @param string $columnName
|
* @param string $columnName
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function getColumnMetadata($gridField, $columnName) {
|
public function getColumnMetadata($gridField, $columnName)
|
||||||
if($columnName == 'Actions') {
|
{
|
||||||
return array('title' => '');
|
if ($columnName == 'Actions') {
|
||||||
}
|
return array('title' => '');
|
||||||
return array();
|
}
|
||||||
}
|
return array();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Which columns are handled by this component
|
* Which columns are handled by this component
|
||||||
*
|
*
|
||||||
* @param type $gridField
|
* @param type $gridField
|
||||||
* @return type
|
* @return type
|
||||||
*/
|
*/
|
||||||
public function getColumnsHandled($gridField) {
|
public function getColumnsHandled($gridField)
|
||||||
return array('Actions');
|
{
|
||||||
}
|
return array('Actions');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param GridField $gridField
|
* @param GridField $gridField
|
||||||
* @param DataObject $record
|
* @param DataObject $record
|
||||||
* @param string $columnName
|
* @param string $columnName
|
||||||
*
|
*
|
||||||
* @return string - the HTML for the column
|
* @return string - the HTML for the column
|
||||||
*/
|
*/
|
||||||
public function getColumnContent($gridField, $record, $columnName) {
|
public function getColumnContent($gridField, $record, $columnName)
|
||||||
$data = new ArrayData(array(
|
{
|
||||||
'Link' => $record->hasMethod('getExternalLink') ? $record->getExternalLink() : $record->ExternalLink,
|
$data = new ArrayData(array(
|
||||||
'Text' => $record->hasMethod('getExternalLinkText') ? $record->getExternalLinkText() : 'External Link'
|
'Link' => $record->hasMethod('getExternalLink') ? $record->getExternalLink() : $record->ExternalLink,
|
||||||
));
|
'Text' => $record->hasMethod('getExternalLinkText') ? $record->getExternalLinkText() : 'External Link'
|
||||||
|
));
|
||||||
|
|
||||||
return $data->renderWith('GridFieldExternalLink');
|
return $data->renderWith('GridFieldExternalLink');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,544 +29,567 @@ use SilverStripe\View\ViewableData;
|
||||||
* the sort field.
|
* the sort field.
|
||||||
*/
|
*/
|
||||||
class GridFieldOrderableRows extends RequestHandler implements
|
class GridFieldOrderableRows extends RequestHandler implements
|
||||||
GridField_ColumnProvider,
|
GridField_ColumnProvider,
|
||||||
GridField_DataManipulator,
|
GridField_DataManipulator,
|
||||||
GridField_HTMLProvider,
|
GridField_HTMLProvider,
|
||||||
GridField_URLHandler,
|
GridField_URLHandler,
|
||||||
GridField_SaveHandler {
|
GridField_SaveHandler
|
||||||
|
{
|
||||||
/**
|
|
||||||
* @see $immediateUpdate
|
/**
|
||||||
* @var boolean
|
* @see $immediateUpdate
|
||||||
*/
|
* @var boolean
|
||||||
private static $default_immediate_update = true;
|
*/
|
||||||
|
private static $default_immediate_update = true;
|
||||||
private static $allowed_actions = array(
|
|
||||||
'handleReorder',
|
private static $allowed_actions = array(
|
||||||
'handleMoveToPage'
|
'handleReorder',
|
||||||
);
|
'handleMoveToPage'
|
||||||
|
);
|
||||||
/**
|
|
||||||
* The database field which specifies the sort, defaults to "Sort".
|
/**
|
||||||
*
|
* The database field which specifies the sort, defaults to "Sort".
|
||||||
* @see setSortField()
|
*
|
||||||
* @var string
|
* @see setSortField()
|
||||||
*/
|
* @var string
|
||||||
protected $sortField;
|
*/
|
||||||
|
protected $sortField;
|
||||||
/**
|
|
||||||
* If set to true, when an item is re-ordered, it will update on the
|
/**
|
||||||
* database and refresh the gridfield. When set to false, it will only
|
* If set to true, when an item is re-ordered, it will update on the
|
||||||
* update the sort order when the record is saved.
|
* database and refresh the gridfield. When set to false, it will only
|
||||||
*
|
* update the sort order when the record is saved.
|
||||||
* @var boolean
|
*
|
||||||
*/
|
* @var boolean
|
||||||
protected $immediateUpdate;
|
*/
|
||||||
|
protected $immediateUpdate;
|
||||||
/**
|
|
||||||
* Extra sort fields to apply before the sort field.
|
/**
|
||||||
*
|
* Extra sort fields to apply before the sort field.
|
||||||
* @see setExtraSortFields()
|
*
|
||||||
* @var string|array
|
* @see setExtraSortFields()
|
||||||
*/
|
* @var string|array
|
||||||
protected $extraSortFields = null;
|
*/
|
||||||
|
protected $extraSortFields = null;
|
||||||
/**
|
|
||||||
* The number of the column containing the reorder handles
|
/**
|
||||||
*
|
* The number of the column containing the reorder handles
|
||||||
* @see setReorderColumnNumber()
|
*
|
||||||
* @var int
|
* @see setReorderColumnNumber()
|
||||||
*/
|
* @var int
|
||||||
protected $reorderColumnNumber = 0;
|
*/
|
||||||
|
protected $reorderColumnNumber = 0;
|
||||||
/**
|
|
||||||
* @param string $sortField
|
/**
|
||||||
*/
|
* @param string $sortField
|
||||||
public function __construct($sortField = 'Sort') {
|
*/
|
||||||
parent::__construct();
|
public function __construct($sortField = 'Sort')
|
||||||
$this->sortField = $sortField;
|
{
|
||||||
$this->immediateUpdate = $this->config()->default_immediate_update;
|
parent::__construct();
|
||||||
}
|
$this->sortField = $sortField;
|
||||||
|
$this->immediateUpdate = $this->config()->default_immediate_update;
|
||||||
/**
|
}
|
||||||
* @return string
|
|
||||||
*/
|
/**
|
||||||
public function getSortField() {
|
* @return string
|
||||||
return $this->sortField;
|
*/
|
||||||
}
|
public function getSortField()
|
||||||
|
{
|
||||||
/**
|
return $this->sortField;
|
||||||
* Sets the field used to specify the sort.
|
}
|
||||||
*
|
|
||||||
* @param string $sortField
|
/**
|
||||||
* @return GridFieldOrderableRows $this
|
* Sets the field used to specify the sort.
|
||||||
*/
|
*
|
||||||
public function setSortField($field) {
|
* @param string $sortField
|
||||||
$this->sortField = $field;
|
* @return GridFieldOrderableRows $this
|
||||||
return $this;
|
*/
|
||||||
}
|
public function setSortField($field)
|
||||||
|
{
|
||||||
/**
|
$this->sortField = $field;
|
||||||
* @return boolean
|
return $this;
|
||||||
*/
|
}
|
||||||
public function getImmediateUpdate() {
|
|
||||||
return $this->immediateUpdate;
|
/**
|
||||||
}
|
* @return boolean
|
||||||
|
*/
|
||||||
/**
|
public function getImmediateUpdate()
|
||||||
* @see $immediateUpdate
|
{
|
||||||
* @param boolean $immediateUpdate
|
return $this->immediateUpdate;
|
||||||
* @return GridFieldOrderableRows $this
|
}
|
||||||
*/
|
|
||||||
public function setImmediateUpdate($bool) {
|
/**
|
||||||
$this->immediateUpdate = $bool;
|
* @see $immediateUpdate
|
||||||
return $this;
|
* @param boolean $immediateUpdate
|
||||||
}
|
* @return GridFieldOrderableRows $this
|
||||||
|
*/
|
||||||
/**
|
public function setImmediateUpdate($bool)
|
||||||
* @return string|array
|
{
|
||||||
*/
|
$this->immediateUpdate = $bool;
|
||||||
public function getExtraSortFields() {
|
return $this;
|
||||||
return $this->extraSortFields;
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
/**
|
* @return string|array
|
||||||
* Sets extra sort fields to apply before the sort field.
|
*/
|
||||||
*
|
public function getExtraSortFields()
|
||||||
* @param string|array $fields
|
{
|
||||||
* @return GridFieldOrderableRows $this
|
return $this->extraSortFields;
|
||||||
*/
|
}
|
||||||
public function setExtraSortFields($fields) {
|
|
||||||
$this->extraSortFields = $fields;
|
/**
|
||||||
return $this;
|
* Sets extra sort fields to apply before the sort field.
|
||||||
}
|
*
|
||||||
|
* @param string|array $fields
|
||||||
/**
|
* @return GridFieldOrderableRows $this
|
||||||
* @return int
|
*/
|
||||||
*/
|
public function setExtraSortFields($fields)
|
||||||
public function getReorderColumnNumber() {
|
{
|
||||||
return $this->reorderColumnNumber;
|
$this->extraSortFields = $fields;
|
||||||
}
|
return $this;
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Sets the number of the column containing the reorder handles.
|
/**
|
||||||
*
|
* @return int
|
||||||
* @param int $colno
|
*/
|
||||||
* @return GridFieldOrderableRows $this
|
public function getReorderColumnNumber()
|
||||||
*/
|
{
|
||||||
public function setReorderColumnNumber($colno) {
|
return $this->reorderColumnNumber;
|
||||||
$this->reorderColumnNumber = $colno;
|
}
|
||||||
return $this;
|
|
||||||
}
|
/**
|
||||||
|
* Sets the number of the column containing the reorder handles.
|
||||||
/**
|
*
|
||||||
* Gets the table which contains the sort field.
|
* @param int $colno
|
||||||
*
|
* @return GridFieldOrderableRows $this
|
||||||
* @param DataList $list
|
*/
|
||||||
* @return string
|
public function setReorderColumnNumber($colno)
|
||||||
*/
|
{
|
||||||
public function getSortTable(SS_List $list) {
|
$this->reorderColumnNumber = $colno;
|
||||||
$field = $this->getSortField();
|
return $this;
|
||||||
|
}
|
||||||
if($list instanceof ManyManyList) {
|
|
||||||
$extra = $list->getExtraFields();
|
/**
|
||||||
$table = $list->getJoinTable();
|
* Gets the table which contains the sort field.
|
||||||
|
*
|
||||||
if($extra && array_key_exists($field, $extra)) {
|
* @param DataList $list
|
||||||
return $table;
|
* @return string
|
||||||
}
|
*/
|
||||||
}
|
public function getSortTable(SS_List $list)
|
||||||
|
{
|
||||||
$classes = ClassInfo::dataClassesFor($list->dataClass());
|
$field = $this->getSortField();
|
||||||
|
|
||||||
foreach($classes as $class) {
|
if ($list instanceof ManyManyList) {
|
||||||
if(singleton($class)->hasDataBaseField($field)) {
|
$extra = $list->getExtraFields();
|
||||||
return $class;
|
$table = $list->getJoinTable();
|
||||||
}
|
|
||||||
}
|
if ($extra && array_key_exists($field, $extra)) {
|
||||||
|
return $table;
|
||||||
throw new Exception("Couldn't find the sort field '$field'");
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function getURLHandlers($grid) {
|
$classes = ClassInfo::dataClassesFor($list->dataClass());
|
||||||
return array(
|
|
||||||
'POST reorder' => 'handleReorder',
|
foreach ($classes as $class) {
|
||||||
'POST movetopage' => 'handleMoveToPage'
|
if (singleton($class)->hasDataBaseField($field)) {
|
||||||
);
|
return $class;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
/**
|
|
||||||
* @param GridField $field
|
throw new Exception("Couldn't find the sort field '$field'");
|
||||||
*/
|
}
|
||||||
public function getHTMLFragments($field) {
|
|
||||||
GridFieldExtensions::include_requirements();
|
public function getURLHandlers($grid)
|
||||||
|
{
|
||||||
$field->addExtraClass('ss-gridfield-orderable');
|
return array(
|
||||||
$field->setAttribute('data-immediate-update', (string)(int)$this->immediateUpdate);
|
'POST reorder' => 'handleReorder',
|
||||||
$field->setAttribute('data-url-reorder', $field->Link('reorder'));
|
'POST movetopage' => 'handleMoveToPage'
|
||||||
$field->setAttribute('data-url-movetopage', $field->Link('movetopage'));
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function augmentColumns($grid, &$cols) {
|
/**
|
||||||
if(!in_array('Reorder', $cols) && $grid->getState()->GridFieldOrderableRows->enabled) {
|
* @param GridField $field
|
||||||
array_splice($cols, $this->reorderColumnNumber, 0, 'Reorder');
|
*/
|
||||||
}
|
public function getHTMLFragments($field)
|
||||||
}
|
{
|
||||||
|
GridFieldExtensions::include_requirements();
|
||||||
public function getColumnsHandled($grid) {
|
|
||||||
return array('Reorder');
|
$field->addExtraClass('ss-gridfield-orderable');
|
||||||
}
|
$field->setAttribute('data-immediate-update', (string)(int)$this->immediateUpdate);
|
||||||
|
$field->setAttribute('data-url-reorder', $field->Link('reorder'));
|
||||||
public function getColumnContent($grid, $record, $col) {
|
$field->setAttribute('data-url-movetopage', $field->Link('movetopage'));
|
||||||
// In case you are using GridFieldEditableColumns, this ensures that
|
}
|
||||||
// the correct sort order is saved. If you are not using that component,
|
|
||||||
// this will be ignored by other components, but will still work for this.
|
public function augmentColumns($grid, &$cols)
|
||||||
$sortFieldName = sprintf(
|
{
|
||||||
'%s[GridFieldEditableColumns][%s][%s]',
|
if (!in_array('Reorder', $cols) && $grid->getState()->GridFieldOrderableRows->enabled) {
|
||||||
$grid->getName(),
|
array_splice($cols, $this->reorderColumnNumber, 0, 'Reorder');
|
||||||
$record->ID,
|
}
|
||||||
$this->getSortField()
|
}
|
||||||
);
|
|
||||||
$sortField = new HiddenField($sortFieldName, false, $record->getField($this->getSortField()));
|
public function getColumnsHandled($grid)
|
||||||
$sortField->addExtraClass('ss-orderable-hidden-sort');
|
{
|
||||||
$sortField->setForm($grid->getForm());
|
return array('Reorder');
|
||||||
|
}
|
||||||
return ViewableData::create()->customise(array(
|
|
||||||
'SortField' => $sortField
|
public function getColumnContent($grid, $record, $col)
|
||||||
))->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldOrderableRowsDragHandle');
|
{
|
||||||
}
|
// In case you are using GridFieldEditableColumns, this ensures that
|
||||||
|
// the correct sort order is saved. If you are not using that component,
|
||||||
public function getColumnAttributes($grid, $record, $col) {
|
// this will be ignored by other components, but will still work for this.
|
||||||
return array('class' => 'col-reorder');
|
$sortFieldName = sprintf(
|
||||||
}
|
'%s[GridFieldEditableColumns][%s][%s]',
|
||||||
|
$grid->getName(),
|
||||||
public function getColumnMetadata($grid, $col) {
|
$record->ID,
|
||||||
if ($fieldLabels = singleton($grid->getModelClass())->fieldLabels()) {
|
$this->getSortField()
|
||||||
return array('title' => isset($fieldLabels['Reorder']) ? $fieldLabels['Reorder'] : '');
|
);
|
||||||
}
|
$sortField = new HiddenField($sortFieldName, false, $record->getField($this->getSortField()));
|
||||||
|
$sortField->addExtraClass('ss-orderable-hidden-sort');
|
||||||
return array('title' => '');
|
$sortField->setForm($grid->getForm());
|
||||||
}
|
|
||||||
|
return ViewableData::create()->customise(array(
|
||||||
public function getManipulatedData(GridField $grid, SS_List $list) {
|
'SortField' => $sortField
|
||||||
$state = $grid->getState();
|
))->renderWith('SilverStripe\\GridFieldExtensions\\GridFieldOrderableRowsDragHandle');
|
||||||
$sorted = (bool) ((string) $state->GridFieldSortableHeader->SortColumn);
|
}
|
||||||
|
|
||||||
// If the data has not been sorted by the user, then sort it by the
|
public function getColumnAttributes($grid, $record, $col)
|
||||||
// sort column, otherwise disable reordering.
|
{
|
||||||
$state->GridFieldOrderableRows->enabled = !$sorted;
|
return array('class' => 'col-reorder');
|
||||||
|
}
|
||||||
if(!$sorted) {
|
|
||||||
$sortterm = '';
|
public function getColumnMetadata($grid, $col)
|
||||||
if ($this->extraSortFields) {
|
{
|
||||||
if (is_array($this->extraSortFields)) {
|
if ($fieldLabels = singleton($grid->getModelClass())->fieldLabels()) {
|
||||||
foreach($this->extraSortFields as $col => $dir) {
|
return array('title' => isset($fieldLabels['Reorder']) ? $fieldLabels['Reorder'] : '');
|
||||||
$sortterm .= "$col $dir, ";
|
}
|
||||||
}
|
|
||||||
} else {
|
return array('title' => '');
|
||||||
$sortterm = $this->extraSortFields.', ';
|
}
|
||||||
}
|
|
||||||
}
|
public function getManipulatedData(GridField $grid, SS_List $list)
|
||||||
if ($list instanceof ArrayList) {
|
{
|
||||||
// Fix bug in 3.1.3+ where ArrayList doesn't account for quotes
|
$state = $grid->getState();
|
||||||
$sortterm .= $this->getSortTable($list).'.'.$this->getSortField();
|
$sorted = (bool) ((string) $state->GridFieldSortableHeader->SortColumn);
|
||||||
} else {
|
|
||||||
$sortterm .= '"'.$this->getSortTable($list).'"."'.$this->getSortField().'"';
|
// If the data has not been sorted by the user, then sort it by the
|
||||||
}
|
// sort column, otherwise disable reordering.
|
||||||
return $list->sort($sortterm);
|
$state->GridFieldOrderableRows->enabled = !$sorted;
|
||||||
} else {
|
|
||||||
return $list;
|
if (!$sorted) {
|
||||||
}
|
$sortterm = '';
|
||||||
}
|
if ($this->extraSortFields) {
|
||||||
|
if (is_array($this->extraSortFields)) {
|
||||||
/**
|
foreach ($this->extraSortFields as $col => $dir) {
|
||||||
* Handles requests to reorder a set of IDs in a specific order.
|
$sortterm .= "$col $dir, ";
|
||||||
*
|
}
|
||||||
* @param GridField $grid
|
} else {
|
||||||
* @param SS_HTTPRequest $request
|
$sortterm = $this->extraSortFields.', ';
|
||||||
* @return SS_HTTPResponse
|
}
|
||||||
*/
|
}
|
||||||
public function handleReorder($grid, $request) {
|
if ($list instanceof ArrayList) {
|
||||||
if (!$this->immediateUpdate)
|
// Fix bug in 3.1.3+ where ArrayList doesn't account for quotes
|
||||||
{
|
$sortterm .= $this->getSortTable($list).'.'.$this->getSortField();
|
||||||
$this->httpError(400);
|
} else {
|
||||||
}
|
$sortterm .= '"'.$this->getSortTable($list).'"."'.$this->getSortField().'"';
|
||||||
$list = $grid->getList();
|
}
|
||||||
$modelClass = $grid->getModelClass();
|
return $list->sort($sortterm);
|
||||||
if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) {
|
} else {
|
||||||
$this->httpError(403);
|
return $list;
|
||||||
} else if(!($list instanceof ManyManyList) && !singleton($modelClass)->canEdit()) {
|
}
|
||||||
$this->httpError(403);
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
// Save any un-committed changes to the gridfield
|
* Handles requests to reorder a set of IDs in a specific order.
|
||||||
if(($form = $grid->getForm()) && ($record = $form->getRecord()) ) {
|
*
|
||||||
$form->loadDataFrom($request->requestVars(), true);
|
* @param GridField $grid
|
||||||
$grid->saveInto($record);
|
* @param SS_HTTPRequest $request
|
||||||
}
|
* @return SS_HTTPResponse
|
||||||
|
*/
|
||||||
// Get records from the `GridFieldEditableColumns` column
|
public function handleReorder($grid, $request)
|
||||||
$data = $request->postVar($grid->getName());
|
{
|
||||||
$sortedIDs = $this->getSortedIDs($data);
|
if (!$this->immediateUpdate) {
|
||||||
if (!$this->executeReorder($grid, $sortedIDs))
|
$this->httpError(400);
|
||||||
{
|
}
|
||||||
$this->httpError(400);
|
$list = $grid->getList();
|
||||||
}
|
$modelClass = $grid->getModelClass();
|
||||||
|
if ($list instanceof ManyManyList && !singleton($modelClass)->canView()) {
|
||||||
Controller::curr()->getResponse()->addHeader('X-Status', rawurlencode('Records reordered.'));
|
$this->httpError(403);
|
||||||
return $grid->FieldHolder();
|
} elseif (!($list instanceof ManyManyList) && !singleton($modelClass)->canEdit()) {
|
||||||
}
|
$this->httpError(403);
|
||||||
|
}
|
||||||
/**
|
|
||||||
* Get mapping of sort value to ID from posted data
|
// Save any un-committed changes to the gridfield
|
||||||
*
|
if (($form = $grid->getForm()) && ($record = $form->getRecord())) {
|
||||||
* @param array $data Raw posted data
|
$form->loadDataFrom($request->requestVars(), true);
|
||||||
* @return array
|
$grid->saveInto($record);
|
||||||
*/
|
}
|
||||||
protected function getSortedIDs($data) {
|
|
||||||
if (empty($data['GridFieldEditableColumns'])) {
|
// Get records from the `GridFieldEditableColumns` column
|
||||||
return array();
|
$data = $request->postVar($grid->getName());
|
||||||
}
|
$sortedIDs = $this->getSortedIDs($data);
|
||||||
|
if (!$this->executeReorder($grid, $sortedIDs)) {
|
||||||
$sortedIDs = array();
|
$this->httpError(400);
|
||||||
foreach($data['GridFieldEditableColumns'] as $id => $recordData) {
|
}
|
||||||
$sortValue = $recordData[$this->sortField];
|
|
||||||
$sortedIDs[$sortValue] = $id;
|
Controller::curr()->getResponse()->addHeader('X-Status', rawurlencode('Records reordered.'));
|
||||||
}
|
return $grid->FieldHolder();
|
||||||
ksort($sortedIDs);
|
}
|
||||||
return $sortedIDs;
|
|
||||||
}
|
/**
|
||||||
|
* Get mapping of sort value to ID from posted data
|
||||||
/**
|
*
|
||||||
* Handles requests to move an item to the previous or next page.
|
* @param array $data Raw posted data
|
||||||
*/
|
* @return array
|
||||||
public function handleMoveToPage(GridField $grid, $request) {
|
*/
|
||||||
if(!$paginator = $grid->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldPaginator')) {
|
protected function getSortedIDs($data)
|
||||||
$this->httpError(404, 'Paginator component not found');
|
{
|
||||||
}
|
if (empty($data['GridFieldEditableColumns'])) {
|
||||||
|
return array();
|
||||||
$move = $request->postVar('move');
|
}
|
||||||
$field = $this->getSortField();
|
|
||||||
|
$sortedIDs = array();
|
||||||
$list = $grid->getList();
|
foreach ($data['GridFieldEditableColumns'] as $id => $recordData) {
|
||||||
$manip = $grid->getManipulatedList();
|
$sortValue = $recordData[$this->sortField];
|
||||||
|
$sortedIDs[$sortValue] = $id;
|
||||||
$existing = $manip->map('ID', $field)->toArray();
|
}
|
||||||
$values = $existing;
|
ksort($sortedIDs);
|
||||||
$order = array();
|
return $sortedIDs;
|
||||||
|
}
|
||||||
$id = isset($move['id']) ? (int) $move['id'] : null;
|
|
||||||
$to = isset($move['page']) ? $move['page'] : null;
|
/**
|
||||||
|
* Handles requests to move an item to the previous or next page.
|
||||||
if(!isset($values[$id])) {
|
*/
|
||||||
$this->httpError(400, 'Invalid item ID');
|
public function handleMoveToPage(GridField $grid, $request)
|
||||||
}
|
{
|
||||||
|
if (!$paginator = $grid->getConfig()->getComponentByType('SilverStripe\\Forms\\GridField\\GridFieldPaginator')) {
|
||||||
$this->populateSortValues($list);
|
$this->httpError(404, 'Paginator component not found');
|
||||||
|
}
|
||||||
$page = ((int) $grid->getState()->GridFieldPaginator->currentPage) ?: 1;
|
|
||||||
$per = $paginator->getItemsPerPage();
|
$move = $request->postVar('move');
|
||||||
|
$field = $this->getSortField();
|
||||||
if($to == 'prev') {
|
|
||||||
$swap = $list->limit(1, ($page - 1) * $per - 1)->first();
|
$list = $grid->getList();
|
||||||
$values[$swap->ID] = $swap->$field;
|
$manip = $grid->getManipulatedList();
|
||||||
|
|
||||||
$order[] = $id;
|
$existing = $manip->map('ID', $field)->toArray();
|
||||||
$order[] = $swap->ID;
|
$values = $existing;
|
||||||
|
$order = array();
|
||||||
foreach($existing as $_id => $sort) {
|
|
||||||
if($id != $_id) $order[] = $_id;
|
$id = isset($move['id']) ? (int) $move['id'] : null;
|
||||||
}
|
$to = isset($move['page']) ? $move['page'] : null;
|
||||||
} elseif($to == 'next') {
|
|
||||||
$swap = $list->limit(1, $page * $per)->first();
|
if (!isset($values[$id])) {
|
||||||
$values[$swap->ID] = $swap->$field;
|
$this->httpError(400, 'Invalid item ID');
|
||||||
|
}
|
||||||
foreach($existing as $_id => $sort) {
|
|
||||||
if($id != $_id) $order[] = $_id;
|
$this->populateSortValues($list);
|
||||||
}
|
|
||||||
|
$page = ((int) $grid->getState()->GridFieldPaginator->currentPage) ?: 1;
|
||||||
$order[] = $swap->ID;
|
$per = $paginator->getItemsPerPage();
|
||||||
$order[] = $id;
|
|
||||||
} else {
|
if ($to == 'prev') {
|
||||||
$this->httpError(400, 'Invalid page target');
|
$swap = $list->limit(1, ($page - 1) * $per - 1)->first();
|
||||||
}
|
$values[$swap->ID] = $swap->$field;
|
||||||
|
|
||||||
$this->reorderItems($list, $values, $order);
|
$order[] = $id;
|
||||||
|
$order[] = $swap->ID;
|
||||||
return $grid->FieldHolder();
|
|
||||||
}
|
foreach ($existing as $_id => $sort) {
|
||||||
|
if ($id != $_id) {
|
||||||
/**
|
$order[] = $_id;
|
||||||
* Handle saving when 'immediateUpdate' is disabled, otherwise this isn't
|
}
|
||||||
* necessary for the default sort mode.
|
}
|
||||||
*/
|
} elseif ($to == 'next') {
|
||||||
public function handleSave(GridField $grid, DataObjectInterface $record) {
|
$swap = $list->limit(1, $page * $per)->first();
|
||||||
if (!$this->immediateUpdate)
|
$values[$swap->ID] = $swap->$field;
|
||||||
{
|
|
||||||
$value = $grid->Value();
|
foreach ($existing as $_id => $sort) {
|
||||||
$sortedIDs = $this->getSortedIDs($value);
|
if ($id != $_id) {
|
||||||
if ($sortedIDs) {
|
$order[] = $_id;
|
||||||
$this->executeReorder($grid, $sortedIDs);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
$order[] = $swap->ID;
|
||||||
|
$order[] = $id;
|
||||||
/**
|
} else {
|
||||||
* @param GridField $grid
|
$this->httpError(400, 'Invalid page target');
|
||||||
* @param array $sortedIDs List of IDS, where the key is the sort field value to save
|
}
|
||||||
* @return bool
|
|
||||||
*/
|
$this->reorderItems($list, $values, $order);
|
||||||
protected function executeReorder(GridField $grid, $sortedIDs) {
|
|
||||||
if(!is_array($sortedIDs)) {
|
return $grid->FieldHolder();
|
||||||
return false;
|
}
|
||||||
}
|
|
||||||
$field = $this->getSortField();
|
/**
|
||||||
|
* Handle saving when 'immediateUpdate' is disabled, otherwise this isn't
|
||||||
$sortterm = '';
|
* necessary for the default sort mode.
|
||||||
if ($this->extraSortFields) {
|
*/
|
||||||
if (is_array($this->extraSortFields)) {
|
public function handleSave(GridField $grid, DataObjectInterface $record)
|
||||||
foreach($this->extraSortFields as $col => $dir) {
|
{
|
||||||
$sortterm .= "$col $dir, ";
|
if (!$this->immediateUpdate) {
|
||||||
}
|
$value = $grid->Value();
|
||||||
} else {
|
$sortedIDs = $this->getSortedIDs($value);
|
||||||
$sortterm = $this->extraSortFields.', ';
|
if ($sortedIDs) {
|
||||||
}
|
$this->executeReorder($grid, $sortedIDs);
|
||||||
}
|
}
|
||||||
$list = $grid->getList();
|
}
|
||||||
$sortterm .= '"'.$this->getSortTable($list).'"."'.$field.'"';
|
}
|
||||||
$items = $list->filter('ID', $sortedIDs)->sort($sortterm);
|
|
||||||
|
/**
|
||||||
// Ensure that each provided ID corresponded to an actual object.
|
* @param GridField $grid
|
||||||
if(count($items) != count($sortedIDs)) {
|
* @param array $sortedIDs List of IDS, where the key is the sort field value to save
|
||||||
return false;
|
* @return bool
|
||||||
}
|
*/
|
||||||
|
protected function executeReorder(GridField $grid, $sortedIDs)
|
||||||
// Populate each object we are sorting with a sort value.
|
{
|
||||||
$this->populateSortValues($items);
|
if (!is_array($sortedIDs)) {
|
||||||
|
return false;
|
||||||
// Generate the current sort values.
|
}
|
||||||
if ($items instanceof ManyManyList)
|
$field = $this->getSortField();
|
||||||
{
|
|
||||||
$current = array();
|
$sortterm = '';
|
||||||
foreach ($items->toArray() as $record)
|
if ($this->extraSortFields) {
|
||||||
{
|
if (is_array($this->extraSortFields)) {
|
||||||
// NOTE: _SortColumn0 is the first ->sort() field
|
foreach ($this->extraSortFields as $col => $dir) {
|
||||||
// used by SS when functions are detected in a SELECT
|
$sortterm .= "$col $dir, ";
|
||||||
// or CASE WHEN.
|
}
|
||||||
if (isset($record->_SortColumn0)) {
|
} else {
|
||||||
$current[$record->ID] = $record->_SortColumn0;
|
$sortterm = $this->extraSortFields.', ';
|
||||||
} else {
|
}
|
||||||
$current[$record->ID] = $record->$field;
|
}
|
||||||
}
|
$list = $grid->getList();
|
||||||
}
|
$sortterm .= '"'.$this->getSortTable($list).'"."'.$field.'"';
|
||||||
}
|
$items = $list->filter('ID', $sortedIDs)->sort($sortterm);
|
||||||
else
|
|
||||||
{
|
// Ensure that each provided ID corresponded to an actual object.
|
||||||
$current = $items->map('ID', $field)->toArray();
|
if (count($items) != count($sortedIDs)) {
|
||||||
}
|
return false;
|
||||||
|
}
|
||||||
// Perform the actual re-ordering.
|
|
||||||
$this->reorderItems($list, $current, $sortedIDs);
|
// Populate each object we are sorting with a sort value.
|
||||||
return true;
|
$this->populateSortValues($items);
|
||||||
}
|
|
||||||
|
// Generate the current sort values.
|
||||||
protected function reorderItems($list, array $values, array $sortedIDs) {
|
if ($items instanceof ManyManyList) {
|
||||||
$sortField = $this->getSortField();
|
$current = array();
|
||||||
/** @var SS_List $map */
|
foreach ($items->toArray() as $record) {
|
||||||
$map = $list->map('ID', $sortField);
|
// NOTE: _SortColumn0 is the first ->sort() field
|
||||||
//fix for versions of SS that return inconsistent types for `map` function
|
// used by SS when functions are detected in a SELECT
|
||||||
if ($map instanceof SS_Map) {
|
// or CASE WHEN.
|
||||||
$map = $map->toArray();
|
if (isset($record->_SortColumn0)) {
|
||||||
}
|
$current[$record->ID] = $record->_SortColumn0;
|
||||||
|
} else {
|
||||||
// If not a ManyManyList and using versioning, detect it.
|
$current[$record->ID] = $record->$field;
|
||||||
$isVersioned = false;
|
}
|
||||||
$class = $list->dataClass();
|
}
|
||||||
if ($class == $this->getSortTable($list)) {
|
} else {
|
||||||
$isVersioned = $class::has_extension('SilverStripe\\ORM\\Versioning\\Versioned');
|
$current = $items->map('ID', $field)->toArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Loop through each item, and update the sort values which do not
|
// Perform the actual re-ordering.
|
||||||
// match to order the objects.
|
$this->reorderItems($list, $current, $sortedIDs);
|
||||||
if (!$isVersioned) {
|
return true;
|
||||||
$sortTable = $this->getSortTable($list);
|
}
|
||||||
$additionalSQL = (!$list instanceof ManyManyList) ? ', "LastEdited" = NOW()' : '';
|
|
||||||
foreach($sortedIDs as $sortValue => $id) {
|
protected function reorderItems($list, array $values, array $sortedIDs)
|
||||||
if($map[$id] != $sortValue) {
|
{
|
||||||
DB::query(sprintf(
|
$sortField = $this->getSortField();
|
||||||
'UPDATE "%s" SET "%s" = %d%s WHERE %s',
|
/** @var SS_List $map */
|
||||||
$sortTable,
|
$map = $list->map('ID', $sortField);
|
||||||
$sortField,
|
//fix for versions of SS that return inconsistent types for `map` function
|
||||||
$sortValue,
|
if ($map instanceof SS_Map) {
|
||||||
$additionalSQL,
|
$map = $map->toArray();
|
||||||
$this->getSortTableClauseForIds($list, $id)
|
}
|
||||||
));
|
|
||||||
}
|
// If not a ManyManyList and using versioning, detect it.
|
||||||
}
|
$isVersioned = false;
|
||||||
} else {
|
$class = $list->dataClass();
|
||||||
// For versioned objects, modify them with the ORM so that the
|
if ($class == $this->getSortTable($list)) {
|
||||||
// *_versions table is updated. This ensures re-ordering works
|
$isVersioned = $class::has_extension('SilverStripe\\ORM\\Versioning\\Versioned');
|
||||||
// similar to the SiteTree where you change the position, and then
|
}
|
||||||
// you go into the record and publish it.
|
|
||||||
foreach($sortedIDs as $sortValue => $id) {
|
// Loop through each item, and update the sort values which do not
|
||||||
if($map[$id] != $sortValue) {
|
// match to order the objects.
|
||||||
$record = $class::get()->byID($id);
|
if (!$isVersioned) {
|
||||||
$record->$sortField = $sortValue;
|
$sortTable = $this->getSortTable($list);
|
||||||
$record->write();
|
$additionalSQL = (!$list instanceof ManyManyList) ? ', "LastEdited" = NOW()' : '';
|
||||||
}
|
foreach ($sortedIDs as $sortValue => $id) {
|
||||||
}
|
if ($map[$id] != $sortValue) {
|
||||||
}
|
DB::query(sprintf(
|
||||||
|
'UPDATE "%s" SET "%s" = %d%s WHERE %s',
|
||||||
$this->extend('onAfterReorderItems', $list);
|
$sortTable,
|
||||||
}
|
$sortField,
|
||||||
|
$sortValue,
|
||||||
protected function populateSortValues(DataList $list) {
|
$additionalSQL,
|
||||||
$list = clone $list;
|
$this->getSortTableClauseForIds($list, $id)
|
||||||
$field = $this->getSortField();
|
));
|
||||||
$table = $this->getSortTable($list);
|
}
|
||||||
$clause = sprintf('"%s"."%s" = 0', $table, $this->getSortField());
|
}
|
||||||
$additionalSQL = (!$list instanceof ManyManyList) ? ', "LastEdited" = NOW()' : '';
|
} else {
|
||||||
|
// For versioned objects, modify them with the ORM so that the
|
||||||
foreach($list->where($clause)->column('ID') as $id) {
|
// *_versions table is updated. This ensures re-ordering works
|
||||||
$max = DB::query(sprintf('SELECT MAX("%s") + 1 FROM "%s"', $field, $table));
|
// similar to the SiteTree where you change the position, and then
|
||||||
$max = $max->value();
|
// you go into the record and publish it.
|
||||||
|
foreach ($sortedIDs as $sortValue => $id) {
|
||||||
DB::query(sprintf(
|
if ($map[$id] != $sortValue) {
|
||||||
'UPDATE "%s" SET "%s" = %d%s WHERE %s',
|
$record = $class::get()->byID($id);
|
||||||
$table,
|
$record->$sortField = $sortValue;
|
||||||
$field,
|
$record->write();
|
||||||
$max,
|
}
|
||||||
$additionalSQL,
|
}
|
||||||
$this->getSortTableClauseForIds($list, $id)
|
}
|
||||||
));
|
|
||||||
}
|
$this->extend('onAfterReorderItems', $list);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function getSortTableClauseForIds(DataList $list, $ids) {
|
protected function populateSortValues(DataList $list)
|
||||||
if(is_array($ids)) {
|
{
|
||||||
$value = 'IN (' . implode(', ', array_map('intval', $ids)) . ')';
|
$list = clone $list;
|
||||||
} else {
|
$field = $this->getSortField();
|
||||||
$value = '= ' . (int) $ids;
|
$table = $this->getSortTable($list);
|
||||||
}
|
$clause = sprintf('"%s"."%s" = 0', $table, $this->getSortField());
|
||||||
|
$additionalSQL = (!$list instanceof ManyManyList) ? ', "LastEdited" = NOW()' : '';
|
||||||
if($list instanceof ManyManyList) {
|
|
||||||
$extra = $list->getExtraFields();
|
foreach ($list->where($clause)->column('ID') as $id) {
|
||||||
$key = $list->getLocalKey();
|
$max = DB::query(sprintf('SELECT MAX("%s") + 1 FROM "%s"', $field, $table));
|
||||||
$foreignKey = $list->getForeignKey();
|
$max = $max->value();
|
||||||
$foreignID = (int) $list->getForeignID();
|
|
||||||
|
DB::query(sprintf(
|
||||||
if($extra && array_key_exists($this->getSortField(), $extra)) {
|
'UPDATE "%s" SET "%s" = %d%s WHERE %s',
|
||||||
return sprintf(
|
$table,
|
||||||
'"%s" %s AND "%s" = %d',
|
$field,
|
||||||
$key,
|
$max,
|
||||||
$value,
|
$additionalSQL,
|
||||||
$foreignKey,
|
$this->getSortTableClauseForIds($list, $id)
|
||||||
$foreignID
|
));
|
||||||
);
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
protected function getSortTableClauseForIds(DataList $list, $ids)
|
||||||
return "\"ID\" $value";
|
{
|
||||||
}
|
if (is_array($ids)) {
|
||||||
|
$value = 'IN (' . implode(', ', array_map('intval', $ids)) . ')';
|
||||||
|
} else {
|
||||||
|
$value = '= ' . (int) $ids;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($list instanceof ManyManyList) {
|
||||||
|
$extra = $list->getExtraFields();
|
||||||
|
$key = $list->getLocalKey();
|
||||||
|
$foreignKey = $list->getForeignKey();
|
||||||
|
$foreignID = (int) $list->getForeignID();
|
||||||
|
|
||||||
|
if ($extra && array_key_exists($this->getSortField(), $extra)) {
|
||||||
|
return sprintf(
|
||||||
|
'"%s" %s AND "%s" = %d',
|
||||||
|
$key,
|
||||||
|
$value,
|
||||||
|
$foreignKey,
|
||||||
|
$foreignID
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "\"ID\" $value";
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,145 +22,155 @@ use SilverStripe\ORM\ArrayList;
|
||||||
* as tabs, breadcrumbs and a back link. Much of this code is extracted from the
|
* as tabs, breadcrumbs and a back link. Much of this code is extracted from the
|
||||||
* detail form.
|
* detail form.
|
||||||
*/
|
*/
|
||||||
abstract class GridFieldRequestHandler extends RequestHandler {
|
abstract class GridFieldRequestHandler extends RequestHandler
|
||||||
|
{
|
||||||
|
|
||||||
private static $allowed_actions = array(
|
private static $allowed_actions = array(
|
||||||
'Form'
|
'Form'
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var GridField
|
* @var GridField
|
||||||
*/
|
*/
|
||||||
protected $grid;
|
protected $grid;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var GridFieldComponent
|
* @var GridFieldComponent
|
||||||
*/
|
*/
|
||||||
protected $component;
|
protected $component;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $name;
|
protected $name;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @var string
|
* @var string
|
||||||
*/
|
*/
|
||||||
protected $template = __CLASS__;
|
protected $template = __CLASS__;
|
||||||
|
|
||||||
public function __construct(GridField $grid, GridFieldComponent $component, $name) {
|
public function __construct(GridField $grid, GridFieldComponent $component, $name)
|
||||||
$this->grid = $grid;
|
{
|
||||||
$this->component = $component;
|
$this->grid = $grid;
|
||||||
$this->name = $name;
|
$this->component = $component;
|
||||||
|
$this->name = $name;
|
||||||
|
|
||||||
parent::__construct();
|
parent::__construct();
|
||||||
}
|
}
|
||||||
|
|
||||||
public function index($request) {
|
public function index($request)
|
||||||
$result = $this->renderWith($this->template);
|
{
|
||||||
|
$result = $this->renderWith($this->template);
|
||||||
|
|
||||||
if($request->isAjax()) {
|
if ($request->isAjax()) {
|
||||||
return $result;
|
return $result;
|
||||||
} else {
|
} else {
|
||||||
return $this->getTopLevelController()->customise(array(
|
return $this->getTopLevelController()->customise(array(
|
||||||
'Content' => $result
|
'Content' => $result
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public function Link($action = null) {
|
public function Link($action = null)
|
||||||
return Controller::join_links($this->grid->Link(), $this->name, $action);
|
{
|
||||||
}
|
return Controller::join_links($this->grid->Link(), $this->name, $action);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method should be overloaded to build out the detail form.
|
* This method should be overloaded to build out the detail form.
|
||||||
*
|
*
|
||||||
* @return Form
|
* @return Form
|
||||||
*/
|
*/
|
||||||
public function Form() {
|
public function Form()
|
||||||
$form = new Form(
|
{
|
||||||
$this,
|
$form = new Form(
|
||||||
'SilverStripe\\Forms\\Form',
|
$this,
|
||||||
new FieldList($root = new TabSet('Root', new Tab('Main'))),
|
'SilverStripe\\Forms\\Form',
|
||||||
new FieldList()
|
new FieldList($root = new TabSet('Root', new Tab('Main'))),
|
||||||
);
|
new FieldList()
|
||||||
|
);
|
||||||
|
|
||||||
if($this->getTopLevelController() instanceof LeftAndMain) {
|
if ($this->getTopLevelController() instanceof LeftAndMain) {
|
||||||
$form->setTemplate('LeftAndMain_EditForm');
|
$form->setTemplate('LeftAndMain_EditForm');
|
||||||
$form->addExtraClass('cms-content cms-edit-form cms-tabset center');
|
$form->addExtraClass('cms-content cms-edit-form cms-tabset center');
|
||||||
$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
|
$form->setAttribute('data-pjax-fragment', 'CurrentForm Content');
|
||||||
|
|
||||||
$root->setTemplate('CMSTabSet');
|
$root->setTemplate('CMSTabSet');
|
||||||
$form->Backlink = $this->getBackLink();
|
$form->Backlink = $this->getBackLink();
|
||||||
}
|
}
|
||||||
|
|
||||||
return $form;
|
return $form;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Controller
|
* @return Controller
|
||||||
*/
|
*/
|
||||||
public function getController() {
|
public function getController()
|
||||||
return $this->grid->getForm()->getController();
|
{
|
||||||
}
|
return $this->grid->getForm()->getController();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $template
|
* @param string $template
|
||||||
*/
|
*/
|
||||||
public function setTemplate($template) {
|
public function setTemplate($template)
|
||||||
$this->template = $template;
|
{
|
||||||
}
|
$this->template = $template;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function getTemplate() {
|
public function getTemplate()
|
||||||
return $this->template;
|
{
|
||||||
}
|
return $this->template;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return ArrayList
|
* @return ArrayList
|
||||||
*/
|
*/
|
||||||
public function getBreadcrumbs() {
|
public function getBreadcrumbs()
|
||||||
$controller = $this->getController();
|
{
|
||||||
|
$controller = $this->getController();
|
||||||
|
|
||||||
if($controller->hasMethod('Breadcrumbs')) {
|
if ($controller->hasMethod('Breadcrumbs')) {
|
||||||
return $controller->Breadcrumbs();
|
return $controller->Breadcrumbs();
|
||||||
} else {
|
} else {
|
||||||
return new ArrayList();
|
return new ArrayList();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
protected function getBackLink() {
|
protected function getBackLink()
|
||||||
$controller = $this->getTopLevelController();
|
{
|
||||||
|
$controller = $this->getTopLevelController();
|
||||||
|
|
||||||
if($controller->hasMethod('Backlink')) {
|
if ($controller->hasMethod('Backlink')) {
|
||||||
return $controller->Backlink();
|
return $controller->Backlink();
|
||||||
} else {
|
} else {
|
||||||
return $controller->Link();
|
return $controller->Link();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Controller
|
* @return Controller
|
||||||
*/
|
*/
|
||||||
protected function getTopLevelController() {
|
protected function getTopLevelController()
|
||||||
$controller = $this->getController();
|
{
|
||||||
|
$controller = $this->getController();
|
||||||
|
|
||||||
while($controller) {
|
while ($controller) {
|
||||||
if($controller instanceof GridFieldRequestHandler) {
|
if ($controller instanceof GridFieldRequestHandler) {
|
||||||
$controller = $controller->getController();
|
$controller = $controller->getController();
|
||||||
} elseif($controller instanceof GridFieldDetailForm_ItemRequest) {
|
} elseif ($controller instanceof GridFieldDetailForm_ItemRequest) {
|
||||||
$controller = $controller->getController();
|
$controller = $controller->getController();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return $controller;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return $controller;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,24 @@ use SilverStripe\View\ArrayData;
|
||||||
/**
|
/**
|
||||||
* A simple header which displays column titles.
|
* A simple header which displays column titles.
|
||||||
*/
|
*/
|
||||||
class GridFieldTitleHeader implements GridField_HTMLProvider {
|
class GridFieldTitleHeader implements GridField_HTMLProvider
|
||||||
|
{
|
||||||
|
|
||||||
public function getHTMLFragments($grid) {
|
public function getHTMLFragments($grid)
|
||||||
$cols = new ArrayList();
|
{
|
||||||
|
$cols = new ArrayList();
|
||||||
|
|
||||||
foreach ($grid->getColumns() as $name) {
|
foreach ($grid->getColumns() as $name) {
|
||||||
$meta = $grid->getColumnMetadata($name);
|
$meta = $grid->getColumnMetadata($name);
|
||||||
|
|
||||||
$cols->push(new ArrayData(array(
|
$cols->push(new ArrayData(array(
|
||||||
'Name' => $name,
|
'Name' => $name,
|
||||||
'Title' => $meta['title']
|
'Title' => $meta['title']
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return array(
|
|
||||||
'header' => $cols->renderWith(__CLASS__)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return array(
|
||||||
|
'header' => $cols->renderWith(__CLASS__)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,57 +8,65 @@ use SilverStripe\GridFieldExtensions\GridFieldAddNewMultiClass;
|
||||||
/**
|
/**
|
||||||
* Tests for {@link GridFieldAddNewMultiClass}.
|
* Tests for {@link GridFieldAddNewMultiClass}.
|
||||||
*/
|
*/
|
||||||
class GridFieldAddNewMultiClassTest extends SapphireTest {
|
class GridFieldAddNewMultiClassTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
public function testGetClasses() {
|
public function testGetClasses()
|
||||||
$grid = new GridField('TestGridField');
|
{
|
||||||
$grid->setModelClass('GridFieldAddNewMultiClassTest_A');
|
$grid = new GridField('TestGridField');
|
||||||
|
$grid->setModelClass('GridFieldAddNewMultiClassTest_A');
|
||||||
|
|
||||||
$component = new GridFieldAddNewMultiClass();
|
$component = new GridFieldAddNewMultiClass();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
array(
|
array(
|
||||||
'GridFieldAddNewMultiClassTest_A' => 'A',
|
'GridFieldAddNewMultiClassTest_A' => 'A',
|
||||||
'GridFieldAddNewMultiClassTest_B' => 'B',
|
'GridFieldAddNewMultiClassTest_B' => 'B',
|
||||||
'GridFieldAddNewMultiClassTest_C' => 'C'
|
'GridFieldAddNewMultiClassTest_C' => 'C'
|
||||||
),
|
),
|
||||||
$component->getClasses($grid),
|
$component->getClasses($grid),
|
||||||
'Subclasses are populated by default and sorted'
|
'Subclasses are populated by default and sorted'
|
||||||
);
|
);
|
||||||
|
|
||||||
$component->setClasses(array(
|
$component->setClasses(array(
|
||||||
'GridFieldAddNewMultiClassTest_B' => 'Custom Title',
|
'GridFieldAddNewMultiClassTest_B' => 'Custom Title',
|
||||||
'GridFieldAddNewMultiClassTest_A'
|
'GridFieldAddNewMultiClassTest_A'
|
||||||
));
|
));
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
array(
|
|
||||||
'GridFieldAddNewMultiClassTest_B' => 'Custom Title',
|
|
||||||
'GridFieldAddNewMultiClassTest_A' => 'A'
|
|
||||||
),
|
|
||||||
$component->getClasses($grid),
|
|
||||||
'Sorting and custom titles can be specified'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
array(
|
||||||
|
'GridFieldAddNewMultiClassTest_B' => 'Custom Title',
|
||||||
|
'GridFieldAddNewMultiClassTest_A' => 'A'
|
||||||
|
),
|
||||||
|
$component->getClasses($grid),
|
||||||
|
'Sorting and custom titles can be specified'
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**#@+
|
/**#@+
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GridFieldAddNewMultiClassTest_A implements TestOnly {
|
class GridFieldAddNewMultiClassTest_A implements TestOnly
|
||||||
public function i18n_singular_name() {
|
{
|
||||||
$class = get_class($this);
|
public function i18n_singular_name()
|
||||||
return substr($class, strpos($class, '_') + 1);
|
{
|
||||||
}
|
$class = get_class($this);
|
||||||
|
return substr($class, strpos($class, '_') + 1);
|
||||||
|
}
|
||||||
|
|
||||||
public function canCreate() {
|
public function canCreate()
|
||||||
return true;
|
{
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldAddNewMultiClassTest_B extends GridFieldAddNewMultiClassTest_A implements TestOnly {}
|
class GridFieldAddNewMultiClassTest_B extends GridFieldAddNewMultiClassTest_A implements TestOnly
|
||||||
class GridFieldAddNewMultiClassTest_C extends GridFieldAddNewMultiClassTest_A implements TestOnly {}
|
{
|
||||||
|
}
|
||||||
|
class GridFieldAddNewMultiClassTest_C extends GridFieldAddNewMultiClassTest_A implements TestOnly
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/**#@-*/
|
/**#@-*/
|
||||||
|
|
|
@ -10,17 +10,18 @@ use SilverStripe\ORM\DataObject;
|
||||||
/**
|
/**
|
||||||
* Tests for the {@link GridFieldOrderableRows} component.
|
* Tests for the {@link GridFieldOrderableRows} component.
|
||||||
*/
|
*/
|
||||||
class GridFieldOrderableRowsTest extends SapphireTest {
|
class GridFieldOrderableRowsTest extends SapphireTest
|
||||||
|
{
|
||||||
|
|
||||||
protected $usesDatabase = true;
|
protected $usesDatabase = true;
|
||||||
|
|
||||||
// protected static $fixture_file = 'GridFieldOrderableRowsTest.yml';
|
// protected static $fixture_file = 'GridFieldOrderableRowsTest.yml';
|
||||||
|
|
||||||
protected $extraDataObjects = array(
|
protected $extraDataObjects = array(
|
||||||
'GridFieldOrderableRowsTest_Parent',
|
'GridFieldOrderableRowsTest_Parent',
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'GridFieldOrderableRowsTest_Ordered',
|
||||||
'GridFieldOrderableRowsTest_Subclass',
|
'GridFieldOrderableRowsTest_Subclass',
|
||||||
);
|
);
|
||||||
|
|
||||||
public function setUp()
|
public function setUp()
|
||||||
{
|
{
|
||||||
|
@ -28,111 +29,112 @@ class GridFieldOrderableRowsTest extends SapphireTest {
|
||||||
$this->markTestSkipped('Upgrade to 4.0: Needs to be re-implemented.');
|
$this->markTestSkipped('Upgrade to 4.0: Needs to be re-implemented.');
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testReorderItems() {
|
public function testReorderItems()
|
||||||
|
{
|
||||||
$orderable = new GridFieldOrderableRows('ManyManySort');
|
$orderable = new GridFieldOrderableRows('ManyManySort');
|
||||||
$reflection = new ReflectionMethod($orderable, 'executeReorder');
|
$reflection = new ReflectionMethod($orderable, 'executeReorder');
|
||||||
$reflection->setAccessible(true);
|
$reflection->setAccessible(true);
|
||||||
|
|
||||||
$parent = $this->objFromFixture('GridFieldOrderableRowsTest_Parent', 'parent');
|
$parent = $this->objFromFixture('GridFieldOrderableRowsTest_Parent', 'parent');
|
||||||
|
|
||||||
$config = new GridFieldConfig_RelationEditor();
|
$config = new GridFieldConfig_RelationEditor();
|
||||||
$config->addComponent($orderable);
|
$config->addComponent($orderable);
|
||||||
|
|
||||||
$grid = new GridField(
|
$grid = new GridField(
|
||||||
'MyManyMany',
|
'MyManyMany',
|
||||||
'My Many Many',
|
'My Many Many',
|
||||||
$parent->MyManyMany()->sort('ManyManySort'),
|
$parent->MyManyMany()->sort('ManyManySort'),
|
||||||
$config
|
$config
|
||||||
);
|
);
|
||||||
|
|
||||||
$originalOrder = $parent->MyManyMany()->sort('ManyManySort')->column('ID');
|
$originalOrder = $parent->MyManyMany()->sort('ManyManySort')->column('ID');
|
||||||
$desiredOrder = array();
|
$desiredOrder = array();
|
||||||
|
|
||||||
// Make order non-contiguous, and 1-based
|
// Make order non-contiguous, and 1-based
|
||||||
foreach(array_reverse($originalOrder) as $index => $id) {
|
foreach (array_reverse($originalOrder) as $index => $id) {
|
||||||
$desiredOrder[$index * 2 + 1] = $id;
|
$desiredOrder[$index * 2 + 1] = $id;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->assertNotEquals($originalOrder, $desiredOrder);
|
$this->assertNotEquals($originalOrder, $desiredOrder);
|
||||||
|
|
||||||
$reflection->invoke($orderable, $grid, $desiredOrder);
|
$reflection->invoke($orderable, $grid, $desiredOrder);
|
||||||
|
|
||||||
$newOrder = $parent->MyManyMany()->sort('ManyManySort')->map('ManyManySort', 'ID')->toArray();
|
$newOrder = $parent->MyManyMany()->sort('ManyManySort')->map('ManyManySort', 'ID')->toArray();
|
||||||
|
|
||||||
$this->assertEquals($desiredOrder, $newOrder);
|
$this->assertEquals($desiredOrder, $newOrder);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
/**
|
||||||
|
* @covers GridFieldOrderableRows::getSortTable
|
||||||
/**
|
*/
|
||||||
* @covers GridFieldOrderableRows::getSortTable
|
public function testGetSortTable()
|
||||||
*/
|
{
|
||||||
public function testGetSortTable() {
|
|
||||||
$orderable = new GridFieldOrderableRows();
|
$orderable = new GridFieldOrderableRows();
|
||||||
|
|
||||||
$parent = new GridFieldOrderableRowsTest_Parent();
|
$parent = new GridFieldOrderableRowsTest_Parent();
|
||||||
$parent->write();
|
$parent->write();
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'GridFieldOrderableRowsTest_Ordered',
|
||||||
$orderable->getSortTable($parent->MyHasMany())
|
$orderable->getSortTable($parent->MyHasMany())
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'GridFieldOrderableRowsTest_Ordered',
|
||||||
$orderable->getSortTable($parent->MyHasManySubclass())
|
$orderable->getSortTable($parent->MyHasManySubclass())
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
$this->assertEquals(
|
||||||
'GridFieldOrderableRowsTest_Ordered',
|
'GridFieldOrderableRowsTest_Ordered',
|
||||||
$orderable->getSortTable($parent->MyManyMany())
|
$orderable->getSortTable($parent->MyManyMany())
|
||||||
);
|
);
|
||||||
|
|
||||||
$this->assertEquals(
|
|
||||||
'GridFieldOrderableRowsTest_Parent_MyManyMany',
|
|
||||||
$orderable->setSortField('ManyManySort')->getSortTable($parent->MyManyMany())
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
$this->assertEquals(
|
||||||
|
'GridFieldOrderableRowsTest_Parent_MyManyMany',
|
||||||
|
$orderable->setSortField('ManyManySort')->getSortTable($parent->MyManyMany())
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**#@+
|
/**#@+
|
||||||
* @ignore
|
* @ignore
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class GridFieldOrderableRowsTest_Parent extends DataObject implements TestOnly {
|
class GridFieldOrderableRowsTest_Parent extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
|
||||||
private static $has_many = array(
|
private static $has_many = array(
|
||||||
'MyHasMany' => 'GridFieldOrderableRowsTest_Ordered',
|
'MyHasMany' => 'GridFieldOrderableRowsTest_Ordered',
|
||||||
'MyHasManySubclass' => 'GridFieldOrderableRowsTest_Subclass'
|
'MyHasManySubclass' => 'GridFieldOrderableRowsTest_Subclass'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $many_many = array(
|
private static $many_many = array(
|
||||||
'MyManyMany' => 'GridFieldOrderableRowsTest_Ordered'
|
'MyManyMany' => 'GridFieldOrderableRowsTest_Ordered'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $many_many_extraFields = array(
|
|
||||||
'MyManyMany' => array('ManyManySort' => 'Int')
|
|
||||||
);
|
|
||||||
|
|
||||||
|
private static $many_many_extraFields = array(
|
||||||
|
'MyManyMany' => array('ManyManySort' => 'Int')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldOrderableRowsTest_Ordered extends DataObject implements TestOnly {
|
class GridFieldOrderableRowsTest_Ordered extends DataObject implements TestOnly
|
||||||
|
{
|
||||||
|
|
||||||
private static $db = array(
|
private static $db = array(
|
||||||
'Sort' => 'Int'
|
'Sort' => 'Int'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $has_one = array(
|
private static $has_one = array(
|
||||||
'Parent' => 'GridFieldOrderableRowsTest_Parent'
|
'Parent' => 'GridFieldOrderableRowsTest_Parent'
|
||||||
);
|
);
|
||||||
|
|
||||||
private static $belongs_many_many =array(
|
|
||||||
'MyManyMany' => 'GridFieldOrderableRowsTest_Parent',
|
|
||||||
);
|
|
||||||
|
|
||||||
|
private static $belongs_many_many =array(
|
||||||
|
'MyManyMany' => 'GridFieldOrderableRowsTest_Parent',
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
class GridFieldOrderableRowsTest_Subclass extends GridFieldOrderableRowsTest_Ordered implements TestOnly {
|
class GridFieldOrderableRowsTest_Subclass extends GridFieldOrderableRowsTest_Ordered implements TestOnly
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
/**#@-*/
|
/**#@-*/
|
||||||
|
|
|
@ -1,16 +1,10 @@
|
||||||
GridFieldOrderableRowsTest_Ordered:
|
GridFieldOrderableRowsTest_Ordered:
|
||||||
item1:
|
item1:
|
||||||
Sort: 0
|
|
||||||
item2:
|
item2:
|
||||||
Sort: 0
|
|
||||||
item3:
|
item3:
|
||||||
Sort: 0
|
|
||||||
item4:
|
item4:
|
||||||
Sort: 0
|
|
||||||
item5:
|
item5:
|
||||||
Sort: 0
|
|
||||||
item6:
|
item6:
|
||||||
Sort: 0
|
|
||||||
GridFieldOrderableRowsTest_Parent:
|
GridFieldOrderableRowsTest_Parent:
|
||||||
parent:
|
parent:
|
||||||
MyManyMany:
|
MyManyMany:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user