tiki-searchindex.php 6.47 KB
Newer Older
1
<?php
changi67's avatar
changi67 committed
2 3 4
/**
 * @package tikiwiki
 */
5
// (c) Copyright 2002-2016 by authors of the Tiki Wiki CMS Groupware Project
6
//
7 8
// All Rights Reserved. See copyright.txt for details and a complete list of authors.
// Licensed under the GNU LESSER GENERAL PUBLIC LICENSE. See license.txt for details.
changi67's avatar
changi67 committed
9 10
// $Id$

rjsmelo's avatar
rjsmelo committed
11 12 13 14 15 16 17 18 19 20
$inputConfiguration = [
  [ 'staticKeyFilters' => [
	'date' => 'digits',
	'maxRecords' => 'digits',
	'highlight' => 'text',
	'where' => 'text',
	'find' => 'text',
	'searchLang' => 'word',
	'words' => 'text',
	'boolean' => 'word',
21
	'storeAs' => 'int',
rjsmelo's avatar
rjsmelo committed
22 23 24
	]
  ]
];
25

26
$section = 'search';
rjsmelo's avatar
rjsmelo committed
27
require_once('tiki-setup.php');
28 29
$access->check_feature('feature_search');
$access->check_permission('tiki_p_search');
30

31
//get_strings tra("Searchindex")
32 33
//ini_set('display_errors', true);
//error_reporting(E_ALL);
34

rjsmelo's avatar
rjsmelo committed
35 36
foreach (['find', 'highlight', 'where'] as $possibleKey) {
	if (empty($_REQUEST['filter']) && ! empty($_REQUEST[$possibleKey])) {
37 38
		$_REQUEST['filter']['content'] = $_REQUEST[$possibleKey];
	}
39
}
rjsmelo's avatar
rjsmelo committed
40 41 42
$filter = isset($_REQUEST['filter']) ? $_REQUEST['filter'] : [];
$postfilter = isset($_REQUEST['postfilter']) ? $_REQUEST['postfilter'] : [];
$facets = [];
43

44
if (count($filter) || count($postfilter)) {
45 46 47
	if (isset($_REQUEST['save_query'])) {
		$_SESSION['quick_search'][(int) $_REQUEST['save_query']] = $_REQUEST;
	}
48
	$offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : 0;
rjsmelo's avatar
rjsmelo committed
49
	$maxRecords = empty($_REQUEST['maxRecords']) ? $prefs['maxRecords'] : $_REQUEST['maxRecords'];
50

51
	if ($access->is_serializable_request(true)) {
52
		$jitRequest->replaceFilter('fields', 'word');
rjsmelo's avatar
rjsmelo committed
53 54
		$fetchFields = array_merge(['title', 'modification_date', 'url'], $jitRequest->asArray('fields', ','));
		;
55

56
		$results = tiki_searchindex_get_results($filter, $postfilter, $offset, $maxRecords);
57

58 59
		$smarty->loadPlugin('smarty_function_object_link');
		$smarty->loadPlugin('smarty_modifier_sefurl');
60
		foreach ($results as &$res) {
61 62 63 64 65
			foreach ($fetchFields as $f) {
				if (isset($res[$f])) {
					$res[$f]; // Dynamic load if applicable
				}
			}
66
			$res['link'] = smarty_function_object_link(
rjsmelo's avatar
rjsmelo committed
67
				[
68 69 70
					'type' => $res['object_type'],
					'id' => $res['object_id'],
					'title' => $res['title'],
rjsmelo's avatar
rjsmelo committed
71
				],
72
				$smarty
73
			);
changi67's avatar
changi67 committed
74 75 76
			$res = array_filter(
				$res,
				function ($v) {
rjsmelo's avatar
rjsmelo committed
77
					return ! is_null($v);
changi67's avatar
changi67 committed
78 79
				}
			);	// strip out null values
80
		}
81
		$access->output_serialized(
82
			$results,
rjsmelo's avatar
rjsmelo committed
83
			[
nkoth's avatar
nkoth committed
84
				'feedTitle' => tr('%0: Results for "%1"', $prefs['sitetitle'], isset($filter['content']) ? $filter['content'] : ''),
85 86 87 88
				'feedDescription' => tr('Search Results'),
				'entryTitleKey' => 'title',
				'entryUrlKey' => 'url',
				'entryModificationKey' => 'modification_date',
rjsmelo's avatar
rjsmelo committed
89 90
				'entryObjectDescriptors' => ['object_type', 'object_id'],
			]
91
		);
92 93
		exit;
	} else {
94 95
		$cachelib = TikiLib::lib('cache');
		$cacheType = 'search';
rjsmelo's avatar
rjsmelo committed
96
		$cacheName = $user . '/' . $offset . '/' . $maxRecords . '/' . serialize($filter);
97
		$isCached = false;
rjsmelo's avatar
rjsmelo committed
98
		if (! empty($prefs['unified_user_cache']) && $cachelib->isCached($cacheName, $cacheType)) {
99 100 101 102 103
			list($date, $html) = $cachelib->getSerialized($cacheName, $cacheType);
			if ($date > $tikilib->now - $prefs['unified_user_cache'] * 60) {
				$isCached = true;
			}
		}
rjsmelo's avatar
rjsmelo committed
104
		if (! $isCached) {
105
			$results = tiki_searchindex_get_results($filter, $postfilter, $offset, $maxRecords);
changi67's avatar
changi67 committed
106 107 108
			$facets = array_map(
				function ($facet) {
					return $facet->getName();
rjsmelo's avatar
rjsmelo committed
109 110
				},
				$results->getFacets()
changi67's avatar
changi67 committed
111
			);
112

113
			$plugin = new Search_Formatter_Plugin_SmartyTemplate('searchresults-plain.tpl');
114
			$plugin->setData(
rjsmelo's avatar
rjsmelo committed
115
				[
116
					'prefs' => $prefs,
rjsmelo's avatar
rjsmelo committed
117
				]
118
			);
rjsmelo's avatar
rjsmelo committed
119
			$fields = [
120 121 122 123
				'title' => null,
				'url' => null,
				'modification_date' => null,
				'highlight' => null,
rjsmelo's avatar
rjsmelo committed
124
			];
125 126 127 128
			if ($prefs['feature_search_show_visit_count'] === 'y') {
				$fields['visits'] = null;
			}
			$plugin->setFields($fields);
129

130
			$formatter = Search_Formatter_Factory::newFormatter($plugin);
131

132
			$wiki = $formatter->format($results);
133
			$html = TikiLib::lib('parser')->parse_data(
134
				$wiki,
rjsmelo's avatar
rjsmelo committed
135
				[
136
					'is_html' => true,
rjsmelo's avatar
rjsmelo committed
137
				]
138
			);
rjsmelo's avatar
rjsmelo committed
139 140
			if (! empty($prefs['unified_user_cache'])) {
				$cachelib->cacheItem($cacheName, serialize([$tikilib->now, $html]), $cacheType);
141 142 143
			}
		}
		$smarty->assign('results', $html);
144
	}
145
}
146

