/** * Loads the mapping of the models with resource types * @return null */ protected function loadModelMapping() { $modelTypesCacheItem = $this->cache->get(self::CACHE_TYPES); if ($modelTypesCacheItem->isValid()) { $this->modelTypes = $modelTypesCacheItem->getValue(); return; } $this->modelTypes = array(); $models = $this->orm->getModels(); foreach ($models as $modelName => $model) { $type = $model->getMeta()->getOption('json.api'); if (!$type) { continue; } $this->modelTypes[$modelName] = $type; } $modelTypesCacheItem->setValue($this->modelTypes); $this->cache->set($modelTypesCacheItem); }
/** * Dispatches the node * @param \ride\library\mvc\Request $request * @param \ride\library\mvc\Response $response * @param \ride\library\security\SecurityManager $securityManager * @param \ride\library\cache\pool\CachePool $cache * @return array Array with the region name as key and a view array as * value. The view array has the widget id as key and the dispatched * widget view as value */ public function dispatch(Request $request, Response $response, SecurityManager $securityManager, CachePool $cache = null) { $this->locale = $this->view->getLocale(); // initialize context $context = array('title' => array('site' => $this->node->getRootNode()->getName($this->locale, 'title'), 'node' => $this->node->getName($this->locale, 'title')), 'breadcrumbs' => $this->breadcrumbs, 'styles' => array(), 'scripts' => array()); // prepare and process incoming route arguments $route = $request->getRoute(); $this->routeArguments = $route->getArguments(); unset($this->routeArguments['node']); unset($this->routeArguments['locale']); if (isset($this->routeArguments['site'])) { // preview has site and revision unset($this->routeArguments['site']); unset($this->routeArguments['revision']); } $nodeRoute = $this->node->getRoute($this->locale); $nodeRouteTokens = explode('/', ltrim($nodeRoute, '/')); foreach ($nodeRouteTokens as $tokenIndex => $tokenValue) { if (isset($this->routeArguments[$tokenIndex]) && $this->routeArguments[$tokenIndex] === $tokenValue) { unset($this->routeArguments[$tokenIndex]); } } $route->setPredefinedArguments(array()); $route->setArguments(); $routeArgumentsMatched = false; // check for cache $cacheKey = null; $cacheItem = null; $cachedViews = array(); $dispatchedViews = array(); $nodeCacheTtl = false; if ($cache) { $method = $request->getMethod(); $isCacheable = $method == 'GET' || $method == 'HEAD' ? true : false; $isNoCache = $request->isNoCache(); if ($isCacheable) { $parameters = $this->routeArguments ? '-' . implode('-', $this->routeArguments) : ''; $parameters .= $request->getQueryParametersAsString(); $containsUserContent = false; $nodeCacheTtl = 0; $cacheKey = 'node.view.' . $this->node->getId() . '.' . $this->node->getRevision() . '.' . $this->locale . '.' . substr(md5($parameters), 0, 10); if ($securityManager->getUser()) { $cacheKey .= '.authenticated'; } $cacheItem = $cache->get($cacheKey); if ($cacheItem->isValid()) { $cachedViews = $cacheItem->getValue(); } else { $cachedViews = array(); } } } else { $isCacheable = false; } foreach ($this->widgets as $this->region => $sections) { $dispatchedViews[$this->region] = array(); foreach ($sections as $this->section => $blocks) { $dispatchedViews[$this->region][$this->section] = array(); foreach ($blocks as $this->block => $widgets) { $dispatchedViews[$this->region][$this->section][$this->block] = array(); foreach ($widgets as $widgetId => $widget) { if ($this->log) { $this->log->logDebug('Rendering widget ' . $widget->getName() . '#' . $widgetId . ' for region ' . $this->region, null, ApplicationListener::LOG_SOURCE); } $widgetProperties = $this->node->getWidgetProperties($widgetId); if (!$widgetProperties->isPublished()) { if ($this->log) { $this->log->logDebug('Widget ' . $widget->getName() . '#' . $widgetId . ' is not published', null, ApplicationListener::LOG_SOURCE); } continue; } elseif (!$widgetProperties->isAllowed($securityManager)) { if ($this->log) { $this->log->logDebug('Widget ' . $widget->getName() . '#' . $widgetId . ' is not allowed', null, ApplicationListener::LOG_SOURCE); } continue; } if ($isCacheable) { $widgetCacheKey = $this->region . '.' . $this->section . '.' . $this->block . '.' . $widgetId . '.'; } $isWidgetCache = $widgetProperties->isCacheEnabled() || $widgetProperties->isAutoCache() && $widget->isAutoCache(); if ($isCacheable && !$isNoCache && $isWidgetCache) { if (isset($cachedViews[$this->region][$this->section][$this->block][$widgetId])) { if ($this->log) { $this->log->logDebug('Retrieved widget ' . $widget->getName() . '#' . $widgetId . ' from cache', null, ApplicationListener::LOG_SOURCE); } $cacheView = $cachedViews[$this->region][$this->section][$this->block][$widgetId]; if ($cacheView->areRoutesMatched()) { $widgetMatchedRouteArguments = true; } $cacheContext = $cacheView->getContext(); if ($cacheContext) { foreach ($cacheContext as $key => $value) { if ($value !== null) { $context[$key] = $value; } elseif (isset($context[$key])) { unset($context[$key]); } } } if ($cacheView->isContent()) { $dispatchedViews = null; $this->view->setContentView($view, $widgetId, $this->block, $this->section, $this->region); break 4; } elseif ($cacheView->isRegion()) { $dispatchedViews[$this->region] = array($this->section => array($this->block => array($widgetId => $cacheView->getView()))); break 3; } elseif ($cacheView->isSection()) { $dispatchedViews[$this->region][$this->section] = array($this->block => array($widgetId => $cacheView->getView())); break 2; } elseif ($cacheView->isBlock()) { $dispatchedViews[$this->region][$this->section][$this->block] = array($widgetId => $cacheView->getView()); break; } else { $dispatchedViews[$this->region][$this->section][$this->block][$widgetId] = $cacheView->getView(); continue; } } } $widget->setProperties($widgetProperties); $widget->setContext($context); $widgetMatchedRouteArguments = $this->dispatchWidget($request, $response, $widgetId, $widget); if ($widgetMatchedRouteArguments) { $routeArgumentsMatched = true; } $statusCode = $response->getStatusCode(); if ($statusCode != Response::STATUS_CODE_OK && $statusCode != Response::STATUS_CODE_BAD_REQUEST && $statusCode != Response::STATUS_CODE_UNPROCESSABLE_ENTITY) { return; } $view = $response->getView(); $response->setView(null); $isContent = $widget->isContent(); $isRegion = $widget->isRegion(); $isSection = $widget->isSection(); $isBlock = $widget->isBlock(); if ($isCacheable && !$containsUserContent && $widget->containsUserContent()) { $containsUserContent = true; } $oldContext = $context; $context = $widget->getContext(); if ($isCacheable && $isWidgetCache) { $widgetContext = $this->getContextDifference($context, $oldContext); if (!$widgetContext) { // calculate node cache time based on the least widget cache time $cacheTtl = $widgetProperties->getCacheTtl(); if ($nodeCacheTtl !== false && $cacheTtl) { if ($nodeCacheTtl == 0) { $nodeCacheTtl = $cacheTtl; } else { $nodeCacheTtl = min($nodeCacheTtl, $cacheTtl); } } $widgetCachedView = new WidgetCacheData($widgetContext, $isContent, $isRegion, $isSection, $isBlock, $widgetMatchedRouteArguments); $cachedViews[$this->region][$this->section][$this->block][$widgetId] = $widgetCachedView; } } if ($isContent) { $dispatchedViews = null; $this->view->setContentView($view, $widgetId, $this->block, $this->section, $this->region); break 4; } elseif ($isRegion) { $dispatchedViews[$this->region] = array($this->section => array($this->block => array($widgetId => $view))); break 3; } elseif ($isSection) { $dispatchedViews[$this->region][$this->section] = array($this->block => array($widgetId => $view)); break 2; } elseif ($isBlock) { $dispatchedViews[$this->region][$this->section][$this->block] = array($widgetId => $view); break; } $dispatchedViews[$this->region][$this->section][$this->block][$widgetId] = $view; } if (!$dispatchedViews[$this->region][$this->section][$this->block]) { unset($dispatchedViews[$this->region][$this->section][$this->block]); } } if (!$dispatchedViews[$this->region][$this->section]) { unset($dispatchedViews[$this->region][$this->section]); } } if (!$dispatchedViews[$this->region]) { unset($dispatchedViews[$this->region]); } } if ($this->routeArguments && !$routeArgumentsMatched) { // sub route provided but never matched $response->setStatusCode(Response::STATUS_CODE_NOT_FOUND); $response->setView(null); $dispatchedViews = null; } // if ($this->eventManager && $isCacheable && $nodeCacheTtl !== false) { // if ($user && $containsUserContent) { // $isCacheable = false; // } // if ($isCacheable) { // $this->cache = $cache; // $this->cacheTtl = $nodeCacheTtl; // $this->eventManager->addEventListener(WebApplication::EVENT_POST_RESPONSE, array($this, 'cacheResponse')); // } // } $this->view->setContext($context); if (is_array($dispatchedViews)) { $this->view->setDispatchedViews($dispatchedViews); $this->view->setRegions($this->regions); if ($nodeCacheTtl !== false && $cachedViews) { $cacheItem->setValue($cachedViews); $cacheItem->setTtl($nodeCacheTtl); $this->view->setCachedViews($cache, $cacheItem); } } $response->setView($this->view); }