From c7cca847c83e96de8467ea4d38fc78bea3b93ece Mon Sep 17 00:00:00 2001 From: Ingo Schommer Date: Sat, 21 Nov 2009 03:16:30 +0000 Subject: [PATCH] ENHANCEMENT Updated LeftAndMain->ajaxupdateparent() and ajaxupdatesort() to return JSON data rather than FormResponse eval()ed javascript, and let the clientside handle any updates. Also updated to use HTTPRequest instead of superglobals. git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/cms/trunk@92740 467b73ca-7a2a-4603-9d3b-597d59a354a9 --- code/LeftAndMain.php | 131 +++++++++++++++++---------------- javascript/LeftAndMain.Tree.js | 92 +++++++++++++++-------- 2 files changed, 128 insertions(+), 95 deletions(-) diff --git a/code/LeftAndMain.php b/code/LeftAndMain.php index b14d8600..69f69ee0 100644 --- a/code/LeftAndMain.php +++ b/code/LeftAndMain.php @@ -683,20 +683,19 @@ JS; /** * Ajax handler for updating the parent of a tree node */ - public function ajaxupdateparent() { - $id = $_REQUEST['ID']; - $parentID = $_REQUEST['ParentID']; - if($parentID == 'root'){ - $parentID = 0; - } - $_REQUEST['ajax'] = 1; - $cleanupJS = ''; - + public function ajaxupdateparent($request) { if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) { - FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad"); - return FormResponse::respond(); + $this->response->setStatusCode( + 403, + _t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved.") + ); + return; } + $id = $request->requestVar('ID'); + $parentID = $request->requestVar('ParentID'); + $statusUpdates = array('modified'=>array()); + if(is_numeric($id) && is_numeric($parentID) && $id != $parentID) { $node = DataObject::get_by_id($this->stat('tree_class'), $id); if($node){ @@ -713,18 +712,33 @@ JS; } } - FormResponse::status_message(_t('LeftAndMain.SAVED','saved'), 'good'); - if($cleanupJS) FormResponse::add($cleanupJS); + $node = DataObject::get_by_id($this->stat('tree_class'), $id); + if($node){ + if($node && !$node->canEdit()) return Security::permissionFailure($this); + + $node->ParentID = $parentID; + $node->Status = "Saved (update)"; + $node->write(); + + $statusUpdates['modified'][$node->ID] = array( + 'TreeTitle'=>$node->TreeTitle + ); - }else{ - FormResponse::status_message(_t('LeftAndMain.PLEASESAVE',"Please Save Page: This page could not be upated because it hasn't been saved yet."),"good"); - } - - - return FormResponse::respond(); - } else { - user_error("Error in ajaxupdateparent request; id=$id, parentID=$parentID", E_USER_ERROR); + $this->response->addHeader( + 'X-Status', + _t('LeftAndMain.SAVED','saved') + ); + }else{ + $this->response->setStatusCode( + 500, + _t( + 'LeftAndMain.PLEASESAVE', + "Please Save Page: This page could not be upated because it hasn't been saved yet." + ) + ); } + + return Convert::raw2json($statusUpdates); } /** @@ -732,53 +746,44 @@ JS; * $_GET[ID]: An array of node ids in the correct order * $_GET[MovedNodeID]: The node that actually got moved */ - public function ajaxupdatesort() { + public function ajaxupdatesort($request) { + if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) { + $this->response->setStatusCode( + 403, + _t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved.") + ); + return; + } + $className = $this->stat('tree_class'); $counter = 0; - $js = ''; - $_REQUEST['ajax'] = 1; + $statusUpdates = array('modified'=>array()); + + if(!is_array($request->requestVar('ID'))) return false; - if (!Permission::check('SITETREE_REORGANISE') && !Permission::check('ADMIN')) { - FormResponse::status_message(_t('LeftAndMain.CANT_REORGANISE',"You do not have permission to rearange the site tree. Your change was not saved."),"bad"); - return FormResponse::respond(); + //Sorting root + if($request->requestVar('MovedNodeID')==0){ + $movedNode = DataObject::get($className, "\"ParentID\"=0"); + }else{ + $movedNode = DataObject::get_by_id($className, $request->requestVar('MovedNodeID')); + } + foreach($request->requestVar('ID') as $id) { + if($id == $movedNode->ID) { + $movedNode->Sort = ++$counter; + $movedNode->Status = "Saved (update)"; + $movedNode->write(); + $statusUpdates['modified'][$movedNode->ID] = array( + 'TreeTitle'=>$movedNode->TreeTitle + ); + } else if(is_numeric($id)) { + // Nodes that weren't "actually moved" shouldn't be registered as + // having been edited; do a direct SQL update instead + ++$counter; + DB::query("UPDATE \"$className\" SET \"Sort\" = $counter WHERE \"ID\" = '$id'"); + } } - if(is_array($_REQUEST['ID'])) { - if($_REQUEST['MovedNodeID']==0){ //Sorting root - $movedNode = DataObject::get($className, "\"ParentID\"=0"); - }else{ - $movedNode = DataObject::get_by_id($className, $_REQUEST['MovedNodeID']); - } - foreach($_REQUEST['ID'] as $id) { - if($id == $movedNode->ID) { - $movedNode->Sort = ++$counter; - $movedNode->Status = "Saved (update)"; - $movedNode->write(); - - $title = Convert::raw2js($movedNode->TreeTitle); - $js .="$('sitetree').setNodeTitle($movedNode->ID, \"$title\");\n"; - - // Nodes that weren't "actually moved" shouldn't be registered as having been edited; do a direct SQL update instead - } else if(is_numeric($id)) { - ++$counter; - DB::query("UPDATE \"$className\" SET \"Sort\" = $counter WHERE \"ID\" = '$id'"); - } - } - // Virtual pages require selected to be null if the page is the same. - FormResponse::add( - "if( $('sitetree').selected && $('sitetree').selected[0]){ - var idx = $('sitetree').selected[0].getIdx(); - if(idx){ - $('Form_EditForm').getPageFromServer(idx); - } - }\n" . $js - ); - FormResponse::status_message(_t('LeftAndMain.SAVED'), 'good'); - } else { - FormResponse::error(_t('LeftAndMain.REQUESTERROR',"Error in request")); - } - - return FormResponse::respond(); + return Convert::raw2json($statusUpdates); } public function CanOrganiseSitetree() { diff --git a/javascript/LeftAndMain.Tree.js b/javascript/LeftAndMain.Tree.js index cc3a91cf..5484dc66 100755 --- a/javascript/LeftAndMain.Tree.js +++ b/javascript/LeftAndMain.Tree.js @@ -445,6 +445,8 @@ SiteTreeNode.prototype = { * Drag'n'drop handlers - Ajax saving */ onParentChanged : function(node, oldParent, newParent) { + var self = this; + if(newParent.id.match(/^record-new/)) { alert("You must save the page before dragging children into it"); return false; @@ -465,18 +467,30 @@ SiteTreeNode.prototype = { return false; } - var currentlyOpenPageID = 0; - if($('Form_EditForm').elements.ID) currentlyOpenPageID = $('Form_EditForm').elements.ID.value; - - statusMessage(ss.i18n._t('CMSMAIN.SAVING'), '', true); - new Ajax.Request(SiteTreeHandlers.parentChanged_url, { - method : 'post', - postBody : 'ID=' + node.getIdx() + '&ParentID=' + newParent.getIdx() + '&CurrentlyOpenPageID=' + currentlyOpenPageID, - onSuccess : Ajax.Evaluator, - onFailure : function(response) { - errorMessage('error saving parent', response); - } - }); + jQuery.post( + SiteTreeHandlers.parentChanged_url, + 'ID=' + node.getIdx() + '&ParentID=' + newParent.getIdx(), + function(data, status) { + // TODO This should use a more common serialization in a new tree library + if(data.modified) { + for(var id in data.modified) { + self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']); + } + } + + // Check if current page still exists, and refresh it. + // Otherwise remove the current form + var selectedNode = self.tree.firstSelected(); + if(selectedNode) { + var selectedNodeId = self.tree.getIdxOf(selectedNode); + if(data.modified[selectedNode.getIdx()]) { + // only if the current page was modified + selectedNode.selectTreeNode(); + } + } + }, + 'json' + ); return true; }, @@ -487,8 +501,8 @@ SiteTreeNode.prototype = { * movedNode is the node that actually got moved to trigger this resorting */ onOrderChanged : function(nodeList, movedNode) { - statusMessage(ss.i18n._t('CMSMAIN.SAVING'), '', true); - + var self = this; + var i, parts = Array(); sort = 0; @@ -497,10 +511,14 @@ SiteTreeNode.prototype = { parts[parts.length] = 'ID[]=' + nodeList[i].getIdx(); // Ensure that the order of new records is preserved when they are moved THEN saved - if( nodeList[i].id.indexOf("record-new") == 0 ) - if( $('Form_EditForm_ID') && ( 'record-' + $('Form_EditForm_ID').value == nodeList[i].id ) ) - if( $('Form_EditForm_Sort') ) - $('Form_EditForm_Sort').value = ++sort; + if( + nodeList[i].id.indexOf("record-new") == 0 + && $('Form_EditForm_ID') + && ('record-' + $('Form_EditForm_ID').value == nodeList[i].id) + && $('Form_EditForm_Sort') + ) { + $('Form_EditForm_Sort').value = ++sort + } } } @@ -508,21 +526,31 @@ SiteTreeNode.prototype = { parts[parts.length] = 'MovedNodeID=' + movedNode.getIdx(); } - var currentlyOpenPageID = 0; - if($('Form_EditForm').elements.ID) currentlyOpenPageID = $('Form_EditForm').elements.ID.value; - if(parts) { - new Ajax.Request(SiteTreeHandlers.orderChanged_url, { - method : 'post', - postBody : parts.join('&') + '&CurrentlyOpenPageID=' + currentlyOpenPageID, - /*onSuccess : function(response) { - // statusMessage(response.responseText, 'good'); - },*/ - onSuccess: Ajax.Evaluator, - onFailure : function(response) { - errorMessage('error saving order', response); - } - }); + jQuery.post( + SiteTreeHandlers.orderChanged_url, + parts.join('&'), + function(data, status) { + // TODO This should use a more common serialization in a new tree library + if(data.modified) { + for(var id in data.modified) { + self.tree.setNodeTitle(id, data.modified[id]['TreeTitle']); + } + } + + // Check if current page still exists, and refresh it. + // Otherwise remove the current form + var selectedNode = self.tree.firstSelected(); + if(selectedNode) { + var selectedNodeId = self.tree.getIdxOf(selectedNode); + if(data.modified[selectedNode.getIdx()]) { + // only if the current page was modified + selectedNode.selectTreeNode(); + } + } + }, + 'json' + ); } return true;