You are here

function views_navigation_store_query in Views navigation 7

Store a view query in cache.

Return the cid or FALSE if the query is not stored.

1 call to views_navigation_store_query()
views_navigation_views_pre_render in ./views_navigation.module
Implements hook_views_pre_render().

File

./views_navigation.inc, line 31
Views navigation main include file.

Code

function views_navigation_store_query($view) {
  if (_views_navigation_query_is_supported($view->query)) {
    $query_to_store = clone $view->query;
    $view_to_store = clone $view;
    $dh_to_store = clone $view_to_store->display_handler;

    // Handle the case when there is no pager.
    if (!isset($view_to_store->total_rows) || empty($view_to_store->total_rows)) {
      $view_to_store->total_rows = count($view_to_store->result);
    }

    // If there is zero or one result, we do nothing.
    if ($view_to_store->total_rows < 2) {
      return FALSE;
    }

    // Store the back destination if needed.
    if ($view->display_handler
      ->get_option('views_navigation_back')) {
      $raw_destination = drupal_get_destination();

      // We must remove the "page=X" query parameter to keep the stored info
      // identical across pages (same hash needed).
      // Thus the back link will always lead to the first page (we can't easily
      // know which page the user was on when he left the view : that would need
      // an extra GET parameter).
      $parsed_destination = drupal_parse_url(urldecode(reset($raw_destination)));
      unset($parsed_destination['query']['page']);
      $view_to_store->back_destination = $parsed_destination;

      // Store the view's title if needed.
      if ($view->display_handler
        ->get_option('views_navigation_title')) {
        $view_to_store->back_title = $view_to_store
          ->get_title();
      }
    }

    // Remove useless properties and query limit. This is the not easy part.
    // We must ensure that the stored query is the same across pagination.
    $query_to_store->pager_backup = $query_to_store->pager;
    unset($query_to_store->display);
    unset($query_to_store->header);
    unset($query_to_store->pager);
    $plugin = _views_navigation_get_query_plugin($query_to_store);
    switch ($plugin) {
      case 'default':
        unset($query_to_store->limit);
        $query_to_store->offset = 0;
        break;
      case 'search_api':
        $query_to_store
          ->set_limit(NULL);
        $query_to_store
          ->set_offset(0);
        break;
    }
    $keys = [
      'base_database',
      'name',
      'total_rows',
      'back_destination',
      'back_title',
    ];
    foreach ($view_to_store as $key => $value) {
      if (!in_array($key, $keys)) {
        unset($view_to_store->{$key});
      }
    }

    // Most of the display handler info is unneeded and might change across
    // pagination. But we need some info though.
    // Unsure we keep inherited cache options.
    $dh_to_store->options['cache'] = $dh_to_store
      ->get_option('cache');
    foreach ($dh_to_store as $key => $value) {

      // For now, we found no bug by keeping all the options, and only that.
      if (!in_array($key, [
        'options',
      ])) {
        unset($dh_to_store->{$key});
      }
    }
    $view_to_store->display_handler = $dh_to_store;
    $query_to_store->view = $view_to_store;

    // Allow modules to alter the stored info.
    drupal_alter('views_navigation_stored_query', $query_to_store, $view);
    $cid = views_navigation_get_query_cid($query_to_store);

    // The query may be stored already.
    if (!views_navigation_get_cached_query($cid)) {

      // We need to store the query as long as the user navigates across the
      // result set. One day should be far enough.
      // @see views_navigation_get_links()
      cache_set('query-' . $cid, $query_to_store, VIEWS_NAVIGATION_CACHE_BIN, REQUEST_TIME + 86400);
    }
    return $cid;
  }
  return FALSE;
}