public function onKernelResponse(FilterResponseEvent $event) { $response = $event->getResponse(); if (null !== $response && $response instanceof PluginResponseInterface) { //when a route from a plugin is hit if (!$event->getRequest()->attributes->get('_jarves_is_plugin')) { //we accept only plugin routes. return; } $pageResponse = $this->pageStack->getPageResponse(); /** @var $content Content */ $content = $event->getRequest()->attributes->get('_content'); //this is later used in ContentTypes\TypePlugin, so it won't execute //the same plugin again. $pageResponse->setPluginResponse($content->getId(), $response); if (HttpKernelInterface::MASTER_REQUEST === $event->getRequestType()) { //when this was a master request, we need to render the actual content of the page, //so HttpKernel can return a valid ready rendered response //if a plugin route has been successfully requested //we need to handle also the Jarves editor if ($this->editMode->isEditMode()) { $this->editMode->registerEditor(); } $pageResponse->renderContent(); } //maintain the actual PageResponse $event->setResponse($pageResponse); } }
public function transform($text) { $parser = new MarkdownExtra(); $stylesAdded = false; if (class_exists('Kadet\\Highlighter\\Language\\Language')) { $parser->code_block_content_func = function ($code, $language) use(&$stylesAdded) { if (!$stylesAdded) { $this->pageStack->getPageResponse()->addCssFile('@Jarves/keylighter/default.scss'); $stylesAdded = true; } return Highlighter\highlight($code, Language::byName($language)); }; } return $parser->transform($text); }
/** * Injects all necessary files to get the Jarves Content Editor working * on the current page response. * * This register in `parent.jarves` a new jarves.Editor. */ public function registerEditor() { $this->addMainResources(['noJs' => true]); $this->addSessionScripts(); $page = $this->pageStack->getCurrentPage(); $response = $this->pageStack->getPageResponse(); $response->addJsFile('@JarvesBundle/admin/mootools-core-1.4.5-fixed-memory-leak.js'); $response->addJsFile('@JarvesBundle/admin/mootools-more.js'); $response->setResourceCompression(false); $response->setDomainHandling(false); $request = $this->pageStack->getRequest(); $nodeArray['id'] = $page->getId(); $nodeArray['title'] = $page->getTitle(); $nodeArray['domainId'] = $page->getDomainId(); $nodeArray['theme'] = $page->getTheme(); $nodeArray['layout'] = $request->query->get('_jarves_editor_layout') ?: $page->getLayout(); $domain = DomainQuery::create()->findPk($page->getDomainId()); $domainArray['id'] = $domain->getId(); $domainArray['domain'] = $domain->getDomain(); $domainArray['path'] = $domain->getPath(); $domainArray['theme'] = $domain->getTheme(); $domainArray['themeOptions'] = $domain->getThemeOptions(); $options = ['id' => $request->query->get('_jarves_editor_id'), 'node' => $nodeArray, 'domain' => $domainArray]; if (is_array($extraOptions = $request->query->get('_jarves_editor_options'))) { $options = array_merge($options, $extraOptions); $options['standalone'] = filter_var($options['standalone'], FILTER_VALIDATE_BOOLEAN); } $response->addJsAtBottom('window.editor = new parent.jarves.Editor(' . json_encode($options) . ', document.documentElement);'); }
/** * 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']); }
/** * Build the page and return the PageResponse. * * Checks for links, mounts etc. * * @return Response * @throws AccessDeniedException * @throws \Exception */ public function handleAction() { $node = $this->pageStack->getCurrentPage(); //is link if ($node->getType() == 1) { $to = $node->getLink(); if (!$to) { throw new \Exception('Redirect failed: ' . sprintf('Current page with title %s has no target link.', $node->getTitle())); } if (intval($to) > 0) { return new RedirectResponse($this->pageStack->getNodeUrl($to), 301); } else { return new RedirectResponse($to, 301); } } if ($this->editMode->isEditMode()) { $this->editMode->registerEditor(); } $pageResponse = $this->pageStack->getPageResponse(); $pageResponse->renderContent(); return $pageResponse; //new Response('<body>ho</body>'); }
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; }
public function render() { if ($response = $this->pageStack->getPageResponse()->getPluginResponse($this->getContent())) { return $response->getContent(); } elseif ($this->plugin) { $config = $this->jarves->getConfig($this->bundleName); if (!$config) { return sprintf('Bundle `%s` does not exist. You probably have to install this bundle.', $this->bundleName); } if ($this->pluginDef = $config->getPlugin($this->plugin['plugin'])) { $controller = $this->pluginDef->getController(); if ($this->isPreview()) { if (!$this->pluginDef->isPreview()) { //plugin does not allow to have a preview on the actual action method return ($config->getLabel() ?: $config->getBundleName()) . ': ' . $this->pluginDef->getLabel(); } } //create a sub request $request = new Request(); $request->attributes->add(array('_controller' => $controller, '_content' => $this->getContent(), '_jarves_is_plugin' => true, 'options' => isset($this->plugin['options']) ? $this->plugin['options'] : array())); $dispatcher = $this->eventDispatcher; $callable = array($this, 'exceptionHandler'); $fixResponse = array($this, 'fixResponse'); $dispatcher->addListener(KernelEvents::EXCEPTION, $callable, 100); $dispatcher->addListener(KernelEvents::VIEW, $fixResponse, 100); ob_start(); $response = $this->kernel->handle($request, HttpKernelInterface::SUB_REQUEST); //EventListener\PluginRequestListener converts all PluginResponse objects to PageResponses if ($response instanceof PageResponse) { if ($pluginResponse = $response->getPluginResponse($this->getContent()->getId())) { $response = $pluginResponse; } } // if ($response instanceof PageResponse) { // if ($response->getPluginResponse($this->getContent()->getId())) { // $response = $response->getPluginResponse($this->getContent()->getId()); // } // } $ob = ob_get_clean(); $dispatcher->removeListener(KernelEvents::EXCEPTION, $callable); $dispatcher->removeListener(KernelEvents::VIEW, $fixResponse); return trim($ob) . $response->getContent(); } else { return sprintf('Plugin `%s` in bundle `%s` does not exist. You probably have to install the bundle first.', $this->plugin['plugin'], $this->bundleName); } } }
/** * @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; }
public function loadAssetAtBottom($asset, $contentType = null) { $this->pageStack->getPageResponse()->loadAssetFileAtBottom($asset, $contentType); }