initialized; $this->getEventManager()->attach( 'option', function () use (& $initialized) { $initialized = false; } ); } /** * get mongodb resource * * @return MongoResource */ private function getMongoDbResource() { if (! $this->initialized) { $options = $this->getOptions(); $this->resourceManager = $options->getResourceManager(); $this->resourceId = $options->getResourceId(); $namespace = $options->getNamespace(); $this->namespacePrefix = ($namespace === '' ? '' : $namespace . $options->getNamespaceSeparator()); $this->initialized = true; } return $this->resourceManager->getResource($this->resourceId); } /** * {@inheritDoc} */ public function setOptions($options) { return parent::setOptions($options instanceof MongoDbOptions ? $options : new MongoDbOptions($options)); } /** * Get options. * * @return MongoDbOptions * @see setOptions() */ public function getOptions() { return $this->options; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ protected function internalGetItem(& $normalizedKey, & $success = null, & $casToken = null) { $result = $this->fetchFromCollection($normalizedKey); $success = false; if (null === $result) { return; } if (isset($result['expires'])) { if (! $result['expires'] instanceof MongoDate) { throw new Exception\RuntimeException(sprintf( "The found item _id '%s' for key '%s' is not a valid cache item" . ": the field 'expired' isn't an instance of MongoDate, '%s' found instead", (string) $result['_id'], $this->namespacePrefix . $normalizedKey, is_object($result['expires']) ? get_class($result['expires']) : gettype($result['expires']) )); } if ($result['expires']->sec < time()) { $this->internalRemoveItem($normalizedKey); return; } } if (! array_key_exists('value', $result)) { throw new Exception\RuntimeException(sprintf( "The found item _id '%s' for key '%s' is not a valid cache item: missing the field 'value'", (string) $result['_id'], $this->namespacePrefix . $normalizedKey )); } $success = true; return $casToken = $result['value']; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ protected function internalSetItem(& $normalizedKey, & $value) { $mongo = $this->getMongoDbResource(); $key = $this->namespacePrefix . $normalizedKey; $ttl = $this->getOptions()->getTTl(); $expires = null; $cacheItem = [ 'key' => $key, 'value' => $value, ]; if ($ttl > 0) { $expiresMicro = microtime(true) + $ttl; $expiresSecs = (int) $expiresMicro; $cacheItem['expires'] = new MongoDate($expiresSecs, $expiresMicro - $expiresSecs); } try { $mongo->remove(['key' => $key]); $result = $mongo->insert($cacheItem); } catch (MongoResourceException $e) { throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); } return null !== $result && ((double) 1) === $result['ok']; } /** * {@inheritDoc} * * @throws Exception\RuntimeException */ protected function internalRemoveItem(& $normalizedKey) { try { $result = $this->getMongoDbResource()->remove(['key' => $this->namespacePrefix . $normalizedKey]); } catch (MongoResourceException $e) { throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); } return false !== $result && ((double) 1) === $result['ok'] && $result['n'] > 0; } /** * {@inheritDoc} */ public function flush() { $result = $this->getMongoDbResource()->drop(); return ((double) 1) === $result['ok']; } /** * {@inheritDoc} */ protected function internalGetCapabilities() { if ($this->capabilities) { return $this->capabilities; } return $this->capabilities = new Capabilities( $this, $this->capabilityMarker = new stdClass(), [ 'supportedDatatypes' => [ 'NULL' => true, 'boolean' => true, 'integer' => true, 'double' => true, 'string' => true, 'array' => true, 'object' => false, 'resource' => false, ], 'supportedMetadata' => [ '_id', ], 'minTtl' => 1, 'staticTtl' => true, 'maxKeyLength' => 255, 'namespaceIsPrefix' => true, ] ); } /** * {@inheritDoc} * * @throws Exception\ExceptionInterface */ protected function internalGetMetadata(& $normalizedKey) { $result = $this->fetchFromCollection($normalizedKey); return null !== $result ? ['_id' => $result['_id']] : false; } /** * Return raw records from MongoCollection * * @param string $normalizedKey * * @return array|null * * @throws Exception\RuntimeException */ private function fetchFromCollection(& $normalizedKey) { try { return $this->getMongoDbResource()->findOne(['key' => $this->namespacePrefix . $normalizedKey]); } catch (MongoResourceException $e) { throw new Exception\RuntimeException($e->getMessage(), $e->getCode(), $e); } } }