/**
  * 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);
 }
 /**
  * Perform the advanced node action
  */
 public function indexAction(Cms $cms, SecurityManager $securityManager, $locale, $site, $revision, $node)
 {
     if (!$cms->resolveNode($site, $revision, $node)) {
         return;
     }
     $this->setContentLocale($locale);
     $cms->setLastAction(self::NAME);
     $translator = $this->getTranslator();
     $referer = $this->request->getQueryParameter('referer');
     $security = $node->get(Node::PROPERTY_SECURITY, 'inherit', false);
     switch ($security) {
         case 'inherit':
         case Node::AUTHENTICATION_STATUS_EVERYBODY:
         case Node::AUTHENTICATION_STATUS_ANONYMOUS:
             $permissions = null;
             break;
         case Node::AUTHENTICATION_STATUS_AUTHENTICATED:
         default:
             $permissions = array_flip(explode(',', $security));
             $security = Node::AUTHENTICATION_STATUS_AUTHENTICATED;
             break;
     }
     $data = array('published' => $node->get(Node::PROPERTY_PUBLISH, 'inherit', false), 'publishStart' => $node->get(Node::PROPERTY_PUBLISH_START, null, false), 'publishStop' => $node->get(Node::PROPERTY_PUBLISH_STOP, null, false), 'security' => $security, 'permissions' => $permissions);
     $permissions = $securityManager->getSecurityModel()->getPermissions();
     $nodeType = $cms->getNodeType($node);
     $isFrontendNode = $nodeType->getFrontendCallback() || $node->getLevel() === 0 ? true : false;
     if ($isFrontendNode) {
         $data['hide'] = array();
         if ($node->hideInMenu()) {
             $data['hide']['menu'] = 'menu';
         }
         if ($node->hideInBreadcrumbs()) {
             $data['hide']['breadcrumbs'] = 'breadcrumbs';
         }
         if ($node->hideForAnonymousUsers()) {
             $data['hide']['anonymous'] = 'anonymous';
         }
         if ($node->hideForAuthenticatedUsers()) {
             $data['hide']['authenticated'] = 'authenticated';
         }
     }
     $form = $this->createFormBuilder($data);
     $form->addRow('published', 'option', array('label' => $translator->translate('label.publish'), 'options' => $this->getPublishedOptions($node, $translator)));
     $form->addRow('publishStart', 'string', array('label' => $translator->translate('label.publish.start'), 'description' => $translator->translate('label.publish.start.description'), 'filters' => array('trim' => array()), 'validators' => array('regex' => array('required' => false, 'regex' => '/2([0-9]){3}-([0-9]){2}-([0-9]){2} ([0-9]){2}:([0-9]){2}:([0-9]){2}/', 'error.regex' => 'error.validation.date.cms'))));
     $form->addRow('publishStop', 'string', array('label' => $translator->translate('label.publish.stop'), 'filters' => array('trim' => array()), 'validators' => array('regex' => array('required' => false, 'regex' => '/2([0-9]){3}-([0-9]){2}-([0-9]){2} ([0-9]){2}:([0-9]){2}:([0-9]){2}/', 'error.regex' => 'error.validation.date.cms'))));
     $form->addRow('security', 'option', array('label' => $translator->translate('label.allow'), 'attributes' => array('data-toggle-dependant' => 'option-security'), 'options' => $this->getSecurityOptions($node, $translator), 'validators' => array('required' => array())));
     if ($permissions) {
         $form->addRow('permissions', 'option', array('label' => $translator->translate('label.permissions.required'), 'attributes' => array('class' => 'option-security option-security-authenticated'), 'multiple' => true, 'options' => $permissions));
     }
     if ($isFrontendNode) {
         $form->addRow('hide', 'option', array('label' => $translator->translate('label.hide'), 'options' => array('menu' => $translator->translate('label.hide.menu'), 'breadcrumbs' => $translator->translate('label.hide.breadcrumbs'), 'anonymous' => $translator->translate('label.hide.anonymous'), 'authenticated' => $translator->translate('label.hide.authenticated')), 'multiple' => true));
     }
     $form = $form->build();
     if ($form->isSubmitted()) {
         try {
             $form->validate();
             $data = $form->getData();
             $security = $this->getSecurityValue($data['security']);
             if ($security == Node::AUTHENTICATION_STATUS_AUTHENTICATED && $permissions && $data['permissions']) {
                 $security = implode(',', $data['permissions']);
             }
             $node->set(Node::PROPERTY_PUBLISH, $this->getPublishedValue($data['published']));
             $node->set(Node::PROPERTY_PUBLISH_START, $data['publishStart']);
             $node->set(Node::PROPERTY_PUBLISH_STOP, $data['publishStop']);
             $node->set(Node::PROPERTY_SECURITY, $security);
             if ($isFrontendNode) {
                 if ($node->getLevel() === 0) {
                     $inherit = false;
                 } else {
                     $inherit = null;
                 }
                 $node->setHideInMenu(isset($data['hide']['menu']), $inherit);
                 $node->setHideInBreadcrumbs(isset($data['hide']['breadcrumbs']), $inherit);
                 $node->setHideForAnonymousUsers(isset($data['hide']['anonymous']), $inherit);
                 $node->setHideForAuthenticatedUsers(isset($data['hide']['authenticated']), $inherit);
             }
             $cms->saveNode($node, 'Set visibility of ' . $node->getName());
             $this->addSuccess('success.node.saved', array('node' => $node->getName($locale)));
             $url = $this->getUrl(self::ROUTE, array('site' => $site->getId(), 'revision' => $node->getRevision(), 'locale' => $locale, 'node' => $node->getId()));
             if ($referer) {
                 $url .= '?referer=' . urlencode($referer);
             }
             $this->response->setRedirect($url);
             return;
         } catch (ValidationException $exception) {
             $validationException = new ValidationException();
             $errors = $exception->getAllErrors();
             foreach ($errors as $field => $fieldErrors) {
                 if ($field == Node::PROPERTY_PUBLISH) {
                     $validationException->addErrors('published', $fieldErrors);
                 } elseif ($field == Node::PROPERTY_PUBLISH_START) {
                     $validationException->addErrors('publishStart', $fieldErrors);
                 } elseif ($field == Node::PROPERTY_PUBLISH_STOP) {
                     $validationException->addErrors('publishStop', $fieldErrors);
                 } else {
                     $validationException->addErrors($field, $fieldErrors);
                 }
             }
             $this->setValidationException($validationException, $form);
         }
     }
     $view = $this->setTemplateView('cms/backend/node.visibility', array('site' => $site, 'node' => $node, 'form' => $form->getView(), 'referer' => $referer, 'locale' => $locale, 'locales' => $cms->getLocales()));
     $form->processView($view);
 }
