setDistributedCache() public method

This stores a ms timestamp on the distributed cache (Jarves::setCache()) and the actual data on the high-speed cache driver (Jarves::setFastCache()). This mechanism makes sure, you gain the maximum performance by using the fast cache driver to store the actual data and using the distributed cache driver to store a ms timestamp where we can check (over several jarves.cms installations) whether the cache is still valid or not. Use Jarves::invalidateCache($key) to invalidate this cache. You don't have to define the full key, instead you can pass only a part of the key.
See also: invalidateCache for more information. Don't mix the usage of getDistributedCache() and getCache() since this method stores extra values at the value, which makes getCache() returning something invalid.
public setDistributedCache ( string $key, mixed $value, integer $lifeTime = null ) : boolean
$key string
$value mixed Only simple data types. Serialize your value if you have objects/arrays.
$lifeTime integer
return boolean
Beispiel #1
0
 /**
  * Returns a rendered view. If we find html behind the given cache
  * it returns this directly. This is a couple os ms faster than `renderCached`
  * since the template engine is never used when there's a valid cache.
  *
  * Example:
  *
  *  return $this->renderFullCached('myCache', 'plugin1/default.tpl', function(){
  *     return array('items' => heavyDbQuery());
  * });
  *
  * Note: The $data callable is only called if the cache needs to regenerate (when it has been
  * invalidated or empty, or the view file changed).
  *
  * If the callable $data returns NULL, then this will return NULL, too, without entering
  * the actual rendering process.
  *
  * You should use this method in your plugins instead of writing your own cache mechanism,
  * because this method handles PageResponse merging. Means: If templates used in this
  * $view are changing somehow the PageResponse ({{loadAsset('style.css')}} calls) then
  * this information (diff to current PageResponse) is stored and restored when we found
  * a html cache. The diff is beside the actual rendered HTML also stored in the cache
  * to keep this possible.
  *
  * @param string $cacheKey
  * @param string $view
  * @param array|callable $data Pass the data as array or a data provider function.
  * @param integer $lifeTime In seconds. Default is one hour/3600 seconds.
  * @param bool $force Force to bypass the cache and always call $data. For debuggin purposes.
  *
  * @see method `render` to get more information.
  *
  * @return string
  */
 public function renderFullCached($cacheKey, $view, $data = null, $lifeTime = null, $force = false)
 {
     $cache = $this->cacher->getDistributedCache($cacheKey);
     $mTime = $this->getViewMTime($view);
     if (!is_string($cache)) {
         $cache = null;
     } else {
         $cache = @unserialize($cache);
     }
     if ($force || !$cache || !$cache['content'] || !is_array($cache) || $mTime != $cache['fileMTime']) {
         $oldResponse = clone $this->pageStack->getPageResponse();
         $data2 = $data;
         if (is_callable($data)) {
             $data2 = call_user_func($data, $view);
             if (null === $data2) {
                 //the data callback returned NULL so this means
                 //we aren't the correct controller for this request
                 //or the request contains invalid input
                 return null;
             }
         }
         $content = $this->templating->render($view, $data2);
         $response = $this->pageStack->getPageResponse();
         $diff = $oldResponse->diff($response);
         $cache = array('content' => $content, 'fileMTime' => $mTime, 'responseDiff' => $diff);
         $this->cacher->setDistributedCache($cacheKey, serialize($cache), $lifeTime ?: 3600);
     } else {
         if ($cache['responseDiff']) {
             $this->pageStack->getPageResponse()->patch($cache['responseDiff']);
         }
     }
     return $this->pageResponseFactory->createPluginResponse($cache['content']);
 }
Beispiel #2
0
 /**
  * Returns a array map url -> nodeId
  *
  * @param integer $domainId
  *
  * @return array
  *
  * @throws \Propel\Runtime\Exception\PropelException
  */
 public function getCachedUrlToPage($domainId)
 {
     $cacheKey = 'core/urls/' . $domainId;
     $urls = $this->cacher->getDistributedCache($cacheKey);
     if (!$urls) {
         $nodes = NodeQuery::create()->select(array('id', 'urn', 'lvl', 'type'))->filterByDomainId($domainId)->orderByBranch()->find();
         //build urls array
         $urls = array();
         $level = array();
         foreach ($nodes as $node) {
             if ($node['lvl'] == 0) {
                 continue;
             }
             //root
             if ($node['type'] == 3) {
                 continue;
             }
             //deposit
             if ($node['type'] == 2 || $node['urn'] == '') {
                 //folder or empty url
                 $level[$node['lvl'] + 0] = isset($level[$node['lvl'] - 1]) ? $level[$node['lvl'] - 1] : '';
                 continue;
             }
             $url = isset($level[$node['lvl'] - 1]) ? $level[$node['lvl'] - 1] : '';
             $url .= '/' . $node['urn'];
             $level[$node['lvl'] + 0] = $url;
             $urls[$url] = $node['id'];
         }
         $this->cacher->setDistributedCache($cacheKey, $urls);
     }
     return $urls;
 }
