From 6661eb28de2a0bd1a41ee0997df33926b0a1872d Mon Sep 17 00:00:00 2001 From: Cameron Date: Fri, 3 Apr 2015 21:19:43 -0700 Subject: [PATCH] Improved parent/child drag-n-drop sorting on custom-pages and forum. --- e107_admin/cpage.php | 20 ++++-- e107_core/sql/core_sql.php | 2 +- e107_handlers/admin_ui.php | 71 +++++++++++++++++++- e107_plugins/forum/forum_admin.php | 100 ++++++++++++++++++++++++----- 4 files changed, 168 insertions(+), 25 deletions(-) diff --git a/e107_admin/cpage.php b/e107_admin/cpage.php index 548d8d9b5..f318e2699 100644 --- a/e107_admin/cpage.php +++ b/e107_admin/cpage.php @@ -140,17 +140,21 @@ class page_chapters_ui extends e_admin_ui protected $batchDelete = false; protected $batchCopy = true; protected $batchLink = true; - protected $listOrder = ' COALESCE(NULLIF(chapter_parent,0), chapter_id), chapter_parent > 0, chapter_order '; //FIXME works with parent/child but doesn't respect parent order. + + protected $listQry = "SELECT a. *, CASE WHEN a.chapter_parent = 0 THEN a.chapter_order ELSE b.chapter_order + (( a.chapter_order)/1000) END AS Sort FROM `#page_chapters` AS a LEFT JOIN `#page_chapters` AS b ON a.chapter_parent = b.chapter_id "; + protected $listOrder = 'Sort,chapter_order '; + // protected $listOrder = ' COALESCE(NULLIF(chapter_parent,0), chapter_id), chapter_parent > 0, chapter_order '; //FIXME works with parent/child but doesn't respect parent order. protected $url = array('route'=>'page/chapter/index', 'vars' => array('id' => 'chapter_id', 'name' => 'chapter_sef'), 'name' => 'chapter_name', 'description' => ''); // 'link' only needed if profile not provided. - // protected $sortField = 'chapter_order'; + protected $sortField = 'chapter_order'; + protected $sortParent = 'chapter_parent'; // protected $orderStep = 10; protected $fields = array( 'checkboxes' => array('title'=> '', 'type' => null, 'width' =>'5%', 'forced'=> TRUE, 'thclass'=>'center', 'class'=>'center'), 'chapter_id' => array('title'=> LAN_ID, 'type' => 'number', 'width' =>'5%', 'forced'=> TRUE, 'readonly'=>TRUE), 'chapter_icon' => array('title'=> LAN_ICON, 'type' => 'icon', 'data' => 'str', 'width' => '100px', 'thclass' => 'center', 'class'=>'center', 'writeParms'=> 'glyphs=1', 'readonly'=>FALSE, 'batch' => FALSE, 'filter'=>FALSE), - 'chapter_parent' => array('title'=> "Book", 'type' => 'dropdown', 'width' => 'auto', 'thclass' => 'left', 'readonly'=>FALSE, 'filter'=>true), + 'chapter_parent' => array('title'=> "Book", 'type' => 'dropdown', 'width' => 'auto', 'thclass' => 'left', 'readonly'=>FALSE, 'filter'=>true), 'chapter_name' => array('title'=> "Book or Chapter Title", 'type' => 'method', 'width' => 'auto', 'thclass' => 'left', 'readonly'=>FALSE, 'writeParms'=>'size=xxlarge'), 'chapter_template' => array('title'=> LAN_TEMPLATE, 'type' => 'dropdown', 'width' => 'auto','filter' => true, 'batch'=>true, 'inline'=>true, 'writeParms'=>''), @@ -171,6 +175,12 @@ class page_chapters_ui extends e_admin_ui function init() { + + if($this->getAction() == 'list') + { + $this->fields['chapter_parent']['title'] = 'Parent'; + } + $sql = e107::getDb(); $sql->gen("SELECT chapter_id,chapter_name FROM #page_chapters WHERE chapter_parent =0"); $this->books[0] = "(New Book)"; @@ -245,6 +255,8 @@ class page_chapters_form_ui extends e_admin_form_ui $parent = $this->getController()->getListModel()->get('chapter_parent'); $id = $this->getController()->getListModel()->get('chapter_id'); + $level = 1; + $linkQ = e_SELF."?searchquery=&filter_options=page_chapter__".$id."&mode=page&action=list"; $level_image = $parent ? ' ' : ''; @@ -278,7 +290,7 @@ class page_chapters_form_ui extends e_admin_form_ui // return "".$curVal.""; $parent = $this->getController()->getListModel()->get('chapter_parent'); // $id = $this->getController()->getListModel()->get('chapter_id'); - // $att['readParms'] = 'sort=1'; + $att['readParms'] = 'sort=1'; $text = ""; if($attributes['mode'] == 'read') diff --git a/e107_core/sql/core_sql.php b/e107_core/sql/core_sql.php index 80dbd0df2..a1c62c86a 100644 --- a/e107_core/sql/core_sql.php +++ b/e107_core/sql/core_sql.php @@ -414,7 +414,7 @@ CREATE TABLE page_chapters ( chapter_meta_keywords varchar(255) NOT NULL default '', chapter_manager tinyint(3) unsigned NOT NULL default '254', chapter_icon varchar(250) NOT NULL default '', - chapter_order int(4) unsigned NOT NULL default '0', + chapter_order int(6) unsigned NOT NULL default '0', chapter_template varchar(50) NOT NULL default '', chapter_visibility tinyint(3) unsigned NOT NULL default '0', PRIMARY KEY (chapter_id), diff --git a/e107_handlers/admin_ui.php b/e107_handlers/admin_ui.php index 4f39d4984..2ed84f2f4 100644 --- a/e107_handlers/admin_ui.php +++ b/e107_handlers/admin_ui.php @@ -4055,6 +4055,9 @@ class e_admin_ui extends e_admin_controller_ui protected $pid; protected $listQry; protected $editQry; + protected $sortField; + protected $sortParent; + protected $orderStep; /** @@ -4857,6 +4860,12 @@ class e_admin_ui extends e_admin_controller_ui echo 'Missing sort field value'; return; } + + if(!empty($this->sortParent)) // Force 100 positions for child when sorting with parent/child. + { + $this->orderStep = 100; + } + $sql = e107::getDb(); $step = $this->orderStep ? intval($this->orderStep) : 1; @@ -4884,7 +4893,52 @@ class e_admin_ui extends e_admin_controller_ui // $changed = (intval($_POST['neworder']) * $step) + $from ; $changed = $c - $step; $qry = "UPDATE `#".$this->table."` e, (SELECT @n := ".($changed).") m SET e.".$this->sortField." = @n := @n + ".$step." WHERE ".$this->sortField." > ".($changed); - $sql->gen($qry); + + $result = $sql->gen($qry); + + + // ------------ Fix Child Order when parent is used. ---------------- + + if(!empty($this->sortParent) && !empty($this->sortField) ) // Make sure there is space for at least 99 + { + + + $data2 = $sql->retrieve($this->table,$this->pid.','.$this->sortField,$this->sortParent .' = 0',true); + foreach($data2 as $val) + { + $id = $val[$this->pid]; + $parent[$id] = $val[$this->sortField]; + + } + + $previous = 0; + + $data = $sql->retrieve($this->table,'*',$this->sortParent.' != 0 ORDER BY '.$this->sortField,true); + + foreach($data as $row) + { + $p = $row[$this->sortParent]; + + if($p != $previous) + { + $c = $parent[$p]; + } + + $c++; + $previous = $p; + + // echo "
".$row['forum_name']." with parent: ".$p." old: ".$row['forum_order']." new: ".$c; + $sql->update($this->table, $this->sortField . ' = '.$c.' WHERE '.$this->pid.' = '.intval($row[$this->pid]).' LIMIT 1'); + + } + + + + + + } + + $this->afterSort($result, $_POST); // e107::getLog()->addDebug(print_r($_POST,true))->toFile('SortAjax','Admin-UI Ajax Sort Log', true); // e107::getLog()->addDebug(print_r($updated,true))->toFile('SortAjax','Admin-UI Ajax Sort Log', true); @@ -5043,8 +5097,8 @@ class e_admin_ui extends e_admin_controller_ui } /** - * User defined error handling, return true to suppress model messages - */ + * User defined error handling, return true to suppress model messages + */ public function onUpdateError($new_data, $old_data, $id) { } @@ -5059,6 +5113,17 @@ class e_admin_ui extends e_admin_controller_ui { } + + /** + * User defined after-sort logic + * @param mixed $result + * @param array $selected + * @return void + */ + public function afterSort($result, $selected) + { + } + /** * Create - send JS to page Header * @return none diff --git a/e107_plugins/forum/forum_admin.php b/e107_plugins/forum/forum_admin.php index 64f3ffb2d..fef5066bc 100644 --- a/e107_plugins/forum/forum_admin.php +++ b/e107_plugins/forum/forum_admin.php @@ -19,7 +19,11 @@ if (!getperms('P')) exit; } -// define('NEW_FORUMADMIN', true); +if(E107_DEBUG_LEVEL > 0) +{ + define('NEW_FORUMADMIN', true); + e107::getMessage()->addwarning("Experimental code now active. Using this page in debug mode active could break your forum configuration."); +} // Generated e107 Plugin Admin Area @@ -71,30 +75,31 @@ if(deftrue('NEW_FORUMADMIN')) // protected $eventName = 'forum-forum'; // remove comment to enable event triggers in admin. protected $table = 'forum'; protected $pid = 'forum_id'; - protected $perPage = 10; + protected $perPage = 30; protected $batchDelete = true; // protected $batchCopy = true; protected $sortField = 'forum_order'; + protected $sortParent = 'forum_parent'; protected $orderStep = 50; + + /* // protected $tabs = array('Tabl 1','Tab 2'); // Use 'tab'=>0 OR 'tab'=>1 in the $fields below to enable. + // protected $listQry = "SELECT *, xAND forum_order > 45 THEN forum_order ELSE forum_order + forum_parent END AS Sort FROM `#forum` "; // Example Custom Query. LEFT JOINS allowed. Should be without any Order or Limit. + // protected $listQry = "SELECT *, CASE WHEN forum_parent = 0 OR forum_order =0 THEN forum_id + (forum_order/1000) ELSE forum_parent + (forum_order/1000) END AS Sort FROM `#forum` "; // Example Custom Query. LEFT JOINS allowed. Should be without any Order or Limit. + // protected $listOrder = ' COALESCE(NULLIF(forum_parent,0), forum_order), forum_parent > 0, forum_order '; //FIXME works with parent/child but doesn't respect parent order. + // protected $listQry = "SELECT * , forum_parent + forum_order AS Sort FROM `#forum` "; + */ - // protected $listQry = "SELECT *, xAND forum_order > 45 THEN forum_order ELSE forum_order + forum_parent END AS Sort FROM `#forum` "; // Example Custom Query. LEFT JOINS allowed. Should be without any Order or Limit. - - // protected $listQry = "SELECT *, CASE WHEN forum_parent = 0 OR forum_order =0 THEN forum_id + (forum_order/1000) ELSE forum_parent + (forum_order/1000) END AS Sort FROM `#forum` "; // Example Custom Query. LEFT JOINS allowed. Should be without any Order or Limit. - - protected $listQry = "SELECT a. *, CASE WHEN a.forum_parent = 0 THEN a.forum_order ELSE b.forum_order + (( a.forum_order)/1000) END AS Sort FROM e107_forum AS a LEFT JOIN e107_forum AS b ON a.forum_parent = b.forum_id "; - - // protected $listQry = "SELECT * , forum_parent + forum_order AS Sort FROM `#forum` "; + protected $listQry = "SELECT a. *, CASE WHEN a.forum_parent = 0 THEN a.forum_order ELSE b.forum_order + (( a.forum_order)/1000) END AS Sort FROM `#forum` AS a LEFT JOIN `#forum` AS b ON a.forum_parent = b.forum_id "; protected $listOrder = 'Sort,forum_order '; - - // protected $listOrder = ' COALESCE(NULLIF(forum_parent,0), forum_order), forum_parent > 0, forum_order '; //FIXME works with parent/child but doesn't respect parent order. + // protected $listOrder = 'forum_order'; protected $fields = array ( 'checkboxes' => array ( 'title' => '', 'type' => null, 'data' => null, 'width' => '5%', 'thclass' => 'center', 'forced' => '1', 'class' => 'center', 'toggle' => 'e-multiselect', ), 'forum_id' => array ( 'title' => LAN_ID, 'data' => 'int', 'width' => '5%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), - 'forum_name' => array ( 'title' => LAN_TITLE, 'type' => 'method', 'data' => 'str', 'width' => '40%', 'inline' => false, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), - 'forum_description' => array ( 'title' => LAN_DESCRIPTION, 'type' => 'textarea', 'data' => 'str', 'width' => '40%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), - 'forum_parent' => array ( 'title' => 'Parent', 'type' => 'dropdown', 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), + 'forum_name' => array ( 'title' => LAN_TITLE, 'type' => 'method', 'inline'=>true, 'data' => 'str', 'width' => '40%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), + 'forum_description' => array ( 'title' => LAN_DESCRIPTION, 'type' => 'textarea', 'data' => 'str', 'width' => '30%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), + 'forum_parent' => array ( 'title' => 'Parent', 'type' => 'dropdown', 'data' => 'int', 'width' => '10%', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), 'forum_sub' => array ( 'title' => 'SubForum of', 'type' => 'dropdown', 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), 'forum_moderators' => array ( 'title' => 'Moderators', 'type' => 'userclass', 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), 'forum_threads' => array ( 'title' => 'Threads', 'type' => 'number', 'data' => 'int', 'noedit'=>true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), @@ -103,7 +108,7 @@ if(deftrue('NEW_FORUMADMIN')) 'forum_lastpost_user_anon' => array ( 'title' => 'User-Anon', 'type' => 'hidden','noedit'=>true, 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), 'forum_lastpost_info' => array ( 'title' => 'LastPost', 'type' => 'hidden', 'noedit'=>true, 'data' => 'str', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), 'forum_class' => array ( 'title' => LAN_VISIBILITY, 'type' => 'userclass', 'data' => 'int', 'width' => 'auto', 'batch' => true, 'filter' => true, 'inline' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), - 'forum_order' => array ( 'title' => LAN_ORDER, 'type' => 'number', 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), + 'forum_order' => array ( 'title' => LAN_ORDER, 'type' => 'text', 'data' => 'int', 'inline'=>true, 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), 'forum_postclass' => array ( 'title' => 'Post Permission', 'type' => 'userclass', 'inline'=>true,'filter'=>true, 'batch'=>true, 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), 'forum_threadclass' => array ( 'title' => 'Thread Creation Class', 'type' => 'userclass', 'inline'=>true, 'filter'=>true, 'batch'=>true, 'data' => 'int', 'width' => 'auto', 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'center', 'thclass' => 'center', ), 'forum_datestamp' => array ( 'title' => LAN_DATESTAMP, 'type' => 'datestamp', 'data' => 'int', 'noedit'=>true, 'width' => 'auto', 'filter' => true, 'help' => '', 'readParms' => '', 'writeParms' => '', 'class' => 'left', 'thclass' => 'left', ), @@ -133,6 +138,12 @@ if(deftrue('NEW_FORUMADMIN')) public function init() { + if($this->getAction() == 'edit') + { + $this->fields['forum_order']['noedit'] = true; + } + + $data = e107::getDb()->retrieve('forum', 'forum_id,forum_name,forum_parent', 'forum_id != 0',true); $this->forumParents[0] = "(New Parent)"; $forumSubParents = array(); @@ -153,16 +164,60 @@ if(deftrue('NEW_FORUMADMIN')) } $this->fields['forum_parent']['writeParms'] = $this->forumParents; - $this->fields['forum_sub']['writeParms'] = $forumSubParents; + $this->fields['forum_sub']['writeParms']['optArray'] = $forumSubParents; + $this->fields['forum_sub']['writeParms']['default'] = 'blank'; } // ------- Customize Create -------- + public function afterSort($result, $selected) + { + + return; + + $sql = e107::getDb(); + + $data2 = $sql->retrieve('forum','forum_id,forum_name,forum_parent,forum_order','forum_parent = 0',true); + foreach($data2 as $val) + { + $id = $val['forum_id']; + $parent[$id] = $val['forum_order']; + + } + + $previous = 0; + + $data = $sql->retrieve('forum','*','forum_parent != 0 ORDER BY forum_order',true); + foreach($data as $row) + { + $p = $row['forum_parent']; + + if($p != $previous) + { + $c = $parent[$p]; + } + + $c++; + $previous = $p; + + // echo "
".$row['forum_name']." with parent: ".$p." old: ".$row['forum_order']." new: ".$c; + $sql->update('forum','forum_order = '.$c.' WHERE forum_id = '.intval($row['forum_id']).' LIMIT 1'); + + } + + } + + + public function beforeCreate($new_data) { - // return $new_data; + $sql = e107::getDb(); + $parentOrder = $sql->retrieve('forum','forum_order','forum_id='.$new_data['forum_parent']." LIMIT 1"); + + $new_data['forum_order'] = $parentOrder + 1; + return $new_data; } public function afterCreate($new_data, $old_data, $id) @@ -253,6 +308,17 @@ if(deftrue('NEW_FORUMADMIN')) { return; } + + if($mode == 'inline') + { + $parent = $this->getController()->getListModel()->get('forum_parent'); + if(empty($parent)) + { + return array('inlineType'=>'text'); + } + + return false; + } }