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