Beispiel #3
0
 public function breadcrumb(\Twig_Environment $twig, $view = 'JarvesBundle:Default:breadcrumb.html.twig')
 {
     $breadcrumbs = [];
     $page = $this->pageStack->getCurrentPage();
     $cacheKey = 'core/breadcrumbs/' . $page->getCacheKey();
     if ($cache = $this->cacher->getDistributedCache($cacheKey)) {
         if (is_string($cache)) {
             return $cache;
         }
     }
     foreach ($page->getParents() as $parent) {
         if ($parent->getLevel() === 0) {
             continue;
         }
         if ($parent->getType() >= 2) {
             continue;
         }
         $breadcrumbs[] = $parent;
     }
     $data = ['domain' => $this->pageStack->getCurrentDomain(), 'baseUrl' => $this->pageStack->getPageResponse()->getBaseHref(), 'breadcrumbs' => $breadcrumbs, 'currentPage' => $this->pageStack->getCurrentPage()];
     $html = $twig->render($view, $data);
     $this->cacher->setDistributedCache($cacheKey, $html);
     return $html;
 }
Beispiel #4
0
 /**
  * 
  * Options:
  * 
  *  //whether the template cache is deactivated. Navigation object is still cached
  *  boolean noCache = false
  *
  *  //whether the pathInfo is used in the cacheKey instead of the currentUrl.
  *  //Useful when you have in your navigation controller calls that are based on pathInfo like
  *  //pageStack->getCurrentUrlAffix()
  *  boolean pathInfoCache = false
  * 
  * Example:
  *   getRendered(['noCache' => true]);
  * 
  * @param array $options
  * @param \Twig_Environment $twig
  * @return string
  * @throws \Exception
  */
 public function getRendered($options, \Twig_Environment $twig)
 {
     $options['noCache'] = isset($options['noCache']) ? (bool) $options['noCache'] : false;
     $options['pathInfoCache'] = isset($options['pathInfoCache']) ? (bool) $options['pathInfoCache'] : false;
     $view = $options['template'] ?: $options['view'];
     $cacheKey = 'core/navigation/' . $this->pageStack->getCurrentPage()->getDomainId() . '.' . $this->pageStack->getCurrentPage()->getId() . ($options['pathInfoCache'] ? '_' . md5($this->pageStack->getRequest()->getPathInfo()) : '') . '_' . md5(json_encode($options));
     $fromCache = false;
     $viewPath = $this->jarves->resolvePath($view, 'Resources/views/');
     if ('@' === $view[0]) {
         $view = substr($view, 1);
     }
     if (!file_exists($viewPath)) {
         throw new \Exception(sprintf('View `%s` not found.', $view));
     } else {
         $mtime = filemtime($viewPath);
     }
     if (!$options['noCache']) {
         $cache = $this->cacher->getDistributedCache($cacheKey);
         if ($cache && isset($cache['html']) && $cache['html'] !== null && $cache['mtime'] == $mtime) {
             return $cache['html'];
         }
     }
     $cache = $this->cacher->getDistributedCache($cacheKey);
     if ($cache && isset($cache['object']) && $cache['mtime'] == $mtime) {
         $navigation = unserialize($cache['object']);
         $fromCache = true;
     } else {
         $navigation = $this->get($options);
     }
     $data['navigation'] = $navigation ?: false;
     if ($navigation !== false) {
         $html = $twig->render($view, $data);
         if (!$options['noCache']) {
             $this->cacher->setDistributedCache($cacheKey, array('mtime' => $mtime, 'html' => $html));
         } elseif (!$fromCache) {
             $this->cacher->setDistributedCache($cacheKey, array('mtime' => $mtime, 'object' => serialize($navigation)));
         }
         return $html;
     }
     //no navigation found, probably the template just uses the breadcrumb
     return $twig->render($view, $data);
 }
