You are here

function search_api_saved_search_fetch_search_results in Search API Saved Searches 7

Fetches the results for a given search object.

Parameters

SearchApiSavedSearch $search: The saved search to check for new results.

Return value

array An associative array with the following keys:

  • search: The executed search.
  • result_count: The number of new results.
  • results: The IDs of the new results.

Throws

SearchApiException If an error occurred in the search.

2 calls to search_api_saved_search_fetch_search_results()
search_api_saved_searches_check_updates in ./search_api_saved_searches.module
Checks for new results for saved searches, and sends a mail if necessary.
search_api_saved_searches_rules_get_saved_search_new_items in ./search_api_saved_searches.rules.inc
Callback: Implements the "Fetch the new results for a search" rules action.

File

./search_api_saved_searches.module, line 1345
Offers the ability to save searches and be notified of new results.

Code

function search_api_saved_search_fetch_search_results(SearchApiSavedSearch $search) {
  $return = array(
    'search' => $search,
    'result_count' => 0,
    'results' => array(),
  );
  $settings = $search
    ->settings();
  try {

    // Make sure we run the query as the user who owns the saved search.
    // Otherwise node access will not work properly.
    $search->query['options']['search_api_access_account'] = $search->uid;

    // Get actual results for the query.
    $query = $search
      ->query();

    // If a date field is set, use that to filter results.
    if (!empty($settings->options['date_field'])) {
      $query
        ->condition($settings->options['date_field'], $search->last_execute, '>');
    }
    $response = $query
      ->execute();
    if (!empty($response['results'])) {
      $old = array();
      $new = $results = drupal_map_assoc(array_keys($response['results']));
      if (empty($settings->options['date_field'])) {

        // ID-based method: Compare these results to the old ones.
        $old = drupal_map_assoc(explode(',', $search->results));
        $new = array_diff_key($results, $old);
      }
      if ($new) {

        // We have new results: send them to the user.
        // Only load those items that will be sent.
        $sent_new = $new;
        if (!empty($settings->options['mail']['notify']['max_results'])) {
          $sent_new = array_slice($new, 0, $settings->options['mail']['notify']['max_results'], TRUE);
        }
        $new_results = $sent_new + $new;

        // Let other modules alter these results.
        drupal_alter('search_api_saved_searches_new_results', $new_results, $search);
        if ($new_results) {

          // We have to slice again in case some items were moved around or
          // removed by alter hooks.
          $sent_new = $new_results;
          if (!empty($settings->options['mail']['notify']['max_results'])) {
            $sent_new = array_slice($new_results, 0, $settings->options['mail']['notify']['max_results']);
          }
          $return['result_count'] = count($new_results);
          $return['results'] = $sent_new;
        }
      }
      if (empty($settings->options['date_field']) && ($new || array_diff($old, $results))) {

        // The results changed in some way: store the latest version.
        $search->results = implode(',', $results);
      }
    }

    // Use time() instead of REQUEST_TIME to minimize the potential of sending
    // duplicate results due to longer-running cron queue workers.
    $search->last_execute = time();
    $search
      ->save();
  } catch (SearchApiException $e) {
    $args = _drupal_decode_exception($e);
    $args['@id'] = $search->id;
    throw new SearchApiException(t('%type while trying to check for new results on saved search @id: !message in %function (line %line of %file).', $args));
  }
  return $return;
}