You are here

function DrupalFileCache::set in File Cache 7

Store data in the persistent cache.

Parameters

$cid: The cache ID of the data to store.

$data: The data to store in the cache. Complex data types will be automatically serialized before insertion. Strings will be stored as plain text and not serialized.

$expire: One of the following values:

  • CACHE_PERMANENT: Indicates that the item should never be removed unless explicitly told to using cache_clear_all() with a cache ID.
  • CACHE_TEMPORARY: Indicates that the item should be removed at the next general cache wipe.
  • A Unix timestamp: Indicates that the item should be kept at least until the given time, after which it behaves like CACHE_TEMPORARY.

Overrides DrupalCacheInterface::set

File

./filecache.inc, line 324
DrupalFileCache class that implements DrupalCacheInterface.

Class

DrupalFileCache

Code

function set($cid, $data, $expire = CACHE_PERMANENT) {
  if (!is_string($cid)) {
    return;
  }
  $filename = $this->directory . '/' . $this
    ->encode_cid($cid);
  if (!$this->ok || filecache_is_readdeleteonly()) {

    // Any cache set while the bin is not OK tries to invalidate the cache record.
    @unlink($filename);
    return;
  }

  // Open file for that entry, handling errors that may arise
  $fh = @fopen($filename, 'r+b');
  if ($fh === FALSE) {

    // If file doesn't exist, create it with a+w permissions
    $fh = fopen($filename, 'c+b');
    if ($fh !== FALSE) {
      if (!chmod($filename, FILECACHE_FILE_MODE)) {
        watchdog('filecache', 'Cannot chmod %filename', array(
          '%filename' => $filename,
        ), WATCHDOG_CRITICAL);
        return;
      }
    }
    else {

      // most likely permission error - report it as critical error
      watchdog('filecache', 'Cannot open %filename', array(
        '%filename' => $filename,
      ), WATCHDOG_CRITICAL);
      return;
    }
  }

  // Our safeguard for simultaneous writing in the same file
  if (flock($fh, LOCK_EX) === FALSE) {
    fclose($fh);
    return;
  }
  $cache = new StdClass();

  // XXX Should be custom class
  $cache->cid = $cid;
  $cache->created = REQUEST_TIME;
  $cache->expire = $expire;
  $cache->data = $data;
  if (ftruncate($fh, 0) === FALSE || fwrite($fh, serialize($cache)) === FALSE || flock($fh, LOCK_UN) === FALSE || fclose($fh) === FALSE) {

    // XXX should not happen -> cleanup
    unlink($filename);
    flock($fh, LOCK_UN);
    fclose($fh);
    return;
  }
}