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