1<?php 2/** 3 * DokuWiki Plugin elasticsearch (Action Component) 4 * 5 * @license GPL 2 http://www.gnu.org/licenses/gpl-2.0.html 6 * @author Andreas Gohr <gohr@cosmocode.de> 7 */ 8 9// must be run within Dokuwiki 10if(!defined('DOKU_INC')) die(); 11 12class action_plugin_elasticsearch_indexing extends DokuWiki_Action_Plugin { 13 14 /** 15 * Registers a callback function for a given event 16 * 17 * @param Doku_Event_Handler $controller DokuWiki's event controller object 18 * @return void 19 */ 20 public function register(Doku_Event_Handler &$controller) { 21 22 $controller->register_hook('ACTION_ACT_PREPROCESS', 'BEFORE', $this, 'handle_preprocess'); 23 $controller->register_hook('TPL_ACT_UNKNOWN', 'BEFORE', $this, 'handle_action'); 24 25 } 26 27 /** 28 * allow our custom do command 29 * 30 * @param Doku_Event $event 31 * @param $param 32 */ 33 public function handle_preprocess(Doku_Event &$event, $param) { 34 if($event->data != 'elasticsearch') return; 35 $event->preventDefault(); 36 $event->stopPropagation(); 37 } 38 39 /** 40 * do the actual search 41 * 42 * @param Doku_Event $event 43 * @param $param 44 */ 45 public function handle_action(Doku_Event &$event, $param) { 46 if($event->data != 'elasticsearch') return; 47 $event->preventDefault(); 48 $event->stopPropagation(); 49 global $QUERY; 50 51 /** @var helper_plugin_elasticsearch_client $hlp */ 52 $hlp = plugin_load('helper', 'elasticsearch_client'); 53 54 $client = $hlp->connect(); 55 $index = $client->getIndex($this->getConf('indexname')); 56 57 // define the query string 58 $qstring = new \Elastica\Query\QueryString(); 59 $qstring->setQuery($QUERY); 60 61 // create the actual search object 62 $equery = new \Elastica\Query(); 63 $equery->setQuery($qstring); 64 $equery->setHighlight( 65 array( 66 "pre_tags" => array('ELASTICSEARCH_MARKER_IN'), 67 "post_tags" => array('ELASTICSEARCH_MARKER_OUT'), 68 "fields" => array("content" => new \StdClass()) 69 ) 70 ); 71 72 $result = $index->search($equery); 73 $this->print_results($result); 74 } 75 76 /** 77 * Output the search results 78 * 79 * @fixme maybe add facets later? 80 * @param \Elastica\Result[] $results 81 */ 82 protected function print_results($results) { 83 global $lang; 84 global $QUERY; 85 86 // just reuse the standard search page intro: 87 $intro = p_locale_xhtml('searchpage'); 88 $intro = str_replace( 89 array('@QUERY@','@SEARCH@'), 90 array(hsc(rawurlencode($QUERY)),hsc($QUERY)), 91 $intro); 92 echo $intro; 93 flush(); 94 95 // output results 96 $found = 0; 97 echo '<dl class="search_results">'; 98 foreach($results as $row) { 99 /** @var Elastica\Result $row */ 100 101 $page = $row->getSource()['uri']; 102 if(!page_exists($page) || auth_quickaclcheck($page) < AUTH_READ) continue; 103 104 echo '<dt>'; 105 echo html_wikilink($page); 106 echo ': ' . $row->getScore(); 107 echo '</dt>'; 108 109 // snippets 110 echo '<dd>'; 111 echo str_replace( 112 array('ELASTICSEARCH_MARKER_IN', 'ELASTICSEARCH_MARKER_OUT'), 113 array('<strong class="search_hit">', '</strong>'), 114 hsc(join(' … ', (array) $row->getHighlights()['content'])) 115 ); 116 echo '</dd>'; 117 $found++; 118 } 119 if(!$found) { 120 echo '<dt>'.$lang['nothingfound'].'</dt>'; 121 } 122 echo '</dl>'; 123 } 124 125}