From 42690e4d38f9519f308f64893283e7d5ad3616f4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20Gro=C3=9Fe?= <grosse@cosmocode.de>
Date: Fri, 27 Apr 2018 10:46:19 +0200
Subject: [PATCH] feat: improve search as a primary means to create new pages

Specifically, this pull request checks if the current query is already a
valid pageid and then return that as suggested pageid.

Also, tests are added for this method.

Fixes #2355

PS: We may want to somehow better educate/nudge users to use the better
way of creating pages by creating links on existing pages.
---
 .../Search_createPagenameFromQuery.test.php   | 133 ++++++++++++++++++
 inc/Ui/Search.php                             |   8 +-
 2 files changed, 139 insertions(+), 2 deletions(-)
 create mode 100644 _test/tests/inc/Ui/Search_createPagenameFromQuery.test.php

diff --git a/_test/tests/inc/Ui/Search_createPagenameFromQuery.test.php b/_test/tests/inc/Ui/Search_createPagenameFromQuery.test.php
new file mode 100644
index 000000000..ad59fea7e
--- /dev/null
+++ b/_test/tests/inc/Ui/Search_createPagenameFromQuery.test.php
@@ -0,0 +1,133 @@
+<?php
+
+/**
+ * Class Search_createPagenameFromQuery
+ *
+ */
+class Search_createPagenameFromQuery extends DokuWikiTest
+{
+
+    /**
+     * @return array
+     */
+    function dataProvider()
+    {
+        return [
+            [
+                [
+                    'query' => 'foo',
+                    'parsed_str' => '(W+:foo)',
+                    'parsed_ary' => [0 => 'W+:foo',],
+                    'words' => [0 => 'foo',],
+                    'highlight' => [0 => 'foo',],
+                    'and' => [0 => 'foo',],
+                    'phrases' => [],
+                    'ns' => [],
+                    'notns' => [],
+                    'not' => [],
+                ],
+                ':foo',
+                'simple single search word',
+            ],
+            [
+                [
+                    'query' => 'foo @wiki',
+                    'parsed_str' => '(W+:foo)AND(N+:wiki)',
+                    'parsed_ary' => [0 => 'W+:foo', 1 => 'N+:wiki', 2 => 'AND',],
+                    'words' => [0 => 'foo',],
+                    'highlight' => [0 => 'foo',],
+                    'and' => [0 => 'foo',],
+                    'ns' => [0 => 'wiki',],
+                    'phrases' => [],
+                    'notns' => [],
+                    'not' => [],
+                ],
+                ':wiki:foo',
+                'simple word limited to a namespace',
+            ],
+            [
+                [
+                    'query' => 'foo ^wiki',
+                    'parsed_str' => '(W+:foo)ANDNOT(N-:wiki)',
+                    'parsed_ary' => [0 => 'W+:foo', 1 => 'N-:wiki', 2 => 'NOT', 3 => 'AND',],
+                    'words' => [0 => 'foo',],
+                    'highlight' => [0 => 'foo',],
+                    'and' => [0 => 'foo',],
+                    'notns' => [0 => 'wiki',],
+                    'phrases' => [],
+                    'ns' => [],
+                    'not' => [],
+                ],
+                ':foo',
+                'simple word and excluding a namespace',
+            ],
+            [
+                [
+                    'query' => 'foo -bar',
+                    'parsed_str' => '(W+:foo)ANDNOT((W-:bar))',
+                    'parsed_ary' => [0 => 'W+:foo', 1 => 'W-:bar', 2 => 'NOT', 3 => 'AND',],
+                    'words' => [0 => 'foo', 1 => 'bar',],
+                    'highlight' => [0 => 'foo',],
+                    'and' => [0 => 'foo',],
+                    'not' => [0 => 'bar',],
+                    'phrases' => [],
+                    'ns' => [],
+                    'notns' => [],
+                ],
+                ':foo',
+                'one word but not the other',
+            ],
+            [
+                [
+                    'query' => 'wiki:foo',
+                    'parsed_str' => '((W+:wiki)AND(W+:foo))',
+                    'parsed_ary' => [0 => 'W+:wiki', 1 => 'W+:foo', 2 => 'AND',],
+                    'words' => [0 => 'wiki', 1 => 'foo',],
+                    'highlight' => [0 => 'wiki', 1 => 'foo',],
+                    'and' => [0 => 'wiki', 1 => 'foo',],
+                    'phrases' => [],
+                    'ns' => [],
+                    'notns' => [],
+                    'not' => [],
+                ],
+                ':wiki:foo',
+                'pageid with colons should result in that pageid',
+            ],
+            [
+                [
+                    'query' => '"wiki:foo"',
+                    'parsed_str' => '((W_:wiki)AND(W_:foo)AND(P+:wiki:foo))',
+                    'parsed_ary' => [0 => 'W_:wiki', 1 => 'W_:foo', 2 => 'AND', 3 => 'P+:wiki:foo', 4 => 'AND',],
+                    'words' => [0 => 'wiki', 1 => 'foo',],
+                    'phrases' => [0 => 'wiki:foo',],
+                    'highlight' => [0 => 'wiki:foo',],
+                    'ns' => [],
+                    'notns' => [],
+                    'and' => [],
+                    'not' => [],
+                ],
+                ':wiki:foo',
+                'pageid with colons and wrapped in double quotes should result in that pageid as well',
+            ],
+        ];
+    }
+
+    /**
+     * @dataProvider dataProvider
+     *
+     * @param $inputParsedQuery
+     * @param $expectedPageName
+     * @param $msg
+     */
+    function test_simpleshort($inputParsedQuery, $expectedPageName, $msg)
+    {
+        $search = new \dokuwiki\Ui\Search([], [], []);
+
+        $actualPageName = $search->createPagenameFromQuery($inputParsedQuery);
+
+        $this->assertEquals($expectedPageName, $actualPageName, $msg);
+    }
+
+}
+
+
diff --git a/inc/Ui/Search.php b/inc/Ui/Search.php
index 3e40b835d..419b967d7 100644
--- a/inc/Ui/Search.php
+++ b/inc/Ui/Search.php
@@ -496,11 +496,15 @@ class Search extends Ui
      *
      * @return string pagename constructed from the parsed query
      */
-    protected function createPagenameFromQuery($parsedQuery)
+    public function createPagenameFromQuery($parsedQuery)
     {
+        $cleanedQuery = cleanID($parsedQuery['query']);
+        if ($cleanedQuery === $parsedQuery['query']) {
+            return ':' . $cleanedQuery;
+        }
         $pagename = '';
         if (!empty($parsedQuery['ns'])) {
-            $pagename .= cleanID($parsedQuery['ns'][0]);
+            $pagename .= ':' . cleanID($parsedQuery['ns'][0]);
         }
         $pagename .= ':' . cleanID(implode(' ' , $parsedQuery['highlight']));
         return $pagename;
-- 
GitLab