diff --git a/lib/plugins/acl/admin.php b/lib/plugins/acl/admin.php index b38d2ac6eddf8a308d7938eba35a6625df22185b..dcd72b6110833c0c188a7a74be4b1d7c631f8d0e 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; } /**