147
$smarty->assign('filter', $filter);
148
$smarty->assign('postfilter', $postfilter);
149
$smarty->assign('facets', $facets);
150

151 152
// disallow robots to index page:
$smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
153

154
if ($prefs['search_use_facets'] == 'y' && $prefs['unified_engine'] === 'elastic') {
155 156 157 158
	$smarty->display("tiki-searchfacets.tpl");
} else {
	$smarty->display("tiki-searchindex.tpl");
}
159

160 161 162 163 164 165
/**
 * @param $filter
 * @param $offset
 * @param $maxRecords
 * @return mixed
 */
166
function tiki_searchindex_get_results($filter, $postfilter, $offset, $maxRecords)
167
{
168
	global $prefs;
changi67's avatar
changi67 committed
169

170
	$unifiedsearchlib = TikiLib::lib('unifiedsearch');
171

172 173 174
	$query = new Search_Query;
	$unifiedsearchlib->initQueryBase($query);
	$query = $unifiedsearchlib->buildQuery($filter, $query);
175
	$query->filterContent('y', 'searchable');
176

177 178 179 180
	if (count($postfilter)) {
		$unifiedsearchlib->buildQuery($postfilter, $query->getPostFilter());
	}

181 182 183 184
	if (isset($_REQUEST['sort_mode']) && $order = Search_Query_Order::parse($_REQUEST['sort_mode'])) {
		$query->setOrder($order);
	}

185 186 187
	if ($prefs['storedsearch_enabled'] == 'y' && ! empty($_POST['storeAs'])) {
		$storedsearch = TikiLib::lib('storedsearch');
		$storedsearch->storeUserQuery($_POST['storeAs'], $query);
188
		TikiLib::lib('smarty')->assign('display_msg', tr('Your query was stored.'));
189 190 191 192 193 194
	}

	$unifiedsearchlib->initQueryPermissions($query);

	$query->setRange($offset, $maxRecords);

195 196 197 198 199 200 201
	if ($prefs['feature_search_stats'] == 'y') {
		$stats = TikiLib::lib('searchstats');
		foreach ($query->getTerms() as $term) {
			$stats->register_term_hit($term);
		}
	}

202 203 204 205 206 207 208
	if ($prefs['search_use_facets'] == 'y') {
		$provider = $unifiedsearchlib->getFacetProvider();

		foreach ($provider->getFacets() as $facet) {
			$query->requestFacet($facet);
		}
	}
209

210 211 212 213 214 215 216 217 218

	if ($prefs['unified_highlight_results'] === 'y') {
		$query->applyTransform(
			new \Search\ResultSet\UrlHighlightTermsTransform(
				$query->getTerms()
			)
		);
	}

219
	try {
220 221 222 223 224
		if ($prefs['federated_enabled'] == 'y' && ! empty($filter['content'])) {
			$fed = TikiLib::lib('federatedsearch');
			$fed->augmentSimpleQuery($query, $filter['content']);
		}

225 226 227
		$resultset = $query->search($unifiedsearchlib->getIndex());

		return $resultset;
228
	} catch (Search_Elastic_TransportException $e) {
229
		Feedback::error(tr('Search functionality currently unavailable.'), 'session');
230
	} catch (Exception $e) {
231
		Feedback::error($e->getMessage(), 'session');
232 233
	}

rjsmelo's avatar
rjsmelo committed
234
	return new Search_ResultSet([], 0, 0, -1);
235
}