Search for files

I tried to implement a custom files methods only to realize that files methods only work with $page->files() files objects, while $pages->files() returns a collection object. However, you could use the following function, which is a simple port of the pages` search function:

function search($files, $query, $params = []) {

  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);
  $collection  = clone $files;
  $searchwords = preg_replace('/(\s)/u',',', $query);
  $searchwords = str::split($searchwords, ',', $options['minlength']);

  if(!empty($options['stopwords'])) {
    $searchwords = array_diff($searchwords, $options['stopwords']);
  }

  if(empty($searchwords)) return $collection->limit(0);

  $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($file) use($query, $searchwords, $preg, $options) {

    $data = $file->meta()->toArray();
    $keys = array_keys($data);

    if(!empty($options['fields'])) {
      $keys = array_intersect($keys, $options['fields']);
    }

    $file->searchHits  = 0;
    $file->searchScore = 0;

    foreach($keys as $key) {

      $score = a::get($options['score'], $key, 1);

      // check for a match
      if($matches = preg_match_all($preg, $data[$key], $r)) {

        $file->searchHits  += $matches;
        $file->searchScore += $matches * $score;

        // check for full matches
        if($matches = preg_match_all('!' . preg_quote($query) . '!i', $data[$key], $r)) {
          $file->searchScore += $matches * $score;
        }

      }

    }

    return $file->searchHits > 0 ? true : false;

  });

  $results = $results->sortBy('searchScore', SORT_DESC);

  return $results;

}

Usage:

$query = get('q');
$files = $pages->files();
$results = search($files, $query);