/** * Set the node title for the newly created Document node * * @param NodeInterface $node The newly created node * @param array $data incoming data from the creationDialog * @return void */ public function handle(NodeInterface $node, array $data) { if (isset($data['title']) && $node->getNodeType()->isOfType('TYPO3.Neos:Document')) { $node->setProperty('title', $data['title']); $node->setProperty('uriPathSegment', NodeUtility::renderValidNodeName($data['title'])); } }
/** * Helper method for creating a new node. * * @param NodeInterface $referenceNode * @param array $nodeData * @param string $position * @return NodeInterface * @throws \InvalidArgumentException */ public function create(NodeInterface $referenceNode, array $nodeData, $position) { if (!in_array($position, array('before', 'into', 'after'), true)) { throw new \InvalidArgumentException('The position should be one of the following: "before", "into", "after".', 1347133640); } $nodeType = $this->nodeTypeManager->getNodeType($nodeData['nodeType']); if ($nodeType->isOfType('TYPO3.Neos:Document') && !isset($nodeData['properties']['uriPathSegment']) && isset($nodeData['properties']['title'])) { $nodeData['properties']['uriPathSegment'] = Utility::renderValidNodeName($nodeData['properties']['title']); } $proposedNodeName = isset($nodeData['nodeName']) ? $nodeData['nodeName'] : null; $nodeData['nodeName'] = $this->nodeService->generateUniqueNodeName($this->getDesignatedParentNode($referenceNode, $position)->getPath(), $proposedNodeName); if ($position === 'into') { $newNode = $referenceNode->createNode($nodeData['nodeName'], $nodeType); } else { $parentNode = $referenceNode->getParent(); $newNode = $parentNode->createNode($nodeData['nodeName'], $nodeType); if ($position === 'before') { $newNode->moveBefore($referenceNode); } else { $newNode->moveAfter($referenceNode); } } if (isset($nodeData['properties']) && is_array($nodeData['properties'])) { foreach ($nodeData['properties'] as $propertyName => $propertyValue) { $newNode->setProperty($propertyName, $propertyValue); } } return $newNode; }
/** * @param NodeInterface $parentNode * @param NodeType $nodeType * @return NodeInterface|void */ public function create(NodeInterface $parentNode, NodeType $nodeType) { $title = Company::name(); $name = Utility::renderValidNodeName($title); $childrenNode = $parentNode->createNode($name, $nodeType); $childrenNode->setProperty('title', $title); return $childrenNode; }
/** * @param string $sitePackage * @param string $siteName * @param string $baseDomain * @return Site */ public function importSiteFromTemplate($sitePackage, $siteName, $baseDomain = '') { if (empty($baseDomain)) { $request = Request::createFromEnvironment(); $baseDomain = $request->getBaseUri()->getHost(); } $siteTemplate = new StandaloneView(); $siteTemplate->setTemplatePathAndFilename(FLOW_PATH_PACKAGES . 'Sites/' . $sitePackage . '/Resources/Private/Templates/Content/Sites.xml'); $siteTemplate->assignMultiple(['siteName' => $siteName, 'siteNodeName' => \TYPO3\TYPO3CR\Utility::renderValidNodeName($siteName), 'packageKey' => $sitePackage]); $generatedSiteImportXmlContent = $siteTemplate->render(); $dataTemporaryPath = $this->environment->getPathToTemporaryDirectory(); $temporarySiteXml = $dataTemporaryPath . uniqid($siteName) . '.xml'; file_put_contents($temporarySiteXml, $generatedSiteImportXmlContent); $site = $this->siteImportService->importFromFile($temporarySiteXml); $domain = new Domain(); $domain->setActive(true); $domain->setSite($site); $domain->setHostPattern(\TYPO3\TYPO3CR\Utility::renderValidNodeName($siteName) . '.' . $baseDomain); $this->domainRepository->add($domain); return $site; }
/** * Saves the given array as a node data entity without using the ORM. * * If the node data already exists (same dimensions, same identifier, same workspace) * it is replaced. * * @param array $nodeData node data to save as an associative array ( $column_name => $value ) * @throws ImportException * @return void */ protected function persistNodeData($nodeData) { if ($nodeData['workspace'] !== 'live') { throw new ImportException('Saving NodeData with workspace != "live" using direct SQL not supported yet. Workspace is "' . $nodeData['workspace'] . '".'); } if ($nodeData['path'] === '/') { return; } // cleanup old data /** @var \Doctrine\DBAL\Connection $connection */ $connection = $this->entityManager->getConnection(); // prepare node dimensions $dimensionValues = $nodeData['dimensionValues']; $dimensionsHash = Utility::sortDimensionValueArrayAndReturnDimensionsHash($dimensionValues); $jsonPropertiesDataTypeHandler = JsonArrayType::getType(JsonArrayType::FLOW_JSON_ARRAY); // post-process node data $nodeData['dimensionsHash'] = $dimensionsHash; $nodeData['dimensionValues'] = $jsonPropertiesDataTypeHandler->convertToDatabaseValue($dimensionValues, $connection->getDatabasePlatform()); $nodeData['properties'] = $jsonPropertiesDataTypeHandler->convertToDatabaseValue($nodeData['properties'], $connection->getDatabasePlatform()); $nodeData['accessRoles'] = $jsonPropertiesDataTypeHandler->convertToDatabaseValue($nodeData['accessRoles'], $connection->getDatabasePlatform()); $connection->executeQuery('DELETE FROM typo3_typo3cr_domain_model_nodedimension' . ' WHERE nodedata IN (' . ' SELECT persistence_object_identifier FROM typo3_typo3cr_domain_model_nodedata' . ' WHERE identifier = :identifier' . ' AND workspace = :workspace' . ' AND dimensionshash = :dimensionsHash' . ' )', array('identifier' => $nodeData['identifier'], 'workspace' => $nodeData['workspace'], 'dimensionsHash' => $nodeData['dimensionsHash'])); /** @var \Doctrine\ORM\QueryBuilder $queryBuilder */ $queryBuilder = $this->entityManager->createQueryBuilder(); $queryBuilder->delete()->from('TYPO3\\TYPO3CR\\Domain\\Model\\NodeData', 'n')->where('n.identifier = :identifier')->andWhere('n.dimensionsHash = :dimensionsHash')->andWhere('n.workspace = :workspace')->setParameter('identifier', $nodeData['identifier'])->setParameter('workspace', $nodeData['workspace'])->setParameter('dimensionsHash', $nodeData['dimensionsHash']); $queryBuilder->getQuery()->execute(); // insert new data // we need to use executeUpdate to execute the INSERT -- else the data types are not taken into account. // That's why we build a DQL INSERT statement which is then executed. $queryParts = array(); $queryArguments = array(); $queryTypes = array(); foreach ($this->nodeDataPropertyNames as $propertyName => $propertyConfig) { if (isset($nodeData[$propertyName])) { $queryParts[$propertyName] = ':' . $propertyName; $queryArguments[$propertyName] = $nodeData[$propertyName]; if (isset($propertyConfig['columnType'])) { $queryTypes[$propertyName] = $propertyConfig['columnType']; } } } $connection->executeUpdate('INSERT INTO typo3_typo3cr_domain_model_nodedata (' . implode(', ', array_keys($queryParts)) . ') VALUES (' . implode(', ', $queryParts) . ')', $queryArguments, $queryTypes); foreach ($dimensionValues as $dimension => $values) { foreach ($values as $value) { $nodeDimension = array('persistence_object_identifier' => Algorithms::generateUUID(), 'nodedata' => $nodeData['Persistence_Object_Identifier'], 'name' => $dimension, 'value' => $value); $connection->insert('typo3_typo3cr_domain_model_nodedimension', $nodeDimension); } } }
/** * Creates a new node beneath $parent * * @param NodeInterface $parent * @return NodeInterface */ protected function createNode(NodeInterface $parent) { $nodeType = $this->getNodeType(); $initialProperties = $this->getInitialProperties(); $name = $this->getName() ?: $this->nodeService->generateUniqueNodeName($parent->getPath()); // // If we're about to create a document, check for the presence of the uriPathSegment property first // and create it, if it's missing // if ($nodeType->isOfType('TYPO3.Neos:Document') && !isset($initialProperties['uriPathSegment'])) { if (!isset($initialProperties['title'])) { throw new \IllegalArgumentException('You must either provide a title or a uriPathSegment in order to create a document.', 1452103891); } $initialProperties['uriPathSegment'] = NodeUtility::renderValidNodeName($initialProperties['title']); } $node = $parent->createNode($name, $nodeType); foreach ($initialProperties as $key => $value) { $node->setProperty($key, $value); } return $node; }
/** * Create a workspace * * @Flow\Validate(argumentName="title", type="\TYPO3\Flow\Validation\Validator\NotEmptyValidator") * @param string $title Human friendly title of the workspace, for example "Christmas Campaign" * @param Workspace $baseWorkspace Workspace the new workspace should be based on * @param string $visibility Visibility of the new workspace, must be either "internal" or "shared" * @param string $description A description explaining the purpose of the new workspace * @return void */ public function createAction($title, Workspace $baseWorkspace, $visibility, $description = '') { $workspace = $this->workspaceRepository->findOneByTitle($title); if ($workspace instanceof Workspace) { $this->addFlashMessage($this->translator->translateById('workspaces.workspaceWithThisTitleAlreadyExists', [], null, null, 'Modules', 'TYPO3.Neos'), '', Message::SEVERITY_WARNING); $this->redirect('new'); } $workspaceName = Utility::renderValidNodeName($title) . '-' . substr(base_convert(microtime(false), 10, 36), -5, 5); while ($this->workspaceRepository->findOneByName($workspaceName) instanceof Workspace) { $workspaceName = Utility::renderValidNodeName($title) . '-' . substr(base_convert(microtime(false), 10, 36), -5, 5); } if ($visibility === 'private') { $owner = $this->userService->getCurrentUser(); } else { $owner = null; } $workspace = new Workspace($workspaceName, $baseWorkspace, $owner); $workspace->setTitle($title); $workspace->setDescription($description); $this->workspaceRepository->add($workspace); $this->redirect('index'); }
/** * Traverses through the tree starting at the given root node and sets the uriPathSegment property derived from * the node label. * * @param NodeInterface $node The node where the traversal starts * @param boolean $dryRun * @return void */ protected function generateUriPathSegmentsForNode(NodeInterface $node, $dryRun) { if ((string) $node->getProperty('uriPathSegment') === '') { $name = $node->getLabel() ?: $node->getName(); $uriPathSegment = Utility::renderValidNodeName($name); if ($dryRun === FALSE) { $node->setProperty('uriPathSegment', $uriPathSegment); $this->output->outputLine('Added missing URI path segment for "%s" (%s) => %s', array($node->getPath(), $name, $uriPathSegment)); } else { $this->output->outputLine('Found missing URI path segment for "%s" (%s) => %s', array($node->getPath(), $name, $uriPathSegment)); } } foreach ($node->getChildNodes('TYPO3.Neos:Document') as $childNode) { $this->generateUriPathSegmentsForNode($childNode, $dryRun); } }
/** * Checks if the given $nodeType is allowed as a childNode of the given $childNodeName * (which must be auto-created in $this NodeType). * * Only allowed to be called if $childNodeName is auto-created. * * @param string $childNodeName The name of a configured childNode of this NodeType * @param NodeType $nodeType The NodeType to check constraints for. * @return boolean TRUE if the $nodeType is allowed as grandchild node, FALSE otherwise. * @throws \InvalidArgumentException If the given $childNodeName is not configured to be auto-created in $this. */ public function allowsGrandchildNodeType($childNodeName, NodeType $nodeType) { $autoCreatedChildNodes = $this->getAutoCreatedChildNodes(); if (!isset($autoCreatedChildNodes[$childNodeName])) { throw new \InvalidArgumentException('The method "allowsGrandchildNodeType" can only be used on auto-created childNodes, given $childNodeName "' . $childNodeName . '" is not auto-created.', 1403858395); } $constraints = $autoCreatedChildNodes[$childNodeName]->getConfiguration('constraints.nodeTypes') ?: array(); $childNodeConfiguration = []; foreach ($this->getConfiguration('childNodes') as $name => $configuration) { $childNodeConfiguration[Utility::renderValidNodeName($name)] = $configuration; } $childNodeConstraintConfiguration = ObjectAccess::getPropertyPath($childNodeConfiguration, $childNodeName . '.constraints.nodeTypes') ?: array(); $constraints = Arrays::arrayMergeRecursiveOverrule($constraints, $childNodeConstraintConfiguration); return $this->isNodeTypeAllowedByConstraints($nodeType, $constraints); }
/** * @param Account $account * @param NodeInterface $userStorageNode * @param PersonDto $person * @return NodeInterface|string */ protected function createProfileNode(Account $account, NodeInterface $userStorageNode, PersonDto $person) { try { $profileNode = $this->findProfileNode($person->getEmailAddress()); if ($profileNode === NULL) { $properties = ['title' => $person->getFirstName() . ' ' . $person->getLastName(), 'firstName' => $person->getFirstName(), 'lastName' => $person->getLastName(), 'address' => $person->getAddress(), 'zipCode' => $person->getZipCode(), 'city' => $person->getCity(), 'emailAddress' => $person->getEmailAddress(), 'phone' => $person->getPhone(), 'dateOfBirth' => $person->getDateOfBirth(), 'jiuJitsu' => $person->getJiuJitsu(), 'buJitsuDo' => $person->getBuJitsuDo(), 'jiuJitsuDegree' => $person->getJiuJitsuDegree(), 'buJitsuDoDegree' => $person->getBuJitsuDoDegree(), 'gender' => $person->getGender()]; if ($person->getFirstName() && $person->getLastName()) { $nodeName = $person->getFirstName() . ' ' . $person->getLastName(); } $idealNodeName = Utility::renderValidNodeName(isset($nodeName) ? $nodeName : uniqid('node')); $idealNodeName = htmlspecialchars($idealNodeName, ENT_NOQUOTES, 'UTF-8'); $profileNode = $this->nodeWriteRepository->createChildNode($userStorageNode, $idealNodeName, 'BuJitsuDo.Authentication:Person', $properties); if ($person->getImage() instanceof Image) { $profileNode = $this->profileService->setImageToNode($profileNode, $person->getImage(), $person->getFirstName(), 'Profile images'); } } $account->getParty()->getPreferences()->set('profileNodeIdentifier', $profileNode->getIdentifier()); $this->partyRepository->update($account->getParty()); $this->persistenceManager->persistAll(); $this->emitPersonCreated($profileNode); return $profileNode; } catch (\Exception $exception) { $this->systemLogger->log('Profile node could not be created because: ' . $exception->getMessage(), LOG_CRIT); return $exception->getMessage(); } }
/** * Get the name of this node template. * * If a name has been set using setName(), it is returned. If not, but the * template has a (non-empty) title property, this property is used to * generate a valid name. As a last resort a random name is returned (in * the form "nameXXXXX"). * * @return string * @api */ public function getName() { if ($this->name !== NULL) { return $this->name; } if ($this->hasProperty('title') && strlen($this->getProperty('title')) > 0) { return \TYPO3\TYPO3CR\Utility::renderValidNodeName($this->getProperty('title')); } return uniqid('node'); }
/** * Returns a camelcase version of $name with the first letter uppercase. * * @param string $name * @return string */ public static function renderValidName($name) { return preg_replace('/\\s+/', '', ucwords(str_replace('-', ' ', \TYPO3\TYPO3CR\Utility::renderValidNodeName($name)))); }
/** * @test * @dataProvider sourcesAndNodeNames */ public function renderValidNodeNameWorks($source, $expectedNodeName) { $this->assertEquals($expectedNodeName, Utility::renderValidNodeName($source)); }
/** * Create missing child nodes for the given node type * * @param NodeType $nodeType * @param string $workspaceName * @param boolean $dryRun * @return void */ protected function createChildNodesByNodeType(NodeType $nodeType, $workspaceName, $dryRun) { $createdNodesCount = 0; $updatedNodesCount = 0; $nodeCreationExceptions = 0; $nodeIdentifiersWhichNeedUpdate = []; $nodeTypes = $this->nodeTypeManager->getSubNodeTypes($nodeType->getName(), false); $nodeTypes[$nodeType->getName()] = $nodeType; if ($this->nodeTypeManager->hasNodeType((string) $nodeType)) { $nodeType = $this->nodeTypeManager->getNodeType((string) $nodeType); $nodeTypeNames[$nodeType->getName()] = $nodeType; } else { $this->output->outputLine('Node type "%s" does not exist', array((string) $nodeType)); exit(1); } /** @var $nodeType NodeType */ foreach ($nodeTypes as $nodeTypeName => $nodeType) { $childNodes = $nodeType->getAutoCreatedChildNodes(); foreach ($this->getNodeDataByNodeTypeAndWorkspace($nodeTypeName, $workspaceName) as $nodeData) { $context = $this->nodeFactory->createContextMatchingNodeData($nodeData); $node = $this->nodeFactory->createFromNodeData($nodeData, $context); if (!$node instanceof NodeInterface) { continue; } foreach ($childNodes as $childNodeName => $childNodeType) { try { $childNode = $node->getNode($childNodeName); $childNodeIdentifier = Utility::buildAutoCreatedChildNodeIdentifier($childNodeName, $node->getIdentifier()); if ($childNode === null) { if ($dryRun === false) { $node->createNode($childNodeName, $childNodeType, $childNodeIdentifier); $this->output->outputLine('Auto created node named "%s" in "%s"', array($childNodeName, $node->getPath())); } else { $this->output->outputLine('Missing node named "%s" in "%s"', array($childNodeName, $node->getPath())); } $createdNodesCount++; } elseif ($childNode->getIdentifier() !== $childNodeIdentifier) { $nodeIdentifiersWhichNeedUpdate[$childNode->getIdentifier()] = $childNodeIdentifier; } } catch (\Exception $exception) { $this->output->outputLine('Could not create node named "%s" in "%s" (%s)', array($childNodeName, $node->getPath(), $exception->getMessage())); $nodeCreationExceptions++; } } } } if (count($nodeIdentifiersWhichNeedUpdate) > 0) { if ($dryRun === false) { foreach ($nodeIdentifiersWhichNeedUpdate as $oldNodeIdentifier => $newNodeIdentifier) { $queryBuilder = $this->entityManager->createQueryBuilder(); $queryBuilder->update(NodeData::class, 'n')->set('n.identifier', $queryBuilder->expr()->literal($newNodeIdentifier))->where('n.identifier = ?1')->setParameter(1, $oldNodeIdentifier); $result = $queryBuilder->getQuery()->getResult(); $updatedNodesCount++; $this->output->outputLine('Updated node identifier from %s to %s because it was not a "stable" identifier', [$oldNodeIdentifier, $newNodeIdentifier]); } } else { foreach ($nodeIdentifiersWhichNeedUpdate as $oldNodeIdentifier => $newNodeIdentifier) { $this->output->outputLine('Child nodes with identifier "%s" need to change their identifier to "%s"', [$oldNodeIdentifier, $newNodeIdentifier]); $updatedNodesCount++; } } } if ($createdNodesCount !== 0 || $nodeCreationExceptions !== 0 || $updatedNodesCount !== 0) { if ($dryRun === false) { if ($createdNodesCount > 0) { $this->output->outputLine('Created %s new child nodes', array($createdNodesCount)); } if ($updatedNodesCount > 0) { $this->output->outputLine('Updated identifier of %s child nodes', array($updatedNodesCount)); } if ($nodeCreationExceptions > 0) { $this->output->outputLine('%s Errors occurred during child node creation', array($nodeCreationExceptions)); } $this->persistenceManager->persistAll(); } else { if ($createdNodesCount > 0) { $this->output->outputLine('%s missing child nodes need to be created', array($createdNodesCount)); } if ($updatedNodesCount > 0) { $this->output->outputLine('%s identifiers of child nodes need to be updated', array($updatedNodesCount)); } } } }
/** * Create missing child nodes for the given node type * * @param NodeType $nodeType * @param string $workspaceName * @param boolean $dryRun * @return void */ protected function createChildNodesByNodeType(NodeType $nodeType, $workspaceName, $dryRun) { $createdNodesCount = 0; $updatedNodesCount = 0; $nodeCreationExceptions = 0; $nodeTypes = $this->nodeTypeManager->getSubNodeTypes($nodeType->getName(), false); $nodeTypes[$nodeType->getName()] = $nodeType; if ($this->nodeTypeManager->hasNodeType((string) $nodeType)) { $nodeType = $this->nodeTypeManager->getNodeType((string) $nodeType); $nodeTypeNames[$nodeType->getName()] = $nodeType; } else { $this->output->outputLine('Node type "%s" does not exist', array((string) $nodeType)); exit(1); } /** @var $nodeType NodeType */ foreach ($nodeTypes as $nodeTypeName => $nodeType) { $childNodes = $nodeType->getAutoCreatedChildNodes(); foreach ($this->getNodeDataByNodeTypeAndWorkspace($nodeTypeName, $workspaceName) as $nodeData) { $context = $this->nodeFactory->createContextMatchingNodeData($nodeData); $node = $this->nodeFactory->createFromNodeData($nodeData, $context); if (!$node instanceof NodeInterface) { continue; } foreach ($childNodes as $childNodeName => $childNodeType) { try { $childNode = $node->getNode($childNodeName); $childNodeIdentifier = Utility::buildAutoCreatedChildNodeIdentifier($childNodeName, $node->getIdentifier()); if ($childNode === null) { if ($dryRun === false) { $node->createNode($childNodeName, $childNodeType, $childNodeIdentifier); $this->output->outputLine('Auto created node named "%s" in "%s"', array($childNodeName, $node->getPath())); } else { $this->output->outputLine('Missing node named "%s" in "%s"', array($childNodeName, $node->getPath())); } $createdNodesCount++; } elseif ($childNode->getIdentifier() !== $childNodeIdentifier) { if ($dryRun === false) { $nodeData = $childNode->getNodeData(); $nodeData->setIdentifier($childNodeIdentifier); $this->nodeDataRepository->update($nodeData); $this->output->outputLine('Updated identifier to %s for child node "%s" in "%s"', array($childNodeIdentifier, $childNodeName, $node->getPath())); } else { $this->output->outputLine('Child node "%s" in "%s" does not have a stable identifier', array($childNodeName, $node->getPath())); } $updatedNodesCount++; } } catch (\Exception $exception) { $this->output->outputLine('Could not create node named "%s" in "%s" (%s)', array($childNodeName, $node->getPath(), $exception->getMessage())); $nodeCreationExceptions++; } } } } if ($createdNodesCount !== 0 || $nodeCreationExceptions !== 0 || $updatedNodesCount !== 0) { if ($dryRun === false) { if ($createdNodesCount > 0) { $this->output->outputLine('Created %s new child nodes', array($createdNodesCount)); } if ($updatedNodesCount > 0) { $this->output->outputLine('Updated identifier of %s child nodes', array($updatedNodesCount)); } if ($nodeCreationExceptions > 0) { $this->output->outputLine('%s Errors occurred during child node creation', array($nodeCreationExceptions)); } $this->persistenceManager->persistAll(); } else { if ($createdNodesCount > 0) { $this->output->outputLine('%s missing child nodes need to be created', array($createdNodesCount)); } if ($updatedNodesCount > 0) { $this->output->outputLine('%s identifiers of child nodes need to be updated', array($updatedNodesCount)); } } } }
/** * Create a recursive copy of this node below $referenceNode with $nodeName. * * $detachedCopy only has an influence if we are copying from one dimension to the other, possibly creating a new * node variant: * * - If $detachedCopy is TRUE, the whole (recursive) copy is done without connecting original and copied node, * so NOT CREATING a new node variant. * - If $detachedCopy is FALSE, and the node does not yet have a variant in the target dimension, we are CREATING * a new node variant. * * As a caller of this method, $detachedCopy should be TRUE if $this->getNodeType()->isAggregate() is TRUE, and FALSE * otherwise. * * @param NodeInterface $referenceNode * @param boolean $detachedCopy * @param string $nodeName * @return NodeInterface */ protected function createRecursiveCopy(NodeInterface $referenceNode, $nodeName, $detachedCopy) { $identifier = null; $referenceNodeDimensions = $referenceNode->getDimensions(); $referenceNodeDimensionsHash = Utility::sortDimensionValueArrayAndReturnDimensionsHash($referenceNodeDimensions); $thisDimensions = $this->getDimensions(); $thisNodeDimensionsHash = Utility::sortDimensionValueArrayAndReturnDimensionsHash($thisDimensions); if ($detachedCopy === false && $referenceNodeDimensionsHash !== $thisNodeDimensionsHash && $referenceNode->getContext()->getNodeByIdentifier($this->getIdentifier()) === null) { // If the target dimensions are different than this one, and there is no node shadowing this one in the target dimension yet, we use the same // node identifier, effectively creating a new node variant. $identifier = $this->getIdentifier(); } $copiedNode = $referenceNode->createSingleNode($nodeName, null, $identifier); $copiedNode->similarize($this, true); /** @var $childNode Node */ foreach ($this->getChildNodes() as $childNode) { // Prevent recursive copy when copying into itself if ($childNode->getIdentifier() !== $copiedNode->getIdentifier()) { $childNode->copyIntoInternal($copiedNode, $childNode->getName(), $detachedCopy); } } return $copiedNode; }
/** * Generate possible node name. When an idealNodeName is given then this is put into a valid format for a node name, * otherwise a random node name in the form "node-alphanumeric" is generated. * * @param string $idealNodeName * @return string */ protected function generatePossibleNodeName($idealNodeName = null) { if ($idealNodeName !== null) { $possibleNodeName = \TYPO3\TYPO3CR\Utility::renderValidNodeName($idealNodeName); } else { $possibleNodeName = NodePaths::generateRandomNodeName(); } return $possibleNodeName; }
/** * Build a cached array of dimension values and a hash to search for it. * * @return void */ protected function buildDimensionValues() { $dimensionValues = array(); foreach ($this->dimensions as $dimension) { /** @var NodeDimension $dimension */ $dimensionValues[$dimension->getName()][] = $dimension->getValue(); } $this->dimensionsHash = Utility::sortDimensionValueArrayAndReturnDimensionsHash($dimensionValues); $this->dimensionValues = $dimensionValues; }
/** * @param string $idealNodeName * @param NodeInterface $referenceNode * @return string */ protected function getFreeNodeName($idealNodeName, NodeInterface $referenceNode) { $idealNodeName = NodeUtility::renderValidNodeName($idealNodeName); $possibleNodeName = $idealNodeName; $counter = 1; while ($referenceNode->getNode($possibleNodeName) !== null) { $possibleNodeName = $idealNodeName . '-' . $counter; $counter++; } return $possibleNodeName; }