You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

315 lines
10 KiB

<?php
/**
* @package tikiwiki
*/
// (c) Copyright by authors of the Tiki Wiki CMS Groupware Project
//
// 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.
// $Id$
$inputConfiguration = [
[ 'staticKeyFilters' => [
'date' => 'digits',
'maxRecords' => 'digits',
'highlight' => 'text',
'where' => 'text',
'find' => 'text',
'searchLang' => 'word',
'words' => 'text',
'boolean' => 'word',
'storeAs' => 'int',
]
]
];
$section = 'search';
require_once('tiki-setup.php');
$access->check_feature('feature_search');
$access->check_permission('tiki_p_search');
$smarty->assign('headtitle', tr('Search'));
//get_strings tra("Searchindex")
//ini_set('display_errors', true);
//error_reporting(E_ALL);
foreach (['find', 'highlight', 'where'] as $possibleKey) {
if (empty($_REQUEST['filter']['content']) && ! empty($_REQUEST[$possibleKey])) {
$_REQUEST['filter']['content'] = $_REQUEST[$possibleKey];
}
}
$filter = isset($_REQUEST['filter']) ? $_REQUEST['filter'] : [];
$postfilter = isset($_REQUEST['postfilter']) ? $_REQUEST['postfilter'] : [];
$facets = [];
if (count($filter) || count($postfilter)) {
if (isset($_REQUEST['save_query'])) {
$_SESSION['quick_search'][(int) $_REQUEST['save_query']] = $_REQUEST;
}
$offset = isset($_REQUEST['offset']) ? $_REQUEST['offset'] : 0;
$maxRecords = empty($_REQUEST['maxRecords']) ? $prefs['maxRecords'] : $_REQUEST['maxRecords'];
if ($access->is_serializable_request(true)) {
$jitRequest->replaceFilter('fields', 'word');
$fetchFields = array_merge(['title', 'modification_date', 'url'], $jitRequest->asArray('fields', ','));
;
$results = tiki_searchindex_get_results($filter, $postfilter, $offset, $maxRecords);
$smarty->loadPlugin('smarty_function_object_link');
$smarty->loadPlugin('smarty_modifier_sefurl');
foreach ($results as &$res) {
foreach ($fetchFields as $f) {
if (isset($res[$f])) {
$res[$f]; // Dynamic load if applicable
}
}
$res['link'] = smarty_function_object_link(
[
'type' => $res['object_type'],
'id' => $res['object_id'],
'title' => $res['title'],
],
$smarty->getEmptyInternalTemplate()
);
$res = array_filter(
$res,
function ($v) {
return ! is_null($v);
}
); // strip out null values
}
// add facet/aggregations to the serialised outout
if ($prefs['search_use_facets'] == 'y') {
$facets = array_map(
function ($facet) {
return $facet->getOptions();
},
$results->getFacets()
);
$resultArray = [
'count' => $results->count(),
'maxRecords' => $results->getMaxRecords(),
'offset' => $results->getOffset(),
'result' => (array) $results,
'facets' => $facets,
];
$results = $resultArray;
}
$access->output_serialized(
$results,
[
'feedTitle' => tr('%0: Results for "%1"', $prefs['sitetitle'], isset($filter['content']) ? $filter['content'] : ''),
'feedDescription' => tr('Search Results'),
'entryTitleKey' => 'title',
'entryUrlKey' => 'url',
'entryModificationKey' => 'modification_date',
'entryObjectDescriptors' => ['object_type', 'object_id'],
]
);
exit;
} else {
$cachelib = TikiLib::lib('cache');
$cacheType = 'search';
if (isset($_REQUEST['forumId'])) {
$filter['forum_id'] = $_REQUEST['forumId'];
}
$cacheName = $user . '/' . $offset . '/' . $maxRecords . '/' . serialize($filter);
$isCached = false;
if (! empty($prefs['unified_user_cache']) && $cachelib->isCached($cacheName, $cacheType)) {
list($date, $html) = $cachelib->getSerialized($cacheName, $cacheType);
if ($date > $tikilib->now - $prefs['unified_user_cache'] * 60) {
$isCached = true;
}
}
$excludedFacets = tiki_searchindex_get_excluded_facets();
if (! $isCached) {
$results = tiki_searchindex_get_results($filter, $postfilter, $offset, $maxRecords);
$facets = array_filter(array_map(
function ($facet) use ($excludedFacets) {
$name = $facet->getName();
if (! in_array($name, $excludedFacets)) {
return $name;
} else {
return '';
}
},
$results->getFacets()
));
$plugin = new Search_Formatter_Plugin_SmartyTemplate('searchresults-plain.tpl');
$plugin->setData(
[
'prefs' => $prefs,
]
);
$fields = [
'title' => null,
'url' => null,
'modification_date' => null,
'highlight' => null,
];
if ($prefs['feature_search_show_visit_count'] === 'y') {
$fields['visits'] = null;
}
$plugin->setFields($fields);
$formatter = Search_Formatter_Factory::newFormatter($plugin);
$wiki = $formatter->format($results);
$parserLib = TikiLib::lib('parser');
$wiki = $parserLib->searchFilePreview($wiki);
$html = $parserLib->parse_data(
$wiki,
[
'is_html' => true,
]
);
if (! empty($prefs['unified_user_cache'])) {
$cachelib->cacheItem($cacheName, serialize([$tikilib->now, $html]), $cacheType);
}
}
$smarty->assign('results', $html);
}
}
$smarty->assign('filter', $filter);
$smarty->assign('postfilter', $postfilter);
$smarty->assign('facets', $facets);
// disallow robots to index page:
$smarty->assign('metatag_robots', 'NOINDEX, NOFOLLOW');
if ($prefs['search_use_facets'] == 'y' && $prefs['unified_engine'] === 'elastic') {
$smarty->display("tiki-searchfacets.tpl");
} else {
$smarty->display("tiki-searchindex.tpl");
}
/**
* @param array $filter
* @param array $postfilter
* @param int $offset
* @param int $maxRecords
*
* @return Search_ResultSet
* @throws Exception
*/
function tiki_searchindex_get_results($filter, $postfilter, $offset, $maxRecords)
{
global $prefs;
$unifiedsearchlib = TikiLib::lib('unifiedsearch');
$query = new Search_Query();
$unifiedsearchlib->initQueryBase($query);
$query = $unifiedsearchlib->buildQuery($filter, $query);
$query->filterContent('y', 'searchable');
if (count($postfilter)) {
$unifiedsearchlib->buildQuery($postfilter, $query->getPostFilter());
}
if (isset($_REQUEST['sort_mode']) && $order = Search_Query_Order::parse($_REQUEST['sort_mode'])) {
$query->setOrder($order);
}
if ($prefs['storedsearch_enabled'] == 'y' && ! empty($_POST['storeAs'])) {
$storedsearch = TikiLib::lib('storedsearch');
$storedsearch->storeUserQuery($_POST['storeAs'], $query);
TikiLib::lib('smarty')->assign('display_msg', tr('Your query was stored.'));
}
$unifiedsearchlib->initQueryPermissions($query);
$query->setRange($offset, $maxRecords);
if ($prefs['feature_search_stats'] == 'y') {
$stats = TikiLib::lib('searchstats');
foreach ($query->getTerms() as $term) {
$stats->register_term_hit($term);
}
}
if ($prefs['search_use_facets'] == 'y') {
$provider = $unifiedsearchlib->getFacetProvider();
$facetLabels = [];
if ($prefs['search_avoid_duplicated_facet_labels'] === 'y') {
foreach ($provider->getFacets() as $facet) {
$facetLabels[] = $facet->getLabel();
}
}
$duplicateLabels = array_filter(
array_count_values($facetLabels),
function ($value) {
return $value > 1;
}
);
foreach ($provider->getFacets() as $facet) {
$name = $facet->getName();
if (! in_array($name, tiki_searchindex_get_excluded_facets())) {
if ($prefs['search_avoid_duplicated_facet_labels'] === 'y') {
$label = $facet->getLabel();
if (key_exists($label, $duplicateLabels)) {
// it's almost always tracker fields that are duplicated, so just them for now
if (strpos($name, 'tracker_field_') === 0) {
$field = TikiLib::lib('trk')->get_tracker_field(substr($name, 14));
$definition = \Tracker_Definition::get($field['trackerId']);
$facet->setLabel($label . ' (' . $definition->getConfiguration('name') . ')');
}
}
}
$query->requestFacet($facet);
}
}
}
if ($prefs['unified_highlight_results'] === 'y') {
$query->applyTransform(
new \Search\ResultSet\UrlHighlightTermsTransform(
$query->getTerms()
)
);
}
try {
if ($prefs['federated_enabled'] == 'y' && ! empty($filter['content'])) {
$fed = TikiLib::lib('federatedsearch');
$fed->augmentSimpleQuery($query, $filter['content']);
}
$resultset = $query->search($unifiedsearchlib->getIndex());
return $resultset;
} catch (Search_Elastic_TransportException $e) {
Feedback::error(tr('Search functionality currently unavailable.'));
} catch (Exception $e) {
Feedback::error($e->getMessage());
}
return new Search_ResultSet([], 0, 0, -1);
}
/**
* Temporarily exclude the two date range facets from tiki-searchindex.php as they don't work
*
* @return array
*/
function tiki_searchindex_get_excluded_facets()
{
global $prefs;
return array_merge(
$prefs['search_excluded_facets'],
[
'date_histogram',
'date_range',
]
);
}