From 8d0e286a89e3ad07963562359bfa5f9e974fd1fb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= <grosse@cosmocode.de>
Date: Mon, 26 Mar 2018 16:14:08 +0200
Subject: [PATCH] feat(search) add option to sort by mtime

---
 inc/Ui/Search.php      |  8 ++++++++
 inc/Ui/SearchState.php | 19 +++++++++++++++++++
 inc/fulltext.php       | 26 +++++++++++++++++++++++---
 3 files changed, 50 insertions(+), 3 deletions(-)

diff --git a/inc/Ui/Search.php b/inc/Ui/Search.php
index dfb489f05..8a02e8139 100644
--- a/inc/Ui/Search.php
+++ b/inc/Ui/Search.php
@@ -77,6 +77,9 @@ class Search extends Ui
         if ($INPUT->has('before')) {
             $searchForm->setHiddenField('before', $INPUT->str('before'));
         }
+        if ($INPUT->has('sort')) {
+            $searchForm->setHiddenField('sort', $INPUT->str('sort'));
+        }
         $searchForm->addFieldsetOpen()->addClass('search-results-form__fieldset');
         $searchForm->addTextInput('q')->val($query)->useInput(false);
         $searchForm->addButton('', $lang['btn_search'])->attr('type', 'submit');
@@ -89,6 +92,11 @@ class Search extends Ui
             $searchForm->addHTML('FIXME Your query is too complex. Search assistance is unavailable. See <a href="https://doku.wiki/search">doku.wiki/search</a> for more help.');
             $searchForm->addTagClose('span');
         }
+        if ($INPUT->str('sort') === 'mtime') {
+            $this->searchState->addSearchLinkSort($searchForm, 'sort by hits', '');
+        } else {
+            $this->searchState->addSearchLinkSort($searchForm, 'sort by mtime', 'mtime');
+        }
 
         $searchForm->addFieldsetClose();
 
diff --git a/inc/Ui/SearchState.php b/inc/Ui/SearchState.php
index 3b2a59add..05fcf5142 100644
--- a/inc/Ui/SearchState.php
+++ b/inc/Ui/SearchState.php
@@ -18,6 +18,7 @@ class SearchState
         $this->parsedQuery = $parsedQuery;
         $this->parsedQuery['after'] = $INPUT->str('after');
         $this->parsedQuery['before'] = $INPUT->str('before');
+        $this->parsedQuery['sort'] = $INPUT->str('sort');
     }
 
     /**
@@ -66,6 +67,21 @@ class SearchState
         $this->addSearchLink($searchForm, $label, $parsedQuery);
     }
 
+    /**
+     * Add a link to the form which sets the sort preference for the current search
+     *
+     * @param Form $searchForm
+     * @param string $label
+     * @param string $sort
+     */
+    public function addSearchLinkSort(Form $searchForm, $label, $sort)
+    {
+        $parsedQuery = $this->parsedQuery;
+        $parsedQuery['sort'] = $sort;
+
+        $this->addSearchLink($searchForm, $label, $parsedQuery);
+    }
+
     protected function addSearchLink(
         Form $searchForm,
         $label,
@@ -87,6 +103,9 @@ class SearchState
         if ($parsedQuery['before']) {
             $hrefAttributes['before'] = $parsedQuery['before'];
         }
+        if ($parsedQuery['sort']) {
+            $hrefAttributes['sort'] = $parsedQuery['sort'];
+        }
         $searchForm->addTagOpen('a')
             ->attrs([
                 'href' => wl($ID, $hrefAttributes, false, '&')
diff --git a/inc/fulltext.php b/inc/fulltext.php
index 987010c93..e7baac189 100644
--- a/inc/fulltext.php
+++ b/inc/fulltext.php
@@ -24,11 +24,12 @@ if(!defined('FT_SNIPPET_NUMBER')) define('FT_SNIPPET_NUMBER',15);
  * @param array $highlight
  * @return array
  */
-function ft_pageSearch($query,&$highlight){
+function ft_pageSearch($query,&$highlight, $sort = 'hits'){
 
     $data = array();
     $data['query'] = $query;
     $data['highlight'] =& $highlight;
+    $data['sort'] = $sort;
 
     return trigger_event('SEARCH_QUERY_FULLPAGE', $data, '_ft_pageSearch');
 }
@@ -135,8 +136,13 @@ function _ft_pageSearch(&$data) {
     }
 
     $docs = _ft_filterResultsByTime($docs);
-    // sort docs by count
-    arsort($docs);
+
+    if ($data['sort'] === 'mtime') {
+        uksort($docs, 'ft_pagemtimesorter');
+    } else {
+        // sort docs by count
+        arsort($docs);
+    }
 
     return $docs;
 }
@@ -351,6 +357,20 @@ function ft_pagesorter($a, $b){
     return strcmp ($a,$b);
 }
 
+/**
+ * Sort pages by their mtime, from newest to oldest
+ *
+ * @param string $a
+ * @param string $b
+ *
+ * @return int Returns < 0 if $a is newer than $b, > 0 if $b is newer than $a and 0 if they are of the same age
+ */
+function ft_pagemtimesorter($a, $b) {
+    $mtimeA = filemtime(wikiFN($a));
+    $mtimeB = filemtime(wikiFN($b));
+    return $mtimeB - $mtimeA;
+}
+
 /**
  * Creates a snippet extract
  *
-- 
GitLab