Hello again @texnixe! With Kirby 3 around the corner I’m curious if a revised search has made it in. Let me know, thanks!
I have the same problem with Kirby 3.
While I could modify the source code at /kirby/src/Cms/Search.php#L43 and change it to $searchwords = array($searchwords)
, I wonder if there’s a more future-proof way.
Can I somehow overwrite the core function like @lukasbestle did for Kirby 2?
To be honest I am wondering why the “each word separately” approach is used at all. It’s not what users expect and it’s more performance-intensive.
@thguenther, I am currently porting an existing project to K3 and I have reused this succesfully:
// site/plugins/mysearch/index.php
/**
* Fork of the native $pages->search() method
* Only searches for full matches
*/
function search($collection, $query, $params = array()) {
if(is_string($params)) {
$params = array('fields' => str::split($params, '|'));
}
$defaults = array(
'minlength' => 2,
'fields' => array(),
'words' => false,
'score' => array()
);
$options = array_merge($defaults, $params);
if(empty($query)) return $collection->limit(0);
$results = $collection->filter(function($page) use($query, $options) {
$data = $page->content()->toArray();
$keys = array_keys($data);
if(!empty($options['fields'])) {
$keys = array_intersect($keys, $options['fields']);
}
$page->searchHits = 0;
$page->searchScore = 0;
foreach($keys as $key) {
$score = a::get($options['score'], $key, 1);
// check for full matches
if($matches = preg_match_all('!' . preg_quote($query) . '!i', $data[$key], $r)) {
$page->searchHits += $matches;
$page->searchScore += $matches * $score;
}
}
return $page->searchHits > 0 ? true : false;
});
$results = $results->sortBy('searchScore', SORT_DESC);
return $results;
}
It’s not a $pages
-method, but afaik does the job as separate search($pages, $query, $options)
function. If you’ld like you could easily turn it into one via plugin options…
Thank You for Your solution for Kirby 3!
Could not figure out what I should adjust to search for exact multiple words (not each individual word) for entire $site and not $page.
Currently using (default) search this way: $searchResults = $site->index()->listed()->search('some search input');
Hey @Bristolscript ,
The code above has no $pages method, which might be confusing.
With the code above, you should be able to use it as follows:
$searchResults = search($site->index()->listed(), 'some search input');
Thank You! It’s working. Previously forgot to add in plugin index.php file: <?php
Is it possible to do that within Kirby 3.9 now without a plugin?