Beispiel #3
0
 /**
  * Gets whether the provided user is allowed to view this node
  * @param ride\library\security\SecurityManager $securityManager
  * @return boolean True if allowed, false otherwise
  */
 public function isAllowed(SecurityManager $securityManager)
 {
     $security = $this->get(self::PROPERTY_SECURITY, self::AUTHENTICATION_STATUS_EVERYBODY);
     if (!$security || $security === self::AUTHENTICATION_STATUS_EVERYBODY) {
         return true;
     }
     try {
         $user = $securityManager->getUser();
     } catch (AuthenticationException $exception) {
         $user = null;
     }
     if ($security === self::AUTHENTICATION_STATUS_ANONYMOUS) {
         if ($user) {
             return false;
         } else {
             return true;
         }
     }
     if (!$user) {
         return false;
     }
     if ($security === self::AUTHENTICATION_STATUS_AUTHENTICATED) {
         return true;
     }
     $isAllowed = true;
     $permissions = explode(',', $security);
     foreach ($permissions as $permission) {
         if (!$securityManager->isPermissionGranted($permission)) {
             $isAllowed = false;
             break;
         }
     }
     return $isAllowed;
 }
 /**
  * Action to dispatch to the properties of a widget
  * @param \ride\web\cms\Cms $cms
  * @param \ride\library\security\SecurityManager $securityManager
  * @param string $locale
  * @param string $site
  * @param string $revision
  * @param string $node
  * @param string $region
  * @param string $widget
  * @return null
  */
 public function indexAction(Cms $cms, SecurityManager $securityManager, $locale, $site, $revision, $node, $region, $widget)
 {
     if (!$cms->resolveNode($site, $revision, $node) || !$cms->resolveRegion($node, $locale, $region)) {
         return;
     }
     $widgetId = $widget;
     $widgetProperties = $node->getWidgetProperties($widgetId);
     $widget = $site->getWidget($widgetId);
     $widget = clone $cms->getWidget($widget);
     $widget->setRequest($this->request);
     $widget->setResponse($this->response);
     $widget->setProperties($widgetProperties);
     $widget->setLocale($locale);
     $widget->setRegion($region);
     if ($widget instanceof AbstractController) {
         $widget->setConfig($this->config);
         $widget->setDependencyInjector($this->dependencyInjector);
     }
     $translator = $this->getTranslator();
     $referer = $this->request->getQueryParameter('referer');
     $security = $widgetProperties->getWidgetProperty(Node::PROPERTY_SECURITY, Node::AUTHENTICATION_STATUS_EVERYBODY);
     switch ($security) {
         case 'inherit':
         case Node::AUTHENTICATION_STATUS_EVERYBODY:
         case Node::AUTHENTICATION_STATUS_ANONYMOUS:
             $permissions = null;
             break;
         case Node::AUTHENTICATION_STATUS_AUTHENTICATED:
         default:
             $permissions = array_flip(explode(',', $security));
             $security = Node::AUTHENTICATION_STATUS_AUTHENTICATED;
             break;
     }
     $data = array('published' => $widgetProperties->getWidgetProperty(Node::PROPERTY_PUBLISH, true), 'publishStart' => $widgetProperties->getWidgetProperty(Node::PROPERTY_PUBLISH_START, null), 'publishStop' => $widgetProperties->getWidgetProperty(Node::PROPERTY_PUBLISH_STOP, null), 'security' => $security, 'permissions' => $permissions);
     $permissions = $securityManager->getSecurityModel()->getPermissions();
     $form = $this->createFormBuilder($data);
     $form->addRow('published', 'option', array('label' => $translator->translate('label.publish'), 'options' => $this->getPublishedOptions($translator)));
     $form->addRow('publishStart', 'string', array('label' => $translator->translate('label.publish.start'), 'description' => $translator->translate('label.publish.start.description'), 'filters' => array('trim' => array()), 'validators' => array('regex' => array('required' => false, 'regex' => '/2([0-9]){3}-([0-9]){2}-([0-9]){2} ([0-9]){2}:([0-9]){2}:([0-9]){2}/', 'error.regex' => 'error.validation.date.cms'))));
     $form->addRow('publishStop', 'string', array('label' => $translator->translate('label.publish.stop'), 'filters' => array('trim' => array()), 'validators' => array('regex' => array('required' => false, 'regex' => '/2([0-9]){3}-([0-9]){2}-([0-9]){2} ([0-9]){2}:([0-9]){2}:([0-9]){2}/', 'error.regex' => 'error.validation.date.cms'))));
     $form->addRow('security', 'option', array('label' => $translator->translate('label.allow'), 'options' => $this->getSecurityOptions($translator), 'validators' => array('required' => array())));
     if ($permissions) {
         $form->addRow('permissions', 'option', array('label' => $translator->translate('label.permissions.required'), 'attributes' => array('class' => 'option-security option-security-authenticated'), 'multiple' => true, 'options' => $permissions));
     }
     $form = $form->build();
     if ($form->isSubmitted()) {
         try {
             $form->validate();
             $data = $form->getData();
             if ($data['security'] == Node::AUTHENTICATION_STATUS_AUTHENTICATED && $permissions && $data['permissions']) {
                 $data['security'] = implode(',', $data['permissions']);
             }
             $widgetProperties->setWidgetProperty(Node::PROPERTY_PUBLISH, $data['published']);
             $widgetProperties->setWidgetProperty(Node::PROPERTY_PUBLISH_START, $data['publishStart']);
             $widgetProperties->setWidgetProperty(Node::PROPERTY_PUBLISH_STOP, $data['publishStop']);
             $widgetProperties->setWidgetProperty(Node::PROPERTY_SECURITY, $data['security']);
             $cms->saveNode($node, 'Updated visibility properties for widget ' . $widgetId . ' in ' . $node->getName());
             $this->addSuccess('success.widget.saved', array('widget' => $translator->translate('widget.' . $widget->getName())));
             $this->response->setRedirect($this->getUrl('cms.node.content.region', array('locale' => $locale, 'site' => $site->getId(), 'revision' => $node->getRevision(), 'node' => $node->getId(), 'region' => $region)));
             return;
         } catch (ValidationException $exception) {
             $validationException = new ValidationException();
             $errors = $exception->getAllErrors();
             foreach ($errors as $field => $fieldErrors) {
                 if ($field == Node::PROPERTY_PUBLISH) {
                     $validationException->addErrors('published', $fieldErrors);
                 } elseif ($field == Node::PROPERTY_PUBLISH_START) {
                     $validationException->addErrors('publishStart', $fieldErrors);
                 } elseif ($field == Node::PROPERTY_PUBLISH_STOP) {
                     $validationException->addErrors('publishStop', $fieldErrors);
                 } else {
                     $validationException->addErrors($field, $fieldErrors);
                 }
             }
             $this->setValidationException($validationException, $form);
         }
     }
     $referer = $this->request->getQueryParameter('referer');
     $this->setTemplateView('cms/backend/widget.visibility', array('site' => $site, 'node' => $node, 'referer' => $referer, 'locale' => $locale, 'locales' => $cms->getLocales(), 'region' => $region, 'widget' => $widget, 'widgetId' => $widgetId, 'widgetName' => $translator->translate('widget.' . $widget->getName()), 'form' => $form->getView()));
 }