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