/** * Clones the node's properties to the destination * @param \ride\library\cms\node\Node $source Source node * @param \ride\library\cms\node\Node $destination Destination node * @param boolean $keepOriginalName Set to true to keep the name untouched * @param boolean $cloneRoutes Set to true to clone the routes of the nodes * @return null */ protected function cloneNodeProperties(Node $source, Node $destination, $keepOriginalName, $cloneRoutes) { $widgetPropertyPrefixLength = strlen(Node::PROPERTY_WIDGET) + 1; try { $site = $destination->getRootNode(); } catch (CmsException $exception) { $site = $destination; } $parent = $source->getParentNode(); $sourceProperties = $source->getProperties(); $destinationProperties = array(); // duplicate the regions and the set widgets foreach ($sourceProperties as $index => $sourceProperty) { $key = $sourceProperty->getKey(); if (strpos($key, Node::PROPERTY_REGION) !== 0 || !strpos($key, '.' . Node::PROPERTY_WIDGETS)) { continue; } $tokens = explode('.', $key); $region = $tokens[1]; $section = $tokens[2]; $newValue = array(); $inheritedWidgetIds = array(); if ($parent) { $inheritedValue = $parent->get($key, null, true, true); if ($inheritedValue) { $inheritedWidgetIds = $source->parseSectionString($source->getRootNode(), $inheritedValue); } } $sourceWidgetIds = $source->parseSectionString($source->getRootNode(), $sourceProperty->getValue()); foreach ($sourceWidgetIds as $blockId => $blockWidgets) { $newValue[$blockId] = array(); foreach ($blockWidgets as $widgetId => $widget) { if (isset($this->widgetTable[$widgetId])) { $newWidgetId = $this->widgetTable[$widgetId]; } elseif (isset($inheritedWidgetIds[$blockId][$widgetId])) { // use the same widget id for inherited widgets $this->widgetTable[$widgetId] = $widgetId; $newWidgetId = $widgetId; } else { // create a new widget for node widgets $widget = $source->getWidget($widgetId); $newWidgetId = $site->createWidget($widget); $this->widgetTable[$widgetId] = $newWidgetId; } $newValue[$blockId][] = $newWidgetId; } $newValue[$blockId] = Node::BLOCK_OPEN . implode(NodeProperty::LIST_SEPARATOR, $newValue[$blockId]) . Node::BLOCK_CLOSE; } $destinationProperty = new NodeProperty($key, implode(NodeProperty::LIST_SEPARATOR, $newValue), $sourceProperty->getInherit()); $destinationProperties[$key] = $destinationProperty; unset($sourceProperties[$index]); } // duplicate the remaining properties foreach ($sourceProperties as $index => $sourceProperty) { $key = $sourceProperty->getKey(); $value = $sourceProperty->getValue(); $destinationProperty = new NodeProperty($key, $value, $sourceProperty->getInherit()); if (!$keepOriginalName && strpos($key, Node::PROPERTY_NAME . '.') === 0) { // add copy suffix to the name $locale = str_replace(Node::PROPERTY_NAME . '.', '', $key); if ($source->getLevel() === 0) { $children = $this->io->getSites(); } else { $children = $this->io->getChildren($source->getRootNodeId(), $source->getRevision(), $source->getParent(), 0); } $baseName = $value; $name = $baseName . ' (clone)'; $index = 2; do { $found = false; foreach ($children as $child) { $childName = $child->getName(); if ($childName == $name) { $name = $baseName . ' (clone ' . $index . ')'; $index++; $found = true; break; } } } while ($found); $destinationProperty->setValue($name); } elseif (!$cloneRoutes && strpos($key, Node::PROPERTY_ROUTE . '.') === 0) { // skip this property as it's a route and it's flagged to not clone routes continue; } elseif (strpos($key, Node::PROPERTY_WIDGET . '.') === 0) { // remap the widget ids for widget properties $propertyKey = substr($key, $widgetPropertyPrefixLength); $positionPropertySeparator = strpos($propertyKey, '.'); if ($positionPropertySeparator === false) { continue; } $widgetId = substr($propertyKey, 0, $positionPropertySeparator); $propertyKey = substr($propertyKey, $positionPropertySeparator); if (!isset($this->widgetTable[$widgetId])) { continue; } $destinationProperty = new NodeProperty(Node::PROPERTY_WIDGET . '.' . $this->widgetTable[$widgetId] . $propertyKey, $destinationProperty->getValue(), $destinationProperty->getInherit()); } $destinationProperties[$destinationProperty->getKey()] = $destinationProperty; } $destination->setProperties($destinationProperties); }