This commit is contained in:
Peter Thaleikis 2015-12-09 20:35:10 +00:00
commit 7920964741
1 changed files with 114 additions and 112 deletions

View File

@ -17,7 +17,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$this->sortColumn = $sortColumn;
$this->disable_selection = $disableSelection;
}
/**
* Returns a map where the keys are fragment names and the values are pieces of HTML to add to these fragments.
* @param GridField $gridField Grid Field Reference
@ -29,18 +29,18 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
if(class_exists('UnsavedRelationList') && $dataList instanceof UnsavedRelationList) {
return array();
}
$state = $gridField->State->GridFieldSortableRows;
if(!is_bool($state->sortableToggle)) {
$state->sortableToggle = false;
}
//Ensure user can edit
if(!singleton($gridField->getModelClass())->canEdit()){
return array();
}
//Sort order toggle
$sortOrderToggle = GridField_FormAction::create(
$gridField,
@ -49,8 +49,8 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
'sortableRowsToggle',
null
)->addExtraClass('sortablerows-toggle');
$sortOrderSave = GridField_FormAction::create(
$gridField,
'sortablerows-savesort',
@ -58,8 +58,8 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
'saveGridRowSort',
null
)->addExtraClass('sortablerows-savesort');
//Sort to Page Action
$sortToPage = GridField_FormAction::create(
$gridField,
@ -68,37 +68,37 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
'sortToPage',
null
)->addExtraClass('sortablerows-sorttopage');
$data = array('SortableToggle' => $sortOrderToggle,
'SortOrderSave' => $sortOrderSave,
'SortToPage' => $sortToPage,
'Checked' => ($state->sortableToggle == true ? ' checked = "checked"':''),
'List' => $dataList);
$forTemplate = new ArrayData($data);
//Inject Requirements
$custom = Config::inst()->get('GridFieldSortableRows', 'Base');
$base = $custom ?: SORTABLE_GRIDFIELD_BASE;
Requirements::css($base . '/css/GridFieldSortableRows.css');
Requirements::javascript($base . '/javascript/GridFieldSortableRows.js');
$args = array('Colspan' => count($gridField->getColumns()), 'ID' => $gridField->ID(), 'DisableSelection' => $this->disable_selection);
$fragments=array('header' => $forTemplate->renderWith('GridFieldSortableRows', $args));
if($gridField->getConfig()->getComponentByType('GridFieldPaginator')) {
$fragments['after']=$forTemplate->renderWith('GridFieldSortableRows_paginator');
}
return $fragments;
}
/**
* Manipulate the datalist as needed by this grid modifier.
* @param GridField $gridField Grid Field Reference
@ -108,22 +108,22 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
public function getManipulatedData(GridField $gridField, SS_List $dataList) {
//Detect and correct items with a sort column value of 0 (push to bottom)
$this->fixSortColumn($gridField, $dataList);
$headerState = $gridField->State->GridFieldSortableHeader;
$state = $gridField->State->GridFieldSortableRows;
if ((!is_bool($state->sortableToggle) || $state->sortableToggle==false) && $headerState && !empty($headerState->SortColumn)) {
return $dataList->sort($this->sortColumn);
}
if ($state->sortableToggle == true) {
$gridField->getConfig()->removeComponentsByType('GridFieldFilterHeader');
$gridField->getConfig()->removeComponentsByType('GridFieldSortableHeader');
}
return $dataList->sort($this->sortColumn);
}
/**
* Sets if new records should be appended to the top or the bottom of the list
* @param bool $value Boolean true to append to the top false to append to the bottom
@ -140,11 +140,13 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
*/
public function setDisableSelection($value){
$this->disable_selection = $value;
return $this;
}
/**
* Detects and corrects items with a sort column value of 0, by appending them to the bottom of the list
*
* @param GridField $gridField Grid Field Reference
* @param SS_List $dataList Data List of items to be checked
*/
@ -152,40 +154,40 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
if(class_exists('UnsavedRelationList') && $dataList instanceof UnsavedRelationList) {
return;
}
$list=clone $dataList;
$list=$list->alterDataQuery(function($query, SS_List $tmplist) {
$list = clone $dataList;
$list = $list->alterDataQuery(function($query, SS_List $tmplist) {
$query->limit(array());
return $query;
});
$many_many = ($list instanceof ManyManyList);
if (!$many_many) {
$sng=singleton($gridField->getModelClass());
$fieldType=$sng->db($this->sortColumn);
if(!$fieldType || !($fieldType=='Int' || is_subclass_of('Int', $fieldType))) {
$sng = singleton($gridField->getModelClass());
$fieldType = $sng->db($this->sortColumn);
if(!$fieldType || !(strtolower($fieldType) == 'int' || is_subclass_of('Int', $fieldType))) {
if(is_array($fieldType)) {
user_error('Sort column '.$this->sortColumn.' could not be found in '.$gridField->getModelClass().'\'s ancestry', E_USER_ERROR);
}else {
user_error('Sort column '.$this->sortColumn.' must be an Int, column is of type '.$fieldType, E_USER_ERROR);
}
exit;
}
}
$max = $list->Max($this->sortColumn);
$list=$list->filter($this->sortColumn, 0)->sort("Created,ID");
if($list->Count()>0) {
$owner = $gridField->Form->getRecord();
$sortColumn = $this->sortColumn;
$i = 1;
if ($many_many) {
list($parentClass, $componentClass, $parentField, $componentField, $table) = $owner->many_many($gridField->getName());
$extraFields=$owner->many_many_extraFields($gridField->getName());
if(!$extraFields || !array_key_exists($this->sortColumn, $extraFields) || !($extraFields[$this->sortColumn]=='Int' || is_subclass_of('Int', $extraFields[$this->sortColumn]))) {
user_error('Sort column '.$this->sortColumn.' must be an Int, column is of type '.$extraFields[$this->sortColumn], E_USER_ERROR);
exit;
@ -194,7 +196,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
//Find table containing the sort column
$table=false;
$class=$gridField->getModelClass();
$db = Config::inst()->get($class, "db", CONFIG::UNINHERITED);
if(!empty($db) && array_key_exists($sortColumn, $db)) {
$table=$class;
@ -208,30 +210,30 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
}
}
}
if($table===false) {
user_error('Sort column '.$this->sortColumn.' could not be found in '.$gridField->getModelClass().'\'s ancestry', E_USER_ERROR);
exit;
}
$baseDataClass=ClassInfo::baseDataClass($gridField->getModelClass());
}
//Start transaction if supported
if(DB::getConn()->supportsTransactions()) {
DB::getConn()->transactionStart();
}
$idCondition=null;
if($this->append_to_top && !($list instanceof RelationList)) {
$idCondition='"ID" IN(\''.implode("','", $dataList->getIDList()).'\')';
}
if($this->append_to_top) {
$topIncremented=array();
}
foreach($list as $obj) {
if($many_many) {
if($this->append_to_top) {
@ -239,7 +241,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = "' . $sortColumn .'"+1'
. ' WHERE "' . $parentField . '" = ' . $owner->ID . (!empty($topIncremented) ? ' AND "' . $componentField . '" NOT IN(\''.implode('\',\'', $topIncremented).'\')':''));
$topIncremented[]=$obj->ID;
}else {
//Append the last record to the bottom
@ -252,12 +254,12 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = "' . $sortColumn .'"+1'
. ' WHERE '.($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':''));
//LastEdited
DB::query('UPDATE "' . $baseDataClass
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE '.($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':''));
. ' WHERE '.($list instanceof RelationList ? '"' . $list->foreignKey . '" = '. $owner->ID:$idCondition) . (!empty($topIncremented) ? ' AND "ID" NOT IN(\''.implode('\',\'', $topIncremented).'\')':''));
$topIncremented[]=$obj->ID;
}else {
//Append the last record to the bottom
@ -269,18 +271,18 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE "ID" = '. $obj->ID);
}
$i++;
}
//End transaction if supported
if(DB::getConn()->supportsTransactions()) {
DB::getConn()->transactionEnd();
}
}
}
/**
* Return a list of the actions handled by this action provider.
* @param GridField $gridField Grid Field Reference
@ -289,7 +291,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
public function getActions($gridField) {
return array('saveGridRowSort', 'sortableRowsToggle', 'sortToPage');
}
/**
* Handle an action on the given grid field.
* @param GridField $gridField Grid Field Reference
@ -305,15 +307,15 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$gridField->getConfig()->removeComponentsByType('GridFieldFilterHeader');
$gridField->getConfig()->removeComponentsByType('GridFieldSortableHeader');
}
if ($actionName == 'savegridrowsort') {
return $this->saveGridRowSort($gridField, $data);
} else if ($actionName == 'sorttopage') {
return $this->sortToPage($gridField, $data);
}
}
/**
* Handles saving of the row sort order
* @param GridField $gridField Grid Field Reference
@ -326,31 +328,31 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
user_error('Cannot sort an UnsavedRelationList', E_USER_ERROR);
return;
}
if(!singleton($gridField->getModelClass())->canEdit()){
throw new ValidationException(_t('GridFieldSortableRows.EditPermissionsFailure', "No edit permissions"),0);
}
if (empty($data['ItemIDs'])) {
user_error('No items to sort', E_USER_ERROR);
}
$className = $gridField->getModelClass();
$owner = $gridField->Form->getRecord();
$items = clone $gridField->getList();
$many_many = ($items instanceof ManyManyList);
$sortColumn = $this->sortColumn;
$pageOffset = 0;
if ($paginator = $gridField->getConfig()->getComponentsByType('GridFieldPaginator')->First()) {
$pageState = $gridField->State->GridFieldPaginator;
if($pageState->currentPage && is_int($pageState->currentPage) && $pageState->currentPage>1) {
$pageOffset = $paginator->getItemsPerPage() * ($pageState->currentPage - 1);
}
}
if ($many_many) {
list($parentClass, $componentClass, $parentField, $componentField, $table) = $owner->many_many($gridField->getName());
}else {
@ -370,30 +372,30 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
}
}
}
if($table===false) {
user_error('Sort column '.$this->sortColumn.' could not be found in '.$gridField->getModelClass().'\'s ancestry', E_USER_ERROR);
exit;
}
$baseDataClass=ClassInfo::baseDataClass($gridField->getModelClass());
}
//Event to notify the Controller or owner DataObject before list sort
if($owner && $owner instanceof DataObject && method_exists($owner, 'onBeforeGridFieldRowSort')) {
$owner->onBeforeGridFieldRowSort(clone $items);
}else if(Controller::has_curr() && Controller::curr() instanceof ModelAdmin && method_exists(Controller::curr(), 'onBeforeGridFieldRowSort')) {
Controller::curr()->onBeforeGridFieldRowSort(clone $items);
}
//Start transaction if supported
if(DB::getConn()->supportsTransactions()) {
DB::getConn()->transactionStart();
}
//Perform sorting
$ids = explode(',', $data['ItemIDs']);
for($sort = 0;$sort<count($ids);$sort++) {
@ -406,20 +408,20 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn . '" = ' . (($sort + 1) + $pageOffset)
. ' WHERE "ID" = '. $id);
DB::query('UPDATE "' . $baseDataClass
. '" SET "LastEdited" = \'' . date('Y-m-d H:i:s') . '\''
. ' WHERE "ID" = '. $id);
}
}
//End transaction if supported
if(DB::getConn()->supportsTransactions()) {
DB::getConn()->transactionEnd();
}
//Event to notify the Controller or owner DataObject after list sort
if($owner && $owner instanceof DataObject && method_exists($owner, 'onAfterGridFieldRowSort')) {
$owner->onAfterGridFieldRowSort(clone $items);
@ -427,7 +429,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
Controller::curr()->onAfterGridFieldRowSort(clone $items);
}
}
/**
* Handles sorting across pages
* @param GridField $gridField Grid Field Reference
@ -437,41 +439,41 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
if (!$paginator = $gridField->getConfig()->getComponentsByType('GridFieldPaginator')->First()) {
user_error('Paginator not detected', E_USER_ERROR);
}
if (empty($data['ItemID'])) {
user_error('No item to sort', E_USER_ERROR);
}
if (empty($data['Target'])) {
user_error('No target page', E_USER_ERROR);
}
$className = $gridField->getModelClass();
$owner = $gridField->Form->getRecord();
$items = clone $gridField->getList();
$many_many = ($items instanceof ManyManyList);
$sortColumn = $this->sortColumn;
$targetItem = $items->byID(intval($data['ItemID']));
if (!$targetItem) {
user_error('Target item not found', E_USER_ERROR);
}
$currentPage = 1;
$pageState = $gridField->State->GridFieldPaginator;
if($pageState->currentPage && $pageState->currentPage>1) {
$currentPage = $pageState->currentPage;
}
if ($many_many) {
list($parentClass, $componentClass, $parentField, $componentField, $table) = $owner->many_many($gridField->getName());
}
if ($data['Target'] == 'previouspage') {
$items = $items->limit($paginator->getItemsPerPage() + 1, ($paginator->getItemsPerPage() * ($currentPage - 1)) - 1);
} else if ($data['Target'] == 'nextpage') {
@ -479,23 +481,23 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
} else {
user_error('Not implemented: '.$data['Target'], E_USER_ERROR);
}
$sortPositions = $items->column($sortColumn);
//Event to notify the Controller or owner DataObject before list sort
if($owner && $owner instanceof DataObject && method_exists($owner, 'onBeforeGridFieldPageSort')) {
$owner->onBeforeGridFieldPageSort(clone $items);
}else if(Controller::has_curr() && Controller::curr() instanceof ModelAdmin && method_exists(Controller::curr(), 'onBeforeGridFieldPageSort')) {
Controller::curr()->onBeforeGridFieldPageSort(clone $items);
}
//Start transaction if supported
if(DB::getConn()->supportsTransactions()) {
DB::getConn()->transactionStart();
}
if($data['Target']=='previouspage') {
if ($many_many) {
DB::query('UPDATE "' . $table
@ -505,15 +507,15 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$targetItem->$sortColumn = $sortPositions[0];
$targetItem->write();
}
$i = 1;
foreach ($items as $obj) {
if ($obj->ID == $targetItem->ID) {
continue;
}
if ($many_many) {
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn.'" = ' . $sortPositions[$i]
@ -522,7 +524,7 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$obj->$sortColumn = $sortPositions[$i];
$obj->write();
}
$i++;
}
} else {
@ -534,15 +536,15 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$targetItem->$sortColumn = $sortPositions[count($sortPositions) - 1];
$targetItem->write();
}
$i = 0;
foreach ($items as $obj) {
if ($obj->ID == $targetItem->ID) {
continue;
}
if ($many_many) {
DB::query('UPDATE "' . $table
. '" SET "' . $sortColumn.'" = ' . $sortPositions[$i]
@ -551,18 +553,18 @@ class GridFieldSortableRows implements GridField_HTMLProvider, GridField_ActionP
$obj->$sortColumn = $sortPositions[$i];
$obj->write();
}
$i++;
}
}
//End transaction if supported
if(DB::getConn()->supportsTransactions()) {
DB::getConn()->transactionEnd();
}
//Event to notify the Controller or owner DataObject after list sort
if($owner && $owner instanceof DataObject && method_exists($owner, 'onAfterGridFieldPageSort')) {
$owner->onAfterGridFieldPageSort(clone $items);