Beispiel #5
0
 /**
  * @param integer $nodeId
  * @param integer $slotId
  * @return Model\Content[]
  */
 public function getSlotContents($nodeId, $slotId)
 {
     if ($contents = $this->pageStack->getPageResponse()->getPageContent()) {
         if (is_array($contents) && $contents[$slotId]) {
             return $contents[$slotId];
         } else {
             if (is_string($contents)) {
                 return $contents;
             }
         }
     }
     $cacheKey = 'core/contents/' . $nodeId . '.' . $slotId;
     $cache = $this->cacher->getDistributedCache($cacheKey);
     $contents = null;
     if ($cache) {
         return unserialize($cache);
     }
     $contents = ContentQuery::create()->filterByNodeId($nodeId)->filterByBoxId($slotId)->orderByRank()->find();
     $this->cacher->setDistributedCache($cacheKey, serialize($contents));
     return $contents;
 }
Beispiel #6
0
 /**
  * @param ACLRequest $aclRequest
  *
  * @return bool
  */
 public function check(ACLRequest $aclRequest)
 {
     $objectKey = Objects::normalizeObjectKey($aclRequest->getObjectKey());
     $targetType = $aclRequest->getTargetType();
     $targetId = $aclRequest->getTargetId();
     $pk = $aclRequest->getPrimaryKey();
     $field = $aclRequest->getField();
     $pk = $this->objects->normalizePkString($objectKey, $pk);
     if (ACL::TARGET_TYPE_USER === $targetType && null === $targetId) {
         //0 means guest
         $targetId = $this->pageStack->getUser() ? $this->pageStack->getUser()->getId() : 0;
     }
     $user = $this->pageStack->getUser();
     if ($user) {
         $groupIds = $user->getGroupIds();
         if (false !== strpos(',' . $groupIds . ',', ',1,')) {
             //user is in the admin group, so he has always access.
             return true;
         }
     }
     if (ACL::TARGET_TYPE_USER === $targetType && 1 === $targetId) {
         //user admin has always access
         return true;
     }
     if (ACL::TARGET_TYPE_GROUP === $targetType && 1 === $targetId) {
         //group admin has always access
         return true;
     }
     if (0 === $targetId) {
         //guests do always have no access
         return false;
     }
     if (ACL::TARGET_TYPE_GROUP === $targetType && !$targetId) {
         throw new \InvalidArgumentException('For type TARGET_TYPE_GROUP a targetId is required.');
     }
     $cacheKey = null;
     if ($pk && $this->getCaching()) {
         $pkString = $this->objects->getObjectUrlId($objectKey, $pk);
         $cacheKey = md5($targetType . '.' . $targetId . '.' . $objectKey . '/' . $pkString . '/' . json_encode($field));
         $cached = $this->cacher->getDistributedCache('core/acl/' . $cacheKey);
         if (null !== $cached) {
             return $cached;
         }
     }
     $rules = self::getRules($objectKey, $aclRequest->getMode(), $targetType, $targetId);
     if (count($rules) === 0) {
         //no rules found, so we have no access
         return false;
     }
     $access = null;
     $currentObjectPk = $pk;
     $definition = $this->objects->getDefinition($objectKey);
     $not_found = true;
     //starts directly as if we were in the parent checking.
     $parent_acl = $aclRequest->isAsParent();
     $fCount = null;
     $fKey = null;
     $fValue = null;
     $fIsArray = is_array($field);
     if ($fIsArray) {
         $fCount = count($field);
         $fKey = key($field);
         $fValue = current($field);
         if (is_int($fKey)) {
             $fKey = $fValue;
             $fValue = null;
         }
     }
     $depth = 0;
     $match = false;
     $originObjectItemPk = $currentObjectPk;
     while ($not_found) {
         $currentObjectPkString = null;
         if ($currentObjectPk) {
             $currentObjectPkString = $this->objects->getObjectUrlId($objectKey, $currentObjectPk);
         }
         $depth++;
         if ($depth > 50) {
             $not_found = false;
             break;
         }
         foreach ($rules as $aclRule) {
             if ($parent_acl && !$aclRule['sub']) {
                 //as soon we enter the parent_acl mode we only take acl rules into consideration
                 //that are also valid for children (sub=true)
                 continue;
             }
             $match = false;
             /*
              * CUSTOM CONSTRAINT
              */
             if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION) {
                 $objectItem = null;
                 if ($originObjectItemPk === $currentObjectPk && null !== $aclRequest->getPrimaryObjectItem()) {
                     $objectItem = $aclRequest->getPrimaryObjectItem();
                 } else {
                     if ($originObjectItemPk) {
                         $objectItem = $this->objects->get($objectKey, $currentObjectPk);
                     }
                 }
                 if ($objectItem && $this->conditionOperator->satisfy($aclRule['constraint_code'], $objectItem, $objectKey)) {
                     $match = true;
                 }
                 /*
                  * EXACT
                  */
             } else {
                 if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT) {
                     if ($currentObjectPk && $aclRule['constraint_code'] === $currentObjectPkString) {
                         $match = true;
                     }
                     /**
                      * ALL
                      */
                 } else {
                     $match = true;
                 }
             }
             if (!$match && $aclRule['sub'] && $currentObjectPk) {
                 // we need to check if a parent matches this $acl as we have sub=true
                 $parentItem = $this->objects->normalizePkString($objectKey, $currentObjectPk);
                 $parentCondition = Condition::create($aclRule['constraint_code']);
                 $parentOptions['fields'] = $this->conditionOperator->extractFields($parentCondition);
                 while ($parentItem = $this->objects->getParent($objectKey, $this->objects->getObjectPk($objectKey, $parentItem), $parentOptions)) {
                     if ($aclRule['constraint_type'] === ACL::CONSTRAINT_CONDITION && $this->conditionOperator->satisfy($parentCondition, $parentItem)) {
                         $match = true;
                         break;
                     } else {
                         if ($aclRule['constraint_type'] === ACL::CONSTRAINT_EXACT && $aclRule['constraint_code'] === $this->objects->getObjectUrlId($objectKey, $parentItem)) {
                             $match = true;
                             break;
                         }
                     }
                 }
             }
             if ($match) {
                 //match, check all $field
                 $field2Key = $field;
                 if ($field) {
                     if ($fIsArray && $fCount === 1) {
                         if (is_string($fKey) && is_array($aclRule['fields'][$fKey])) {
                             //this field has limits
                             if (($field2Acl = $aclRule['fields'][$fKey]) !== null) {
                                 if (is_array($field2Acl[0])) {
                                     //complex field rule, $field2Acl = ([{access: no, condition: [['id', '>', 2], ..]}, {}, ..])
                                     foreach ($field2Acl as $fRule) {
                                         $satisfy = false;
                                         if (($f = $definition->getField($fKey)) && $f->getType() === 'object') {
                                             $uri = $f->getObject() . '/' . $fValue;
                                             $uriObject = $this->objects->getFromUrl($uri);
                                             $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $uriObject);
                                         } else {
                                             if (null !== $fValue) {
                                                 $satisfy = $this->conditionOperator->satisfy($fRule['condition'], $field);
                                             }
                                         }
                                         if ($satisfy) {
                                             return $fRule['access'] === 1 ? true : false;
                                         }
                                     }
                                     //if no field rules fits, we consider the whole rule
                                     if ($aclRule['access'] !== 2) {
                                         return $aclRule['access'] === 1 ? true : false;
                                     }
                                 } else {
                                     //simple field rule $field2Acl = ({"value1": yes, "value2": no}
                                     if ($field2Acl[$fKey] !== null) {
                                         return $field2Acl[$fKey] === 1 ? true : false;
                                     } else {
                                         //current($field) is not exactly defined in $field2Acl, so we set $access to $acl['access']
                                         //
                                         //if access = 2 then wo do not know it, cause 2 means 'inherited', so maybe
                                         //a other rule has more detailed rule
                                         if ($aclRule['access'] !== 2) {
                                             $access = $aclRule['access'] === 1 ? true : false;
                                             break;
                                         }
                                     }
                                 }
                             }
                         } else {
                             //this field has only true or false
                             $field2Key = $fKey;
                         }
                     }
                     if (!is_array($field2Key)) {
                         if ($aclRule['fields'] && ($field2Acl = $aclRule['fields'][$field2Key]) !== null && !is_array($aclRule['fields'][$field2Key])) {
                             $access = $field2Acl === 1 ? true : false;
                             break;
                         } else {
                             //$field is not exactly defined, so we set $access to $acl['access']
                             //and maybe a rule with the same code has the field defined
                             // if access = 2 then this rule is only for exactly define fields
                             if ($aclRule['access'] !== 2) {
                                 $access = $aclRule['access'] === 1 ? true : false;
                                 break;
                             }
                         }
                     }
                 } else {
                     $access = $aclRule['access'] === 1 ? true : false;
                     break;
                 }
             }
         }
         //foreach
         if (null === $access && $definition->isNested() && $pk) {
             //$access has not defined yet (no rule matched yet). Check if nested and $pk is given
             //load its root and check again
             if (null === ($currentObjectPk = $this->objects->getParentPk($objectKey, $currentObjectPk))) {
                 $access = $aclRequest->isRootHasAccess() ? true : $access;
                 break;
             }
             $parent_acl = true;
         } else {
             break;
         }
     }
     $access = (bool) $access;
     if ($pk && $this->getCaching()) {
         $this->cacher->setDistributedCache('core/acl/' . $cacheKey, $access);
     }
     return $access;
 }
