xref: /plugin/tagging/action/elasticsearch.php (revision df43a7be9125b55733c41a4f1a13770bf4033169)
14a5f6748SAnna Dabrowska<?php
24a5f6748SAnna Dabrowska
3*df43a7beSAndreas Gohruse dokuwiki\Extension\ActionPlugin;
4*df43a7beSAndreas Gohruse dokuwiki\Extension\EventHandler;
5*df43a7beSAndreas Gohruse dokuwiki\Extension\Event;
6*df43a7beSAndreas Gohr
74a5f6748SAnna Dabrowska/**
84a5f6748SAnna Dabrowska * Class action_plugin_tagging_elasticsearch
94a5f6748SAnna Dabrowska */
10*df43a7beSAndreas Gohrclass action_plugin_tagging_elasticsearch extends ActionPlugin
114a5f6748SAnna Dabrowska{
12*df43a7beSAndreas Gohr    public function register(EventHandler $controller)
134a5f6748SAnna Dabrowska    {
144a5f6748SAnna Dabrowska        $controller->register_hook(
15*df43a7beSAndreas Gohr            'PLUGIN_ELASTICSEARCH_CREATEMAPPING',
16*df43a7beSAndreas Gohr            'BEFORE',
17*df43a7beSAndreas Gohr            $this,
184a5f6748SAnna Dabrowska            'elasticMapping'
194a5f6748SAnna Dabrowska        );
204a5f6748SAnna Dabrowska
214a5f6748SAnna Dabrowska        $controller->register_hook(
22*df43a7beSAndreas Gohr            'PLUGIN_ELASTICSEARCH_INDEXPAGE',
23*df43a7beSAndreas Gohr            'BEFORE',
24*df43a7beSAndreas Gohr            $this,
254a5f6748SAnna Dabrowska            'elasticIndexPage'
264a5f6748SAnna Dabrowska        );
274a5f6748SAnna Dabrowska
284a5f6748SAnna Dabrowska        $controller->register_hook(
29*df43a7beSAndreas Gohr            'PLUGIN_ELASTICSEARCH_FILTERS',
30*df43a7beSAndreas Gohr            'BEFORE',
31*df43a7beSAndreas Gohr            $this,
324a5f6748SAnna Dabrowska            'elasticSearchFilter'
334a5f6748SAnna Dabrowska        );
344a5f6748SAnna Dabrowska
354a5f6748SAnna Dabrowska        $controller->register_hook(
36*df43a7beSAndreas Gohr            'PLUGIN_ELASTICSEARCH_SEARCHFIELDS',
37*df43a7beSAndreas Gohr            'BEFORE',
38*df43a7beSAndreas Gohr            $this,
394a5f6748SAnna Dabrowska            'elasticSearchFields'
404a5f6748SAnna Dabrowska        );
414a5f6748SAnna Dabrowska
424a5f6748SAnna Dabrowska        $controller->register_hook(
43*df43a7beSAndreas Gohr            'PLUGIN_ELASTICSEARCH_QUERY',
44*df43a7beSAndreas Gohr            'BEFORE',
45*df43a7beSAndreas Gohr            $this,
464a5f6748SAnna Dabrowska            'setupTagSearchElastic'
474a5f6748SAnna Dabrowska        );
484a5f6748SAnna Dabrowska    }
494a5f6748SAnna Dabrowska    /**
504a5f6748SAnna Dabrowska     * Add our own field mapping to Elasticsearch
514a5f6748SAnna Dabrowska     *
52*df43a7beSAndreas Gohr     * @param Event $event
534a5f6748SAnna Dabrowska     */
54*df43a7beSAndreas Gohr    public function elasticMapping(Event $event)
554a5f6748SAnna Dabrowska    {
564a5f6748SAnna Dabrowska        $event->data[] = ['tagging' => ['type' => 'keyword']];
574a5f6748SAnna Dabrowska    }
584a5f6748SAnna Dabrowska
594a5f6748SAnna Dabrowska    /**
604a5f6748SAnna Dabrowska     * Add taggings to Elastic index
614a5f6748SAnna Dabrowska     *
62*df43a7beSAndreas Gohr     * @param Event $event
634a5f6748SAnna Dabrowska     */
64*df43a7beSAndreas Gohr    public function elasticIndexPage(Event $event)
654a5f6748SAnna Dabrowska    {
664a5f6748SAnna Dabrowska        $data = &$event->data;
674a5f6748SAnna Dabrowska
684a5f6748SAnna Dabrowska        /** @var helper_plugin_tagging $hlp */
694a5f6748SAnna Dabrowska        $hlp = plugin_load('helper', 'tagging');
704a5f6748SAnna Dabrowska        $tags = $hlp->findItems(['pid' => $data['uri']], 'tag');
714a5f6748SAnna Dabrowska
72*df43a7beSAndreas Gohr        $data['tagging'] = array_map(fn($tag) => $hlp->cleanTag($tag), array_keys($tags));
734a5f6748SAnna Dabrowska    }
744a5f6748SAnna Dabrowska
754a5f6748SAnna Dabrowska    /**
764a5f6748SAnna Dabrowska     * Add configuration for tagging filter in advanced search
774a5f6748SAnna Dabrowska     * when using Elasticsearch plugin
784a5f6748SAnna Dabrowska     *
79*df43a7beSAndreas Gohr     * @param Event $event
804a5f6748SAnna Dabrowska     */
81*df43a7beSAndreas Gohr    public function elasticSearchFilter(Event $event)
824a5f6748SAnna Dabrowska    {
834a5f6748SAnna Dabrowska        $event->data['tagging'] = [
844a5f6748SAnna Dabrowska            'label' => $this->getLang('search_filter_label'),
85ff8dbe20SAndreas Gohr            'prefix' => '#',
864ef6a59aSAnna Dabrowska            'id' => 'plugin__tagging-tags',
874a5f6748SAnna Dabrowska            'fieldPath' => 'tagging',
884a5f6748SAnna Dabrowska            'limit' => '100',
894a5f6748SAnna Dabrowska        ];
904a5f6748SAnna Dabrowska    }
914a5f6748SAnna Dabrowska
924a5f6748SAnna Dabrowska    /**
934a5f6748SAnna Dabrowska     * Remove tags from query string and put them into $INPUT
944a5f6748SAnna Dabrowska     * to be used as filter by Elasticsearch.
954a5f6748SAnna Dabrowska     * Also return new #tag values to be appended to the query.
964a5f6748SAnna Dabrowska     *
97*df43a7beSAndreas Gohr     * @param Event $event
984a5f6748SAnna Dabrowska     */
99*df43a7beSAndreas Gohr    public function setupTagSearchElastic(Event $event)
1004a5f6748SAnna Dabrowska    {
1014a5f6748SAnna Dabrowska        global $QUERY;
1024a5f6748SAnna Dabrowska        global $INPUT;
1034a5f6748SAnna Dabrowska
104454c07f2SAnna Dabrowska        /** @var helper_plugin_tagging $hlp */
105454c07f2SAnna Dabrowska        $hlp = plugin_load('helper', 'tagging');
106454c07f2SAnna Dabrowska
1074a5f6748SAnna Dabrowska        $taggingFilter = $INPUT->arr('tagging');
1084a5f6748SAnna Dabrowska
1094a5f6748SAnna Dabrowska        // get (hash)tags from query
1104a5f6748SAnna Dabrowska        preg_match_all('/(?:#)(\w+)/u', $QUERY, $matches);
1114a5f6748SAnna Dabrowska        if (isset($matches[1])) {
112454c07f2SAnna Dabrowska            $matches[1] = array_map([$hlp, 'cleanTag'], $matches[1]);
1134a5f6748SAnna Dabrowska            $INPUT->set('tagging', array_merge($matches[1], $taggingFilter));
1144a5f6748SAnna Dabrowska        }
115*df43a7beSAndreas Gohr        action_plugin_tagging_search::removeTagsFromQuery($QUERY);
1164a5f6748SAnna Dabrowska
1174a5f6748SAnna Dabrowska        // return tagging filter as hashtags to be appended to the original query (without doubles)
1184a5f6748SAnna Dabrowska        if ($taggingFilter) {
1194a5f6748SAnna Dabrowska            $additions = array_map(function ($tag) use ($matches) {
1204a5f6748SAnna Dabrowska                if (!isset($matches[1]) || !in_array($tag, $matches[1])) {
1214a5f6748SAnna Dabrowska                    return "#$tag";
1224a5f6748SAnna Dabrowska                }
1234a5f6748SAnna Dabrowska                return null;
1244a5f6748SAnna Dabrowska            }, $taggingFilter);
1254a5f6748SAnna Dabrowska            $event->data += array_filter($additions);
1264a5f6748SAnna Dabrowska        }
1274a5f6748SAnna Dabrowska    }
1284a5f6748SAnna Dabrowska
1294a5f6748SAnna Dabrowska    /**
1304a5f6748SAnna Dabrowska     * Add tagging to the list of search fields
1314a5f6748SAnna Dabrowska     *
132*df43a7beSAndreas Gohr     * @param Event $event
1334a5f6748SAnna Dabrowska     */
134*df43a7beSAndreas Gohr    public function elasticSearchFields(Event $event)
1354a5f6748SAnna Dabrowska    {
136*df43a7beSAndreas Gohr        $event->data[] = 'tagging';
1374a5f6748SAnna Dabrowska    }
1384a5f6748SAnna Dabrowska}
139