[dokuwiki] Re: Patch submission : allow user-defined namespaces/pages order in the index

Please find below a new release of the patch (unified diff with 2009-06-17 
release)

Features are :
 - To define namespaces order : place in the namespace in which namespaces 
order shall be changed a file named ?.user_order_dirs?
In this file, place in the order you want it to appear the list of 
namespaces - i.e. directories - (one per line).
Non-existing namespaces will be ignored.
A line with a single '*' represents all namespaces (sorted alphabetically) 
remaining once the user sort has ended.
If no single '*' is present, the patch behaves as if there was a single 
'*' at the end of the list.
Wildcards are supported in the namespace names : '*' is any character 
present 0 time or more, '?' is any character present one and only one 
time.
Regex are supported as namespace names. It shall be written as complete 
regex (starting with '/', ending with '/').
To add comments, just begin a line with ':' or ';'.
Notice that every line is trimmed, i.e. spaces/tabulations/? at the 
beginning and the end of lines will have no impact.
Repeat this process in all concerned namespaces. 
 - To define pages order : place in the namespace in which pages order 
shall be changed a file named ?.user_order_files?
In this file, place in the order you want it to appear the list of pages - 
i.e. files - with the ?.txt? extension (one per line).
Non-existing pages will be ignored.
A line with a single '*' represents all pages (sorted alphabetically) 
remaining once the user sort has ended.
If no single '*' is present, the patch behaves as if there was a single 
'*' at the end of the list.
Wildcards are supported in the page names : '*' is any character present 0 
time or more, '?' is any character present one and only one time.
Regex are supported as page names. It shall be written as complete regex 
(starting with '/', ending with '/').Don't forget ?.txt? is needed at the 
end of the name
To add comments, just begin a line with ':' or ';'.
Notice that every line is trimmed, i.e. spaces/tabulations/? at the 
beginning and the end of lines will have no impact.
Repeat this process in all concerned namespaces.

----------------------------------------------------------------------------------------------------------------------------
--- inc/search.php      2009-06-05 13:06:56.000000000 +0200 
+++ inc/search.php      2009-06-17 12:24:30.000000000 +0200 
@@ -38,9 +38,18 @@ 
     $files[] = $dir.'/'.$file; 
   } 
   closedir($dh); 
-  sort($files); 
-  sort($dirs); 
- 
+  if(file_exists($base.'/'.$dir.'/.user_order_files')){ //if a user sort 
order exists for files
+    user_sort_order($files,file($base.'/'.$dir.'/.user_order_files')); 
//run the sorting function
+  }  
+  else{  
+    sort($files);  
+  }  
+  if(file_exists($base.'/'.$dir.'/.user_order_dirs')){ //if a user sort 
order exists for dirs 
+    user_sort_order($dirs,file($base.'/'.$dir.'/.user_order_dirs')); 
//run the sorting function 
+  }  
+  else{  
+    sort($dirs);  
+  }  
   //give directories to userfunction then recurse  
   foreach($dirs as $dir){  
     if (call_user_func_array($func, 
array(&$data,$base,$dir,'d',$lvl,$opts))){ 
@@ -63,6 +72,63 @@  
 }  
  
 /**  
+ * Apply user sort order when exists  
+ *  
+ * This function applies user sort order (of dirs or files)   
+ *  
+ * @param   array ref $items     List of items to sort   
+ * @param   array     $sort_list User defined sort list   
+ * @author  Matthieu Rioteau <matthieu.rioteau@xxxxxxx>   
+ */  
+function user_sort_order(&$items,$sort_list){  
+  $begin_sort = array(); //temporary stores the user-sorted items (top)
+  $end_sort = array(); //temporary stores the user-sorted items (bottom)
+  $is_end = false; //true if a bottom part is defined
+
+  foreach($sort_list as $sort_list_item){ //for each item defined in the 
user sort list
+    if(preg_match("/^\s*(;|:)/",$sort_list_item)){ //if sort list item is 
a comment...
+      continue; //...directly jump to next one
+    }
+    foreach($items as $item_id => $item){ //for each item present in the 
"to sort" list
+      $item_trim=trim(substr($item,-strlen(strrchr($item,"/"))),"/ 
\t\n\r\0"); //remove extra characters and path of item (only keep name)
+      $sort_list_item_trim=trim($sort_list_item); //remove extra 
characters
+      if(preg_match("/^\*$/",$sort_list_item_trim)){ //if a bottom part 
is defined
+        $is_end=true; //change flag status...
+        break;
+        ; //...and directly go to next item of sort list
+      }
+      else{
+        if(preg_match("/^\/.*\/$/",$sort_list_item_trim)){ //if the sort 
list item is a regex
+          $sort_list_item_reg=$sort_list_item_trim; //no need to create 
regex
+        }
+        else{
+ 
$sort_list_item_reg="/^".str_replace("*",".*",str_replace("?",".?",$sort_list_item_trim))."$/";
 
//create regex (mainly replace wildcards)
+        }
+        if(preg_match($sort_list_item_reg,$item_trim)){ //if the user 
list item is present in the "to sort" list
+          $temp_match[]=$item; //store the matching in a temp array...
+          unset($items[$item_id]); //...and remove it from the to sort 
list
+        }
+      }
+    } //when all matching items have been found
+    if(isset($temp_match)){ //if matches have been found
+      sort($temp_match); //sort the found matching items
+      if($is_end){ //if the bottom as been reached
+        $end_sort=array_merge($end_sort,$temp_match); //add new item(s) 
in the temporary sorted list (top)...
+      }
+      else{
+        $begin_sort=array_merge($begin_sort,$temp_match); //store item in 
the temporary sorted list (bottom)...
+      }
+      unset($temp_match); //clean temp array
+    }
+    unset($item_id); //clear reference
+    unset($item); //clear reference
+  }
+  unset($sort_list_item); //clear reference
+  sort($items); //sort remaining (i.e. not present in user sort order) 
items from lowest to highest
+  $items=array_values(array_merge($begin_sort,$items,$end_sort)); //merge 
user-sorted and auto-sorted items and clean array
+}
+
+/**
  * The following functions are userfunctions to use with the search
  * function above. This function is called for every found file or
  * directory. When a directory is given to the function it has to
----------------------------------------------------------------------------------------------------------------------------

Regards,
Matthieu
--
DokuWiki mailing list - more info at
http://wiki.splitbrain.org/wiki:mailinglist

Other related posts: