site()->index()->files()->search($query, $params); } /** * Native search method to search for anything within the collection */ public static function collection(Collection $collection, string $query = null, $params = []) { if (empty(trim($query)) === true) { return $collection->limit(0); } if (is_string($params) === true) { $params = ['fields' => Str::split($params, '|')]; } $defaults = [ 'fields' => [], 'minlength' => 2, 'score' => [], 'words' => false, ]; $options = array_merge($defaults, $params); $collection = clone $collection; $searchwords = preg_replace('/(\s)/u', ',', $query); $searchwords = Str::split($searchwords, ',', $options['minlength']); $lowerQuery = strtolower($query); if (empty($options['stopwords']) === false) { $searchwords = array_diff($searchwords, $options['stopwords']); } $searchwords = array_map(function ($value) use ($options) { return $options['words'] ? '\b' . preg_quote($value) . '\b' : preg_quote($value); }, $searchwords); $preg = '!(' . implode('|', $searchwords) . ')!i'; $results = $collection->filter(function ($item) use ($query, $preg, $options, $lowerQuery) { $data = $item->content()->toArray(); $keys = array_keys($data); $keys[] = 'id'; if (is_a($item, User::class) === true) { $keys[] = 'email'; $keys[] = 'role'; } elseif (is_a($item, Page::class) === true) { // apply the default score for pages $options['score'] = array_merge([ 'id' => 64, 'title' => 64, ], $options['score']); } if (empty($options['fields']) === false) { $keys = array_intersect($keys, $options['fields']); } $item->searchHits = 0; $item->searchScore = 0; foreach ($keys as $key) { $score = $options['score'][$key] ?? 1; $value = $data[$key] ?? (string)$item->$key(); $lowerValue = strtolower($value); // check for exact matches if ($lowerQuery == $lowerValue) { $item->searchScore += 16 * $score; $item->searchHits += 1; // check for exact beginning matches } elseif (Str::startsWith($lowerValue, $lowerQuery) === true) { $item->searchScore += 8 * $score; $item->searchHits += 1; // check for exact query matches } elseif ($matches = preg_match_all('!' . preg_quote($query) . '!i', $value, $r)) { $item->searchScore += 2 * $score; $item->searchHits += $matches; } // check for any match if ($matches = preg_match_all($preg, $value, $r)) { $item->searchHits += $matches; $item->searchScore += $matches * $score; } } return $item->searchHits > 0 ? true : false; }); return $results->sortBy('searchScore', 'desc'); } public static function pages(string $query = null, $params = []) { return App::instance()->site()->index()->search($query, $params); } public static function users(string $query = null, $params = []) { return App::instance()->users()->search($query, $params); } }