xref: /plugin/tagging/action/elasticsearch.php (revision 4ef6a59ad4d100f010e551cb15c1f068a3d0adbe)
1<?php
2
3/**
4 * Class action_plugin_tagging_elasticsearch
5 */
6class action_plugin_tagging_elasticsearch extends DokuWiki_Action_Plugin
7{
8
9    public function register(Doku_Event_Handler $controller)
10    {
11        $controller->register_hook(
12            'PLUGIN_ELASTICSEARCH_CREATEMAPPING', 'BEFORE', $this,
13            'elasticMapping'
14        );
15
16        $controller->register_hook(
17            'PLUGIN_ELASTICSEARCH_INDEXPAGE', 'BEFORE', $this,
18            'elasticIndexPage'
19        );
20
21        $controller->register_hook(
22            'PLUGIN_ELASTICSEARCH_FILTERS', 'BEFORE', $this,
23            'elasticSearchFilter'
24        );
25
26        $controller->register_hook(
27            'PLUGIN_ELASTICSEARCH_SEARCHFIELDS', 'BEFORE', $this,
28            'elasticSearchFields'
29        );
30
31        $controller->register_hook(
32            'PLUGIN_ELASTICSEARCH_QUERY', 'BEFORE', $this,
33            'setupTagSearchElastic'
34        );
35    }
36    /**
37     * Add our own field mapping to Elasticsearch
38     *
39     * @param Doku_Event $event
40     */
41    public function elasticMapping(Doku_Event $event)
42    {
43        $event->data[] = ['tagging' => ['type' => 'keyword']];
44    }
45
46    /**
47     * Add taggings to Elastic index
48     *
49     * @param Doku_Event $event
50     */
51    public function elasticIndexPage(Doku_Event $event)
52    {
53        $data = &$event->data;
54
55        /** @var helper_plugin_tagging $hlp */
56        $hlp = plugin_load('helper', 'tagging');
57        $tags = $hlp->findItems(['pid' => $data['uri']], 'tag');
58
59        $data['tagging'] = array_keys($tags);
60    }
61
62    /**
63     * Add configuration for tagging filter in advanced search
64     * when using Elasticsearch plugin
65     *
66     * @param Doku_Event $event
67     */
68    public function elasticSearchFilter(Doku_Event $event)
69    {
70        $event->data['tagging'] = [
71            'label' => $this->getLang('search_filter_label'),
72            'id' => 'plugin__tagging-tags',
73            'fieldPath' => 'tagging',
74            'limit' => '100',
75        ];
76    }
77
78    /**
79     * Remove tags from query string and put them into $INPUT
80     * to be used as filter by Elasticsearch.
81     * Also return new #tag values to be appended to the query.
82     *
83     * @param Doku_Event $event
84     */
85    public function setupTagSearchElastic(Doku_Event $event)
86    {
87        global $QUERY;
88        global $INPUT;
89
90        $taggingFilter = $INPUT->arr('tagging');
91
92        // get (hash)tags from query
93        preg_match_all('/(?:#)(\w+)/u', $QUERY, $matches);
94        if (isset($matches[1])) {
95            $INPUT->set('tagging', array_merge($matches[1], $taggingFilter));
96        }
97        \action_plugin_tagging_search::removeTagsFromQuery($QUERY);
98
99        // return tagging filter as hashtags to be appended to the original query (without doubles)
100        if ($taggingFilter) {
101            $additions = array_map(function ($tag) use ($matches) {
102                if (!isset($matches[1]) || !in_array($tag, $matches[1])) {
103                    return "#$tag";
104                }
105                return null;
106            }, $taggingFilter);
107            $event->data += array_filter($additions);
108        }
109    }
110
111    /**
112     * Add tagging to the list of search fields
113     *
114     * @param Doku_Event $event
115     */
116    public function elasticSearchFields(Doku_Event $event)
117    {
118        array_push($event->data, 'tagging');
119    }
120}
121