/** * Checks if this action is available for the node * @param \ride\library\cms\node\Node $node * @return boolean True if available */ public function isAvailableForNode(Node $node) { if (!$node->getParent()) { return true; } $nodeType = $this->cms->getNodeType($node); return $nodeType->getFrontendCallback() ? true : false; }
/** * Checks if this action is available for the node * @param \ride\library\cms\node\Node $node * @return boolean True if available */ public function isAvailableForNode(Node $node) { if (!$node->getParent()) { return !$node->isAutoPublish(); } $nodeType = $this->cms->getNodeType($node); $isAvailable = $nodeType->getFrontendCallback() ? true : false; return $isAvailable && !$node->getRootNode()->isAutoPublish(); }
/** * Removes a node * @param \ride\library\cms\node\Node $node Node to delete * @param boolean $recursive Flag to see if child nodes should be deleted * @return */ public function removeNode(Node $node, $recursive = true) { $siteId = $node->getRootNodeId(); $revision = $node->getRevision(); $parent = $node->getParent(); $path = $node->getPath(); $orderIndex = $node->getOrderIndex(); $baseOrderIndex = $orderIndex - 1; $changedNodes = array(); // remove children or move the children the the parent's path $numChildren = 0; $children = $this->getNodesByPath($siteId, $revision, $path); foreach ($children as $child) { if ($recursive) { $this->removeNode($child, true); continue; } $childParent = $child->getParent(); if ($childParent === $path) { $child->setOrderIndex($baseOrderIndex + $child->getOrderIndex()); $numChildren++; } $child->setParent(str_replace($path, $parent, $childParent)); $changedNodes[] = $child; } if (!$recursive) { // fix order index for nodes after the removed node $siblings = $this->getChildren($node->getRootNodeId(), $node->getRevision(), $parent, 0); foreach ($siblings as $sibling) { $siblingOrderIndex = $sibling->getOrderIndex(); if ($siblingOrderIndex <= $orderIndex) { continue; } $sibling->setOrderIndex($siblingOrderIndex + $numChildren - 1); $changedNodes[] = $sibling; } } // save and remove the necessairy nodes foreach ($changedNodes as $changedNode) { $this->setNode($changedNode); } $this->deleteNode($node); unset($this->nodes[$siteId][$revision][$node->getId()]); }
/** * Perform the actual publishing of a single node * @param \ride\library\cms\node\SiteNode $site * @param \ride\library\cms\node\Node $node * @param string $revision * @param \ride\library\system\file\File $publishDirectory * @param boolean $isRecursive Flag to see if this publishing is part of a * recursive publish action * @return null */ protected function publishNode(SiteNode $site, Node $node, $revision, File $publishDirectory, $isRecursive) { // initialize needed variables $siteId = $site->getId(); $nodeId = $node->getId(); $changedNodes = array(); try { $publishSite = $this->getSite($siteId, $revision); } catch (NodeNotFoundException $exception) { $publishSite = null; } // process and merge the necessairy nodes try { $oldNode = $this->getNode($siteId, $revision, $nodeId); // check for expired routes $oldRoutes = $oldNode->getRoutes(); $newRoutes = $node->getRoutes(); if ($oldRoutes && $oldRoutes !== $newRoutes) { foreach ($oldRoutes as $locale => $route) { if (isset($newRoutes[$locale]) && $route === $newRoutes[$locale]) { continue; } $this->expiredRouteModel->addExpiredRoute($siteId, $nodeId, $locale, $route, $site->getBaseUrl($locale)); } } // check for order conflicts $nodeOrderIndex = $node->getOrderIndex(); $nodeParent = $node->getParent(); if (!$isRecursive && ($nodeOrderIndex != $oldNode->getOrderIndex() || $nodeParent != $oldNode->getParent())) { $orderIndex = 0; $parentNodes = $this->getChildren($siteId, $revision, $nodeParent, 0); foreach ($parentNodes as $parentNodeId => $parentNode) { $orderIndex++; $parentOrderIndex = $parentNode->getOrderIndex(); $isBefore = $parentOrderIndex < $nodeOrderIndex; if ($isBefore && $parentOrderIndex == $orderIndex) { continue; } elseif ($nodeOrderIndex == $parentOrderIndex && $nodeId != $parentNodeId) { $orderIndex++; $parentNode->setOrderIndex($orderIndex); $changedNodes[] = $parentNode; } elseif ($nodeId == $parentNodeId) { $orderIndex--; continue; } else { $parentNode->setOrderIndex($orderIndex); $changedNodes[] = $parentNode; } } } } catch (NodeNotFoundException $exception) { // new node in the revision } // check for new widgets if ($publishSite) { $isPublishSiteChanged = false; $usedWidgets = $node->getUsedWidgets(); $availableWidgetsSite = $site->getAvailableWidgets(); $availableWidgetsPublishSite = $publishSite->getAvailableWidgets(); foreach ($usedWidgets as $widgetId) { if (!$widgetId || isset($availableWidgetsPublishSite[$widgetId]) || !isset($availableWidgetsSite[$widgetId])) { continue; } $publishSite->set(Node::PROPERTY_WIDGET . '.' . $widgetId, $availableWidgetsSite[$widgetId], true); $isPublishSiteChanged = true; } if ($isPublishSiteChanged) { $changedNodes[] = $publishSite; } } // write the changed nodes foreach ($changedNodes as $changedNode) { $this->writeNode($changedNode); } // write the node file to the publish directory $nodeFile = $this->getNodeFile($node); $publishFile = $publishDirectory->getChild($nodeFile->getName()); if ($nodeFile->exists()) { // node has been created or updated $nodeFile->copy($publishFile); return null; } elseif ($publishFile->exists()) { // node has been deleted $publishFile->delete(); return $node; } }
/** * Cleans up all properties in the provided node which are used one of the * provided widgets * @param \ride\library\cms\node\Node $node * @param array $unusedWidgetd Array with the widget instance id as key * @return boolean Flag to see if the node has changed */ protected function clearWidgetUsage(Node $node, array $unusedWidgets) { $isChanged = false; $isRootNode = $node->getParent() ? false : true; $properties = $node->getProperties(); foreach ($unusedWidgets as $widgetId => $null) { foreach ($properties as $key => $property) { if (strpos($key, Node::PROPERTY_WIDGET . '.' . $widgetId . '.') === 0 || $isRootNode && $key === Node::PROPERTY_WIDGET . '.' . $widgetId) { $node->set($key, null); $isChanged = true; } } } return $isChanged; }
/** * Validates the route of the node * @param \ride\library\cms\node\Node $node Node to be validated * @param \ride\library\cms\node\NodeModel $nodeModel Model of the nodes * @param \ride\library\validation\exception\ValidationException $exception * @return null */ protected function validateRoute(Node $node, NodeModel $nodeModel, ValidationException $exception) { if (!$node->getParent()) { return; } $rootNode = $node->getRootNode(); $rootNodeId = $rootNode->getId(); $nodeId = $node->getId(); $modelNodes = $nodeModel->getNodes($rootNodeId, $node->getRevision()); $propertyPrefix = Node::PROPERTY_ROUTE . '.'; $lengthPropertyPrefix = strlen($propertyPrefix); // loop all properties $properties = $node->getProperties(); foreach ($properties as $key => $property) { if (strpos($key, $propertyPrefix) !== 0) { // we're only interested in route properties continue; } $routeLocale = substr($key, $lengthPropertyPrefix); $route = $property->getValue(); // normalize route $route = trim($route, '/'); $baseUrls[$routeLocale] = $rootNode->getBaseUrl($routeLocale); $tokens = explode('/', $route); foreach ($tokens as $index => $token) { if ($token) { $token = StringHelper::safeString($token); } if (empty($token)) { unset($tokens[$index]); } else { $tokens[$index] = $token; } } $route = '/' . implode('/', $tokens); // check for duplicate routes $errors = array(); foreach ($modelNodes as $modelNode) { $modelNodeId = $modelNode->getId(); if ($modelNodeId == $nodeId || $modelNode->getRootNodeId() != $rootNodeId || !$modelNode->hasParent() || $modelNode->getType() == ReferenceNodeType::NAME) { // same node, different site or root node or a reference node continue; } $modelNodeRoutes = $modelNode->getRoutes(); foreach ($modelNodeRoutes as $locale => $modelNodeRoute) { if (!array_key_exists($locale, $baseUrls)) { $baseUrls[$locale] = $rootNode->getBaseUrl($locale); } if ($baseUrls[$routeLocale] . $route != $baseUrls[$locale] . $modelNodeRoute) { continue; } $errors[$modelNodeId] = new ValidationError('error.route.used.node', "Route '%route%' is already used by node %node% in locale %locale%", array('route' => $route, 'node' => $modelNodeId, 'locale' => $locale)); } } foreach ($errors as $error) { $exception->addErrors(Node::PROPERTY_ROUTE, array($error)); } // update property with normalized route $property->setValue($route); } }
/** * Gets an array of a node with all it's properties * @param \ride\library\cms\node\Node $node * @return array */ protected function getArrayFromNode(Node $node) { $array = array(); $array[self::PROPERTY_TYPE] = new NodeProperty(self::PROPERTY_TYPE, $node->getType()); $array[self::PROPERTY_ID] = new NodeProperty(self::PROPERTY_ID, $node->getId()); $array[self::PROPERTY_PARENT] = new NodeProperty(self::PROPERTY_PARENT, $node->getParent()); $array[self::PROPERTY_ORDER] = new NodeProperty(self::PROPERTY_ORDER, $node->getOrderIndex()); $array += $node->getProperties(); return $array; }