You are here

public function MemCacheDrupal::clear in Memcache API and Integration 7

Implements DrupalCacheInterface::clear().

Overrides DrupalCacheInterface::clear

File

./memcache.inc, line 295

Class

MemCacheDrupal
Implementation of cache.inc with memcache logic included

Code

public function clear($cid = NULL, $wildcard = FALSE) {
  if ($this->memcache === FALSE) {

    // No memcache connection.
    return;
  }

  // It is not possible to detect a cache_clear_all() call other than looking
  // at the backtrace unless http://drupal.org/node/81461 is added.
  $backtrace = debug_backtrace();
  if ($cid == MEMCACHE_CONTENT_CLEAR || isset($backtrace[2]) && $backtrace[2]['function'] == 'cache_clear_all' && empty($backtrace[2]['args'])) {

    // Update the timestamp of the last global flushing of this bin.  When
    // retrieving data from this bin, we will compare the cache creation
    // time minus the cache_flush time to the cache_lifetime to determine
    // whether or not the cached item is still valid.
    $this->cache_content_flush = time();
    $this
      ->variable_set('cache_content_flush_' . $this->bin, $this->cache_content_flush);
    if (variable_get('cache_lifetime_' . $this->bin, variable_get('cache_lifetime', 0))) {

      // We store the time in the current user's session. We then simulate
      // that the cache was flushed for this user by not returning cached
      // data to this user that was cached before the timestamp.
      if (isset($_SESSION['cache_flush']) && is_array($_SESSION['cache_flush'])) {
        $cache_bins = $_SESSION['cache_flush'];
      }
      else {
        $cache_bins = array();
      }

      // Use time() rather than request time here for correctness.
      $cache_tables[$this->bin] = $this->cache_content_flush;
      $_SESSION['cache_flush'] = $cache_tables;
    }
  }
  if (empty($cid) || $wildcard === TRUE) {

    // system_cron() flushes all cache bins returned by hook_flush_caches()
    // with cache_clear_all(NULL, $bin); The expected behaviour in this case
    // is to perform garbage collection on expired cache items (which is
    // irrelevant to memcache) but also to remove all CACHE_TEMPORARY items.
    // @see https://api.drupal.org/api/drupal/includes!cache.inc/function/cache_clear_all/7
    if (!isset($cid)) {

      // Update the timestamp of the last CACHE_TEMPORARY clear. All
      // temporary cache items created before this will be invalidated.
      $this->cache_temporary_flush = time();
      $this
        ->variable_set("cache_temporary_flush_{$this->bin}", $this->cache_temporary_flush);

      // Return early here as we do not want to register a wildcard flush.
      return;
    }
    elseif ($cid == '*') {
      $cid = '';
    }
    if (empty($cid)) {

      // Update the timestamp of the last global flushing of this bin.  When
      // retrieving data from this bin, we will compare the cache creation
      // time minus the cache_flush time to the cache_lifetime to determine
      // whether or not the cached item is still valid.
      $this->cache_flush = time();
      $this
        ->variable_set("cache_flush_{$this->bin}", $this->cache_flush);
      $this->flushed = min($this->cache_flush, time() - $this->cache_lifetime);
      if ($this->cache_lifetime) {

        // We store the time in the current user's session which is saved into
        // the sessions table by sess_write().  We then simulate that the
        // cache was flushed for this user by not returning cached data to
        // this user that was cached before the timestamp.
        if (isset($_SESSION['cache_flush']) && is_array($_SESSION['cache_flush'])) {
          $cache_bins = $_SESSION['cache_flush'];
        }
        else {
          $cache_bins = array();
        }
        $cache_bins[$this->bin] = $this->cache_flush;
        $_SESSION['cache_flush'] = $cache_bins;
      }
    }
    else {

      // Register a wildcard flush for current cid.
      $this
        ->wildcards($cid, TRUE);
    }
  }
  else {
    $cids = is_array($cid) ? $cid : array(
      $cid,
    );
    foreach ($cids as $cid) {
      dmemcache_delete($cid, $this->bin, $this->memcache);
    }
  }
}