Beispiel #7
0
 /**
  * Returns the domain if found
  *
  * @return \Jarves\Model\Domain|null
  *
  * @throws \Propel\Runtime\Exception\PropelException
  */
 public function searchDomain()
 {
     $request = $this->getRequest();
     $dispatcher = $this->eventDispatcher;
     if ($domainId = $request->get('_jarves_editor_domain')) {
         $hostname = DomainQuery::create()->select('domain')->findOneById($domainId);
     } else {
         $hostname = $request->getHost();
     }
     $title = sprintf('Searching Domain [%s]', $hostname);
     $this->stopwatch->start($title);
     /** @var \Jarves\Model\Domain $foundDomain */
     $foundDomain = null;
     $possibleLanguage = $this->getPossibleLanguage();
     $hostnameWithLanguage = $hostname . '/' . $possibleLanguage;
     $cachedDomains = $this->cacher->getDistributedCache('core/domains');
     if ($cachedDomains) {
         $cachedDomains = @unserialize($cachedDomains);
     }
     if (!is_array($cachedDomains)) {
         $cachedDomains = array();
         $domains = DomainQuery::create()->find();
         foreach ($domains as $domain) {
             $key = $domain->getDomain();
             $langKey = '';
             if (!$domain->getMaster()) {
                 $langKey = '/' . $domain->getLang();
             }
             $cachedDomains[$key . $langKey] = $domain;
             if ($domain->getRedirect()) {
                 $redirects = $domain->getRedirect();
                 $redirects = explode(',', str_replace(' ', '', $redirects));
                 foreach ($redirects as $redirectDomain) {
                     $cachedDomains['!redirects'][$redirectDomain . $langKey] = $key . $langKey;
                 }
             }
             if ($domain->getAlias()) {
                 $aliases = $domain->getAlias();
                 $aliases = explode(',', str_replace(' ', '', $aliases));
                 foreach ($aliases as $aliasDomain) {
                     $cachedDomains['!aliases'][$aliasDomain . $langKey] = $key . $langKey;
                 }
             }
         }
         $this->cacher->setDistributedCache('core/domains', serialize($cachedDomains));
     }
     //search redirect
     if (isset($cachedDomains['!redirects']) && (isset($cachedDomains['!redirects'][$hostnameWithLanguage]) && ($redirectToDomain = $cachedDomains['!redirects'][$hostnameWithLanguage])) || isset($cachedDomains['!redirects'][$hostname]) && ($redirectToDomain = $cachedDomains['!redirects'][$hostname])) {
         $foundDomain = $cachedDomains[$redirectToDomain];
         $dispatcher->dispatch('core/domain-redirect', new GenericEvent($foundDomain));
         return null;
     }
     //search alias
     if (isset($cachedDomains['!aliases']) && (isset($cachedDomains['!aliases'][$hostnameWithLanguage]) && ($aliasHostname = $cachedDomains['!aliases'][$hostnameWithLanguage]) || isset($cachedDomains['!aliases'][$hostname]) && ($aliasHostname = $cachedDomains['!aliases'][$hostname]))) {
         $foundDomain = $cachedDomains[$aliasHostname];
         $hostname = $aliasHostname;
     } else {
         if (isset($cachedDomains[$hostname])) {
             $foundDomain = $cachedDomains[$hostname];
         }
     }
     if (!$foundDomain) {
         $dispatcher->dispatch('core/domain-not-found', new GenericEvent($hostname));
         $this->stopwatch->stop($title);
         return null;
     }
     $foundDomain->setRealDomain($hostname);
     $this->stopwatch->stop($title);
     return $foundDomain;
 }