Ejemplo n.º 1
0
	/**
	 * Writes item into the cache.
	 * Dependencies are:
	 * - Cache::PRIORITY => (int) priority
	 * - Cache::EXPIRE => (timestamp) expiration
	 * - Cache::SLIDING => (bool) use sliding expiration?
	 * - Cache::TAGS => (array) tags
	 * - Cache::FILES => (array|string) file names
	 * - Cache::ITEMS => (array|string) cache items
	 * - Cache::CONSTS => (array|string) cache items
	 *
	 * @param  string key
	 * @param  mixed  value
	 * @param  array  dependencies
	 * @return mixed  value itself
	 * @throws \InvalidArgumentException
	 */
	public function save($key, $data, array $dp = NULL)
	{
		if (!is_string($key) && !is_int($key)) {
			throw new \InvalidArgumentException("Cache key name must be string or integer, " . gettype($key) ." given.");
		}
		$this->key = (string) $key;
		$key = $this->namespace . self::NAMESPACE_SEPARATOR . $key;

		// convert expire into relative amount of seconds
		if (!empty($dp[Cache::EXPIRE])) {
			$dp[Cache::EXPIRE] = Nette\Tools::createDateTime($dp[Cache::EXPIRE])->format('U') - time();
		}

		// convert FILES into CALLBACKS
		if (isset($dp[self::FILES])) {
			//clearstatcache();
			foreach ((array) $dp[self::FILES] as $item) {
				$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); // @ - stat may fail
			}
			unset($dp[self::FILES]);
		}

		// add namespaces to items
		if (isset($dp[self::ITEMS])) {
			$dp[self::ITEMS] = (array) $dp[self::ITEMS];
			foreach ($dp[self::ITEMS] as $k => $item) {
				$dp[self::ITEMS][$k] = $this->namespace . self::NAMESPACE_SEPARATOR . $item;
			}
		}

		// convert CONSTS into CALLBACKS
		if (isset($dp[self::CONSTS])) {
			foreach ((array) $dp[self::CONSTS] as $item) {
				$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item));
			}
			unset($dp[self::CONSTS]);
		}

		if ($data instanceof Nette\Callback || $data instanceof \Closure) {
			Nette\Tools::enterCriticalSection();
			$data = $data->__invoke();
			Nette\Tools::leaveCriticalSection();
		}

		if (is_object($data)) {
			$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data),
				Nette\Reflection\ClassReflection::from($data)->getAnnotation('serializationVersion'));
		}

		$this->data = $data;
		if ($data === NULL) {
			$this->storage->remove($key);
		} else {
			$this->storage->write($key, $data, (array) $dp);
		}
		return $data;
	}
Ejemplo n.º 2
0
	/**
	 * Writes item into the cache.
	 * Dependencies are:
	 * - Cache::PRIORITY => (int) priority
	 * - Cache::EXPIRATION => (timestamp) expiration
	 * - Cache::SLIDING => (bool) use sliding expiration?
	 * - Cache::TAGS => (array) tags
	 * - Cache::FILES => (array|string) file names
	 * - Cache::ITEMS => (array|string) cache items
	 * - Cache::CONSTS => (array|string) cache items
	 *
	 * @param  mixed  key
	 * @param  mixed  value
	 * @param  array  dependencies
	 * @return mixed  value itself
	 * @throws \InvalidArgumentException
	 */
	public function save($key, $data, array $dp = NULL)
	{
		$this->key = is_scalar($key) ? (string) $key : serialize($key);
		$key = $this->namespace . md5($this->key);

		// convert expire into relative amount of seconds
		if (isset($dp[Cache::EXPIRATION])) {
			$dp[Cache::EXPIRATION] = Nette\Tools::createDateTime($dp[Cache::EXPIRATION])->format('U') - time();
		}

		// convert FILES into CALLBACKS
		if (isset($dp[self::FILES])) {
			//clearstatcache();
			foreach ((array) $dp[self::FILES] as $item) {
				$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkFile'), $item, @filemtime($item)); // @ - stat may fail
			}
			unset($dp[self::FILES]);
		}

		// add namespaces to items
		if (isset($dp[self::ITEMS])) {
			$dp[self::ITEMS] = (array) $dp[self::ITEMS];
			foreach ($dp[self::ITEMS] as $k => $item) {
				$dp[self::ITEMS][$k] = $this->namespace . md5(is_scalar($item) ? $item : serialize($item));
			}
		}

		// convert CONSTS into CALLBACKS
		if (isset($dp[self::CONSTS])) {
			foreach ((array) $dp[self::CONSTS] as $item) {
				$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkConst'), $item, constant($item));
			}
			unset($dp[self::CONSTS]);
		}

		if ($data instanceof Nette\Callback || $data instanceof \Closure) {
			Nette\Tools::enterCriticalSection();
			$data = $data->__invoke();
			Nette\Tools::leaveCriticalSection();
		}

		if (is_object($data)) {
			$dp[self::CALLBACKS][] = array(array(__CLASS__, 'checkSerializationVersion'), get_class($data),
				Nette\Reflection\ClassReflection::from($data)->getAnnotation('serializationVersion'));
		}

		$this->data = $data;
		if ($data === NULL) {
			$this->storage->remove($key);
		} else {
			$this->storage->write($key, $data, (array) $dp);
		}
		return $data;
	}