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_map(function ($tag) use ($hlp) { 60 return $hlp->cleanTag($tag); 61 }, array_keys($tags)); 62 } 63 64 /** 65 * Add configuration for tagging filter in advanced search 66 * when using Elasticsearch plugin 67 * 68 * @param Doku_Event $event 69 */ 70 public function elasticSearchFilter(Doku_Event $event) 71 { 72 $event->data['tagging'] = [ 73 'label' => $this->getLang('search_filter_label'), 74 'id' => 'plugin__tagging-tags', 75 'fieldPath' => 'tagging', 76 'limit' => '100', 77 ]; 78 } 79 80 /** 81 * Remove tags from query string and put them into $INPUT 82 * to be used as filter by Elasticsearch. 83 * Also return new #tag values to be appended to the query. 84 * 85 * @param Doku_Event $event 86 */ 87 public function setupTagSearchElastic(Doku_Event $event) 88 { 89 global $QUERY; 90 global $INPUT; 91 92 /** @var helper_plugin_tagging $hlp */ 93 $hlp = plugin_load('helper', 'tagging'); 94 95 $taggingFilter = $INPUT->arr('tagging'); 96 97 // get (hash)tags from query 98 preg_match_all('/(?:#)(\w+)/u', $QUERY, $matches); 99 if (isset($matches[1])) { 100 $matches[1] = array_map([$hlp, 'cleanTag'], $matches[1]); 101 $INPUT->set('tagging', array_merge($matches[1], $taggingFilter)); 102 } 103 \action_plugin_tagging_search::removeTagsFromQuery($QUERY); 104 105 // return tagging filter as hashtags to be appended to the original query (without doubles) 106 if ($taggingFilter) { 107 $additions = array_map(function ($tag) use ($matches) { 108 if (!isset($matches[1]) || !in_array($tag, $matches[1])) { 109 return "#$tag"; 110 } 111 return null; 112 }, $taggingFilter); 113 $event->data += array_filter($additions); 114 } 115 } 116 117 /** 118 * Add tagging to the list of search fields 119 * 120 * @param Doku_Event $event 121 */ 122 public function elasticSearchFields(Doku_Event $event) 123 { 124 array_push($event->data, 'tagging'); 125 } 126} 127