Ejemplo n.º 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']);
 }
Ejemplo n.º 2
0
 public function fixResponse(GetResponseForControllerResultEvent $event)
 {
     $data = $event->getControllerResult();
     if ($data instanceof PluginResponseInterface) {
         $response = $data;
     } else {
         $response = $this->pageResponseFactory->createPluginResponse($data);
     }
     $event->setResponse($response);
 }
Ejemplo n.º 3
0
 public function onKernelView(GetResponseForControllerResultEvent $event)
 {
     $data = $event->getControllerResult();
     $request = $event->getRequest();
     if (!$event->getRequest()->attributes->get('_jarves_is_plugin')) {
         //we accept only plugin responses.
         return;
     }
     $content = $request->attributes->get('_content');
     if (null !== $data) {
         if ($data instanceof PluginResponseInterface) {
             $response = $data;
         } else {
             $response = $this->pageResponseFactory->createPluginResponse($data);
         }
         //it's required to place a PluginResponseInterface as response, so
         //PluginResponseListener::onKernelResponse can correctly identify it
         //and set it as response for this plugin content, so ContentTypes\TypePlugin
         //can place the correct response at the correct position, without executing
         //the plugin twice.
         $event->setResponse($response);
     } else {
         //we hit a plugin route, but it has responsed with NULL
         //this means it is not responsible for this route/slug.
         //we need now to remove this plugin route from the route collection
         //and fire again a sub request until all plugins on this page
         //are handled. If no plugin is responsible for this url pattern
         //and the main page route is also not responsible
         //no response is set in the $event and a 404 is thrown by the HttpKernel.
         $foundRoute = false;
         $routes = $this->frontendRouteListener->getRoutes();
         foreach ($routes as $idx => $route) {
             /** @var \Symfony\Component\Routing\Route $route */
             if ($content === $route->getDefault('_content')) {
                 //remove exactly only the current plugin that was hit in this sub request
                 $routes->remove($idx);
                 $foundRoute = true;
                 break;
             }
         }
         if ($foundRoute) {
             //we've removed the route and fire now again a sub request
             $request = clone $this->pageStack->getRequest();
             $request->attributes = new ParameterBag();
             $response = $this->kernel->handle($request, HttpKernelInterface::SUB_REQUEST);
             $event->setResponse($response);
         }
         //we do not need to restore routes in the frontendRouteListener, because
         //it reload all routes on every master request
     }
 }
Ejemplo n.º 4
0
 public function showAction()
 {
     return $this->pageResponseFactory->createFromRoute();
 }
Ejemplo n.º 5
0
 public function onKernelRequest(GetResponseEvent $event)
 {
     $request = $event->getRequest();
     if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) {
         //we need to reset all routes. They will anyway replaced by FrontendRouter::loadRoutes,
         //but to prevent caching conflicts, when a user removes a plugin for example
         //from a page, we need to know that without using actual caching.
         $this->routes = new RouteCollection();
         $this->urlMatcher->__construct($this->routes, $this->requestContext);
         //prepare for new master request: clear the PageResponse object
         $this->pageStack->setCurrentPage(null);
         $this->pageStack->setCurrentDomain(null);
         $this->pageStack->setPageResponse($this->pageResponseFactory->create());
         $this->frontendRouter->setRequest($request);
         $editorNodeId = (int) $this->pageStack->getRequest()->get('_jarves_editor_node');
         $editorDomainId = (int) $this->pageStack->getRequest()->get('_jarves_editor_domain');
         $domain = null;
         if ($editorDomainId) {
             $domain = $this->pageStack->getDomain($editorDomainId);
             if (!$domain) {
                 //we haven't found any domain that is responsible for this request
                 return;
             }
             $this->pageStack->setCurrentDomain($domain);
         }
         if ($editorNodeId) {
             //handle jarves content editor stuff
             //access is later checked
             if (!$editorNodeId && $domain) {
                 $editorNodeId = $domain->getStartnodeId();
             }
             $page = $this->pageStack->getPage($editorNodeId);
             if (!$page || !$page->isRenderable()) {
                 //we haven't found any page that is responsible for this request
                 return;
             }
             if (!$domain) {
                 $domain = $this->pageStack->getDomain($page->getDomainId());
             }
             $this->pageStack->setCurrentPage($page);
             $this->pageStack->setCurrentDomain($domain);
             $request->attributes->set('_controller', 'jarves.page_controller:handleAction');
         } else {
             //regular frontend route search
             //search domain
             if (!$domain) {
                 $domain = $this->frontendRouter->searchDomain();
                 if (!$domain) {
                     //we haven't found any domain that is responsible for this request
                     return;
                 }
                 $this->pageStack->setCurrentDomain($domain);
             }
             //search page
             $page = $this->frontendRouter->searchPage();
             if (!$page || !$page->isRenderable()) {
                 //we haven't found any page that is responsible for this request
                 return;
             }
             $this->pageStack->setCurrentPage($page);
             if ($response = $this->frontendRouter->loadRoutes($this->routes, $page)) {
                 //loadRoutes return in case of redirects and permissions a redirect or 404 response.
                 $event->setResponse($response);
                 return;
             }
             try {
                 //check routes in $this->route
                 parent::onKernelRequest($event);
             } catch (MethodNotAllowedException $e) {
             } catch (NotFoundHttpException $e) {
             }
         }
     }
 }