From d74913c6df41b27eb1ea8388a47d94e66f97c652 Mon Sep 17 00:00:00 2001 From: Michael Hamann <michael@content-space.de> Date: Sat, 3 Apr 2010 14:40:32 +0200 Subject: [PATCH] Fixed sorting in the acl manager treeview Previously the content of expanded namespaces was displayed below all other pages, now it is placed below it's parent namespace. The new comparison function is quite complex. Please have a look at it if it can done easier or if there are cases I haven't considered where the function produces incorrect results. --- lib/plugins/acl/admin.php | 39 ++++++++++++++++++++++++++++++++------- 1 file changed, 32 insertions(+), 7 deletions(-) diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php index b38d2ac6e..dcd72b611 100644 --- a/lib/plugins/acl/admin.php +++ b/lib/plugins/acl/admin.php @@ -267,8 +267,7 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin { usort($data,array($this,'_tree_sort')); $count = count($data); if($count>0) for($i=1; $i<$count; $i++){ - if($data[$i]['type'] == 'f') break; // namespaces come first, we're done - if($data[$i-1]['id'] == $data[$i]['id']) unset($data[$i]); + if($data[$i-1]['id'] == $data[$i]['id'] && $data[$i-1]['type'] == $data[$i]['type']) unset($data[$i]); } return $data; } @@ -279,13 +278,39 @@ class admin_plugin_acl extends DokuWiki_Admin_Plugin { * Sorts the combined trees of media and page files */ function _tree_sort($a,$b){ - if($a['type'] == 'd' && $b['type'] == 'f'){ + // handle the trivial cases first + if ($a['id'] == '') return -1; + if ($b['id'] == '') return 1; + // split up the id into parts + $a_ids = explode(':', $a['id']); + $b_ids = explode(':', $b['id']); + // now loop through the parts + while (count($a_ids) && count($b_ids)) { + // compare each level from upper to lower + // until a non-equal component is found + $cur_result = strcmp(array_shift($a_ids), array_shift($b_ids)); + if ($cur_result) { + // if one of the components is the last component and is a file + // and the other one is either of a deeper level or a directory, + // the file has to come after the deeper level or directory + if (empty($a_ids) && $a['type'] == 'f' && (count($b_ids) || $b['type'] == 'd')) return 1; + if (empty($b_ids) && $b['type'] == 'f' && (count($a_ids) || $a['type'] == 'd')) return -1; + return $cur_result; + } + } + // The two ids seem to be equal. One of them might however refer + // to a page, one to a namespace, the namespace needs to be first. + if (empty($a_ids) && empty($b_ids)) { + if ($a['type'] == $b['type']) return 0; + if ($a['type'] == 'f') return 1; return -1; - }elseif($a['type'] == 'f' && $b['type'] == 'd'){ - return 1; - }else{ - return strcmp($a['id'],$b['id']); } + // Now the empty part is either a page in the parent namespace + // that obviously needs to be after the namespace + // Or it is the namespace that contains the other part and should be + // before that other part. + if (empty($a_ids)) return ($a['type'] == 'd') ? -1 : 1; + if (empty($b_ids)) return ($b['type'] == 'd') ? 1 : -1; } /** -- GitLab