/**
  * Recursive function for fetching all node type names
  *
  * @param NodeType $nodeType
  * @param array $nodeTypeNames
  * @return void
  */
 protected function extractNodeTypeNamesAndSupertypesInternal(NodeType $nodeType, array &$nodeTypeNames)
 {
     $nodeTypeNames[$nodeType->getName()] = $nodeType->getName();
     foreach ($nodeType->getDeclaredSuperTypes() as $superType) {
         $this->extractNodeTypeNamesAndSupertypesInternal($superType, $nodeTypeNames);
     }
 }
 /**
  * Convert raw property values to the correct type according to a node type configuration
  *
  * @param NodeType $nodeType
  * @param string $propertyName
  * @param string $rawValue
  * @param Context $context
  * @return mixed
  */
 public function convert(NodeType $nodeType, $propertyName, $rawValue, Context $context)
 {
     $propertyType = $nodeType->getPropertyType($propertyName);
     switch ($propertyType) {
         case 'string':
             return $rawValue;
         case 'reference':
             return $this->convertReference($rawValue, $context);
         case 'references':
             return $this->convertReferences($rawValue, $context);
         case 'DateTime':
             return $this->convertDateTime($rawValue);
         case 'integer':
             return $this->convertInteger($rawValue);
         case 'boolean':
             return $this->convertBoolean($rawValue);
         case 'array':
             return $this->convertArray($rawValue);
         default:
             $innerType = $propertyType;
             if ($propertyType !== null) {
                 try {
                     $parsedType = \TYPO3\Flow\Utility\TypeHandling::parseType($propertyType);
                     $innerType = $parsedType['elementType'] ?: $parsedType['type'];
                 } catch (\TYPO3\Flow\Utility\Exception\InvalidTypeException $exception) {
                 }
             }
             if (is_string($rawValue) && $this->objectManager->isRegistered($innerType) && $rawValue !== '') {
                 return $this->propertyMapper->convert(json_decode($rawValue, true), $propertyType, $configuration);
             }
     }
 }
 /**
  * @param NodeType $nodeType The (uninitialized) node type to process
  * @param array $configuration The configuration of the node type
  * @param array $options The processor options
  * @return void
  */
 public function process(NodeType $nodeType, array &$configuration, array $options)
 {
     if ($nodeType->isOfType('TYPO3.TYPO3CR.Testing:NodeTypeWithProcessor')) {
         $someOption = isset($options['someOption']) ? $options['someOption'] : '';
         $someOtherOption = isset($options['someOtherOption']) ? $options['someOtherOption'] : '';
         $configuration['properties']['test1']['defaultValue'] = sprintf('The value of "someOption" is "%s", the value of "someOtherOption" is "%s"', $someOption, $someOtherOption);
     }
 }
 /**
  * Generate a TypoScript prototype definition for a given node type
  *
  * A node will be rendered by TYPO3.Neos:Content by default with a template in
  * resource://PACKAGE_KEY/Private/Templates/NodeTypes/NAME.html and forwards all public
  * node properties to the template TypoScript object.
  *
  * @param NodeType $nodeType
  * @return string
  */
 public function generate(NodeType $nodeType)
 {
     if (strpos($nodeType->getName(), ':') === false) {
         return '';
     }
     if ($nodeType->isOfType('TYPO3.Neos:Content')) {
         $basePrototypeName = 'TYPO3.Neos:Content';
     } elseif ($nodeType->isOfType('TYPO3.Neos:Document')) {
         $basePrototypeName = 'TYPO3.Neos:Document';
     } else {
         $basePrototypeName = 'TYPO3.TypoScript:Template';
     }
     $output = 'prototype(' . $nodeType->getName() . ') < prototype(' . $basePrototypeName . ') {' . chr(10);
     list($packageKey, $relativeName) = explode(':', $nodeType->getName(), 2);
     $templatePath = 'resource://' . $packageKey . '/Private/Templates/NodeTypes/' . $relativeName . '.html';
     $output .= "\t" . 'templatePath = \'' . $templatePath . '\'' . chr(10);
     foreach ($nodeType->getProperties() as $propertyName => $propertyConfiguration) {
         if (isset($propertyName[0]) && $propertyName[0] !== '_') {
             $output .= "\t" . $propertyName . ' = ${q(node).property("' . $propertyName . '")}' . chr(10);
             if (isset($propertyConfiguration['type']) && isset($propertyConfiguration['ui']['inlineEditable']) && $propertyConfiguration['type'] === 'string' && $propertyConfiguration['ui']['inlineEditable'] === true) {
                 $output .= "\t" . $propertyName . '.@process.convertUris = TYPO3.Neos:ConvertUris' . chr(10);
             }
         }
     }
     $output .= '}' . chr(10);
     return $output;
 }
 /**
  * Convert raw property values to the correct type according to a node type configuration
  *
  * @param NodeType $nodeType
  * @param string $propertyName
  * @param string $rawValue
  * @param Context $context
  * @return mixed
  */
 public function convert(NodeType $nodeType, $propertyName, $rawValue, Context $context)
 {
     $propertyType = $nodeType->getPropertyType($propertyName);
     switch ($propertyType) {
         case 'string':
             return $rawValue;
         case 'reference':
             return $this->convertReference($rawValue, $context);
         case 'references':
             return $this->convertReferences($rawValue, $context);
         case 'DateTime':
             return $this->convertDateTime($rawValue);
         case 'integer':
             return $this->convertInteger($rawValue);
         case 'boolean':
             return $this->convertBoolean($rawValue);
         case 'array':
             return $this->convertArray($rawValue);
         default:
             $innerType = $propertyType;
             if ($propertyType !== null) {
                 try {
                     $parsedType = \TYPO3\Flow\Utility\TypeHandling::parseType($propertyType);
                     $innerType = $parsedType['elementType'] ?: $parsedType['type'];
                 } catch (\TYPO3\Flow\Utility\Exception\InvalidTypeException $exception) {
                 }
             }
             if ((is_string($rawValue) || is_array($rawValue)) && $this->objectManager->isRegistered($innerType) && $rawValue !== '') {
                 $propertyMappingConfiguration = new MvcPropertyMappingConfiguration();
                 $propertyMappingConfiguration->allowOverrideTargetType();
                 $propertyMappingConfiguration->allowAllProperties();
                 $propertyMappingConfiguration->skipUnknownProperties();
                 $propertyMappingConfiguration->setTypeConverterOption('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, true);
                 $propertyMappingConfiguration->setTypeConverterOption('TYPO3\\Flow\\Property\\TypeConverter\\PersistentObjectConverter', \TYPO3\Flow\Property\TypeConverter\PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true);
                 return $this->propertyMapper->convert($rawValue, $propertyType, $propertyMappingConfiguration);
             } else {
                 return $rawValue;
             }
     }
 }
 /**
  * @param NodeType $nodetype
  * @return boolean
  */
 private function isNodeTypeInAllowedSite(NodeType $nodetype)
 {
     // dont restrict abstract nodes
     if ($nodetype->isAbstract()) {
         return true;
     }
     $deniedWilcard = false;
     $allowedSites = $nodetype->getConfiguration('allowedSites');
     if ($allowedSites) {
         $currentDomain = $this->domainRepository->findOneByActiveRequest();
         if ($currentDomain !== null) {
             $currentSite = $currentDomain->getSite();
         } else {
             $currentSite = $this->siteRepository->findFirstOnline();
         }
         if (!$currentSite) {
             return true;
         }
         foreach ($allowedSites as $siteName => $allowed) {
             if ($allowed == TRUE && $siteName == '*' | $currentSite->getSiteResourcesPackageKey() == $siteName) {
                 return true;
             }
             if ($allowed == FALSE && $currentSite->getSiteResourcesPackageKey() == $siteName) {
                 return false;
             }
             if ($allowed == TRUE && $siteName == '*') {
                 $deniedWilcard = false;
             }
             if ($allowed == FALSE && $siteName == '*') {
                 $deniedWilcard = true;
             }
         }
         if ($deniedWilcard == true) {
             return false;
         }
     }
     return true;
 }
 /**
  * This method traverses the given node type to find the first super type that matches the constraint node type.
  * In case the hierarchy has more than one way of finding a path to the node type it's not taken into account,
  * since the first matched is returned. This is accepted on purpose for performance reasons and due to the fact
  * that such hierarchies should be avoided.
  *
  * @param NodeType $currentNodeType
  * @param string $constraintNodeTypeName
  * @param integer $distance
  * @return integer or NULL if no NodeType matched
  */
 protected function traverseSuperTypes(NodeType $currentNodeType, $constraintNodeTypeName, $distance)
 {
     if ($currentNodeType->getName() === $constraintNodeTypeName) {
         return $distance;
     }
     $distance++;
     foreach ($currentNodeType->getDeclaredSuperTypes() as $superType) {
         $result = $this->traverseSuperTypes($superType, $constraintNodeTypeName, $distance);
         if ($result !== null) {
             return $result;
         }
     }
     return null;
 }
 /**
  * @param NodeInterface $node
  * @param NodeType $nodeType
  * @return boolean
  */
 public function isNodeOfType(NodeInterface $node, NodeType $nodeType)
 {
     if ($node->getNodeType()->getName() === $nodeType->getName()) {
         return true;
     }
     $subNodeTypes = $this->nodeTypeManager->getSubNodeTypes($nodeType->getName());
     return isset($subNodeTypes[$node->getNodeType()->getName()]);
 }
 /**
  * @param string $nodeTypeName
  * @param NodeType $nodeType
  * @return void
  */
 protected function readNodeTypeConfiguration($nodeTypeName, NodeType $nodeType)
 {
     $nodeTypeConfiguration = $nodeType->getFullConfiguration();
     $this->superTypeConfiguration['typo3:' . $nodeTypeName] = array();
     /** @var NodeType $superType */
     foreach ($nodeType->getDeclaredSuperTypes() as $superType) {
         $this->superTypeConfiguration['typo3:' . $nodeTypeName][] = 'typo3:' . $superType->getName();
     }
     $nodeTypeProperties = array();
     if (isset($nodeTypeConfiguration['properties'])) {
         foreach ($nodeTypeConfiguration['properties'] as $property => $propertyConfiguration) {
             // TODO Make sure we can configure the range for all multi column elements to define what types a column may contain
             $this->addProperty('typo3:' . $nodeTypeName, 'typo3:' . $property, $propertyConfiguration);
             $nodeTypeProperties[] = 'typo3:' . $property;
         }
     }
     $metadata = array();
     $metaDataPropertyIndexes = array('ui');
     foreach ($metaDataPropertyIndexes as $propertyName) {
         if (isset($nodeTypeConfiguration[$propertyName])) {
             $metadata[$propertyName] = $nodeTypeConfiguration[$propertyName];
         }
     }
     if ($nodeType->isAbstract()) {
         $metadata['abstract'] = true;
     }
     $this->types['typo3:' . $nodeTypeName] = (object) array('label' => $nodeType->getLabel() ?: $nodeTypeName, 'id' => 'typo3:' . $nodeTypeName, 'properties' => array(), 'specific_properties' => $nodeTypeProperties, 'subtypes' => array(), 'metadata' => (object) $metadata, 'supertypes' => $this->superTypeConfiguration['typo3:' . $nodeTypeName], 'url' => 'http://www.typo3.org/ns/2012/Flow/Packages/Neos/Content/', 'ancestors' => array(), 'comment' => '', 'comment_plain' => '');
 }
 /**
  * @test
  */
 public function magicHasReturnsFalseIfPropertyDoesNotExist()
 {
     $baseType = new NodeType('TYPO3.TYPO3CR:Base', array(), array());
     $this->assertFalse($baseType->hasFooKey());
 }
 /**
  * Sets the node type of this node.
  *
  * @param \TYPO3\TYPO3CR\Domain\Model\NodeType $nodeType
  * @return void
  */
 public function setNodeType(NodeType $nodeType)
 {
     if ($this->nodeType !== $nodeType->getName()) {
         $this->nodeType = $nodeType->getName();
         $this->update();
     }
 }
 /**
  * Collects all nodes with missing shadow nodes
  *
  * @param Workspace $workspace
  * @param boolean $dryRun
  * @param NodeType $nodeType
  * @return array
  */
 protected function fixShadowNodesInWorkspace(Workspace $workspace, $dryRun, NodeType $nodeType = null)
 {
     $workspaces = array_merge([$workspace], $workspace->getBaseWorkspaces());
     $fixedShadowNodes = 0;
     foreach ($workspaces as $workspace) {
         /** @var Workspace $workspace */
         if ($workspace->getBaseWorkspace() === null) {
             continue;
         }
         /** @var QueryBuilder $queryBuilder */
         $queryBuilder = $this->entityManager->createQueryBuilder();
         $queryBuilder->select('n')->from(NodeData::class, 'n')->where('n.workspace = :workspace');
         $queryBuilder->setParameter('workspace', $workspace->getName());
         if ($nodeType !== null) {
             $queryBuilder->andWhere('n.nodeType = :nodeType');
             $queryBuilder->setParameter('nodeType', $nodeType->getName());
         }
         /** @var NodeData $nodeData */
         foreach ($queryBuilder->getQuery()->getResult() as $nodeData) {
             $nodeDataSeenFromParentWorkspace = $this->nodeDataRepository->findOneByIdentifier($nodeData->getIdentifier(), $workspace->getBaseWorkspace(), $nodeData->getDimensionValues());
             // This is the good case, either the node does not exist or was shadowed
             if ($nodeDataSeenFromParentWorkspace === null) {
                 continue;
             }
             // Also good, the node was not moved at all.
             if ($nodeDataSeenFromParentWorkspace->getPath() === $nodeData->getPath()) {
                 continue;
             }
             $nodeDataOnSamePath = $this->nodeDataRepository->findOneByPath($nodeData->getPath(), $workspace->getBaseWorkspace(), $nodeData->getDimensionValues(), null);
             // We cannot just put a shadow node in the path, something exists, but that should be fine.
             if ($nodeDataOnSamePath !== null) {
                 continue;
             }
             if (!$dryRun) {
                 $nodeData->createShadow($nodeDataSeenFromParentWorkspace->getPath());
             }
             $fixedShadowNodes++;
         }
     }
     return $fixedShadowNodes;
 }
 /**
  * Iterates through the given $properties setting them on the specified $node using the appropriate TypeConverters.
  *
  * @param object $nodeLike
  * @param NodeType $nodeType
  * @param array $properties
  * @param \TYPO3\TYPO3CR\Domain\Service\Context $context
  * @throws \TYPO3\Flow\Property\Exception\TypeConverterException
  * @return void
  */
 protected function setNodeProperties($nodeLike, NodeType $nodeType, array $properties, TYPO3CRContext $context)
 {
     $nodeTypeProperties = $nodeType->getProperties();
     foreach ($properties as $nodePropertyName => $nodePropertyValue) {
         if (substr($nodePropertyName, 0, 2) === '__') {
             continue;
         }
         $nodePropertyType = isset($nodeTypeProperties[$nodePropertyName]['type']) ? $nodeTypeProperties[$nodePropertyName]['type'] : NULL;
         switch ($nodePropertyType) {
             case 'reference':
                 $nodePropertyValue = $context->getNodeByIdentifier($nodePropertyValue);
                 break;
             case 'references':
                 $nodeIdentifiers = json_decode($nodePropertyValue);
                 $nodePropertyValue = array();
                 if (is_array($nodeIdentifiers)) {
                     foreach ($nodeIdentifiers as $nodeIdentifier) {
                         $referencedNode = $context->getNodeByIdentifier($nodeIdentifier);
                         if ($referencedNode !== NULL) {
                             $nodePropertyValue[] = $referencedNode;
                         }
                     }
                 } else {
                     throw new TypeConverterException(sprintf('node type "%s" expects an array of identifiers for its property "%s"', $nodeType->getName(), $nodePropertyName), 1383587419);
                 }
                 break;
             case 'date':
                 if ($nodePropertyValue !== '') {
                     $nodePropertyValue = \DateTime::createFromFormat('!Y-m-d', $nodePropertyValue);
                 } else {
                     $nodePropertyValue = NULL;
                 }
                 break;
         }
         if (substr($nodePropertyName, 0, 1) === '_') {
             $nodePropertyName = substr($nodePropertyName, 1);
             ObjectAccess::setProperty($nodeLike, $nodePropertyName, $nodePropertyValue);
             continue;
         }
         if (!isset($nodeTypeProperties[$nodePropertyName])) {
             throw new TypeConverterException(sprintf('node type "%s" does not have a property "%s" according to the schema', $nodeType->getName(), $nodePropertyName), 1359552744);
         }
         if ($this->objectManager->isRegistered($nodePropertyType) && $nodePropertyValue !== '') {
             $nodePropertyValue = $this->propertyMapper->convert(json_decode($nodePropertyValue, TRUE), $nodePropertyType);
         }
         $nodeLike->setProperty($nodePropertyName, $nodePropertyValue);
     }
 }
 /**
  * Configure grid row element (M12.Foundation:GridRowXCol):
  * - add child columns
  * - set default column width (based on num of columns and grid size)
  * - create text node with sample content in each column
  *
  * @param NodeInterface $node
  * @param NodeType $nodeType : one of M12.Foundation:GridRowXCol
  * @throws \TYPO3\TYPO3CR\Exception\NodeTypeNotFoundException
  */
 protected function configureGridRow(NodeInterface $node, NodeType $nodeType)
 {
     if (false === $this->enableAutoCreateNodes) {
         return;
     }
     $gs = $this->gridSize;
     // Get number of columns to create from M12.Foundation:GridRowXCol node type name
     $cols = (int) substr($nodeType->getName(), -4, 1);
     for ($k = 1; $k <= $cols; $k++) {
         $newNodeType = $this->nodeTypeManager->getNodeType('M12.Foundation:GridColumn');
         $newNode = $node->createNode(uniqid('node-'), $newNodeType);
         // configure sensible default columns width
         if (1 === $cols) {
             $newNode->setProperty('classGridSize', ['small-' . $gs]);
         } elseif (4 === $cols) {
             $newNode->setProperty('classGridSize', ['small-' . $gs, 'medium-' . $gs / 2, 'large-' . $gs / 4]);
         } else {
             $newNode->setProperty('classGridSize', ['small-' . $gs, 'medium-' . (int) $gs / $cols]);
         }
         // Create sample content in each column
         $config = $this->getAssistanceConfigForNodeType($newNodeType->getName());
         $this->configureCreateAssistanceChildNodes($newNode, $newNodeType, $config, [$k]);
     }
 }
 /**
  * Iterates through the given $properties setting them on the specified $node using the appropriate TypeConverters.
  *
  * @param object $nodeLike
  * @param NodeType $nodeType
  * @param array $properties
  * @param TYPO3CRContext $context
  * @param PropertyMappingConfigurationInterface $configuration
  * @return void
  * @throws TypeConverterException
  */
 protected function setNodeProperties($nodeLike, NodeType $nodeType, array $properties, TYPO3CRContext $context, PropertyMappingConfigurationInterface $configuration = null)
 {
     $nodeTypeProperties = $nodeType->getProperties();
     unset($properties['_lastPublicationDateTime']);
     foreach ($properties as $nodePropertyName => $nodePropertyValue) {
         if (substr($nodePropertyName, 0, 2) === '__') {
             continue;
         }
         $nodePropertyType = isset($nodeTypeProperties[$nodePropertyName]['type']) ? $nodeTypeProperties[$nodePropertyName]['type'] : null;
         switch ($nodePropertyType) {
             case 'reference':
                 $nodePropertyValue = $context->getNodeByIdentifier($nodePropertyValue);
                 break;
             case 'references':
                 $nodeIdentifiers = json_decode($nodePropertyValue);
                 $nodePropertyValue = array();
                 if (is_array($nodeIdentifiers)) {
                     foreach ($nodeIdentifiers as $nodeIdentifier) {
                         $referencedNode = $context->getNodeByIdentifier($nodeIdentifier);
                         if ($referencedNode !== null) {
                             $nodePropertyValue[] = $referencedNode;
                         }
                     }
                 } elseif ($nodeIdentifiers !== null) {
                     throw new TypeConverterException(sprintf('node type "%s" expects an array of identifiers for its property "%s"', $nodeType->getName(), $nodePropertyName), 1383587419);
                 }
                 break;
             case 'DateTime':
                 if ($nodePropertyValue !== '' && ($nodePropertyValue = \DateTime::createFromFormat(\DateTime::W3C, $nodePropertyValue)) !== false) {
                     $nodePropertyValue->setTimezone(new \DateTimeZone(date_default_timezone_get()));
                 } else {
                     $nodePropertyValue = null;
                 }
                 break;
             case 'integer':
                 $nodePropertyValue = intval($nodePropertyValue);
                 break;
             case 'boolean':
                 if (is_string($nodePropertyValue)) {
                     $nodePropertyValue = $nodePropertyValue === 'true' ? true : false;
                 }
                 break;
             case 'array':
                 $nodePropertyValue = json_decode($nodePropertyValue, true);
                 break;
         }
         if (substr($nodePropertyName, 0, 1) === '_') {
             $nodePropertyName = substr($nodePropertyName, 1);
             ObjectAccess::setProperty($nodeLike, $nodePropertyName, $nodePropertyValue);
             continue;
         }
         if (!isset($nodeTypeProperties[$nodePropertyName])) {
             if ($configuration !== null && $configuration->shouldSkipUnknownProperties()) {
                 continue;
             } else {
                 throw new TypeConverterException(sprintf('Node type "%s" does not have a property "%s" according to the schema', $nodeType->getName(), $nodePropertyName), 1359552744);
             }
         }
         $innerType = $nodePropertyType;
         if ($nodePropertyType !== null) {
             try {
                 $parsedType = TypeHandling::parseType($nodePropertyType);
                 $innerType = $parsedType['elementType'] ?: $parsedType['type'];
             } catch (InvalidTypeException $exception) {
             }
         }
         if (is_string($nodePropertyValue) && $this->objectManager->isRegistered($innerType) && $nodePropertyValue !== '') {
             $nodePropertyValue = $this->propertyMapper->convert(json_decode($nodePropertyValue, true), $nodePropertyType, $configuration);
         }
         $nodeLike->setProperty($nodePropertyName, $nodePropertyValue);
     }
 }
 /**
  * @param NodeType $pluginNodeType
  * @return array
  */
 protected function getPluginViewConfigurationsByPluginNodeType(NodeType $pluginNodeType)
 {
     $pluginNodeTypeOptions = $pluginNodeType->getOptions();
     return isset($pluginNodeTypeOptions['pluginViews']) ? $pluginNodeTypeOptions['pluginViews'] : array();
 }
 /**
  * @param AbstractNodeData $nodeData
  * @param NodeType $nodeType
  * @param MetaDataCollection $metaDataCollection
  * @throws \TYPO3\Eel\Exception
  */
 protected function mapMetaDataToNodeData(AbstractNodeData $nodeData, NodeType $nodeType, MetaDataCollection $metaDataCollection)
 {
     if ($this->defaultContextVariables === NULL) {
         $this->defaultContextVariables = EelUtility::getDefaultContextVariables($this->settings['defaultEelContext']);
     }
     foreach ($nodeType->getProperties() as $propertyName => $propertyConfiguration) {
         $contextVariables = array_merge($this->defaultContextVariables, $metaDataCollection->toArray());
         if (isset($propertyConfiguration['mapping'])) {
             $nodeData->setProperty($propertyName, EelUtility::evaluateEelExpression($propertyConfiguration['mapping'], $this->eelEvaluator, $contextVariables));
         }
     }
 }
 /**
  * @test
  */
 public function defaultValuesForPropertiesHandlesDateTypes()
 {
     $nodeType = new NodeType('TYPO3.TYPO3CR:Base', array(), array('properties' => array('date' => array('type' => 'DateTime', 'defaultValue' => '2014-09-23'))));
     $this->assertEquals($nodeType->getDefaultValuesForProperties(), array('date' => new \DateTime('2014-09-23')));
 }
 /**
  * @param NodeType $nodeType
  * @return array<NodeType>
  */
 protected function getAllImplementedNodeTypes(NodeType $nodeType)
 {
     $types = array($nodeType);
     foreach ($nodeType->getDeclaredSuperTypes() as $superType) {
         $types = array_merge($types, $this->getAllImplementedNodeTypes($superType));
     }
     return $types;
 }
 /**
  * Generate an `@cache` entry tag for a node type
  * A cache entry with this tag will be flushed whenever a node
  * (for any variant) that is of the given node type (including inheritance)
  * is updated.
  *
  * @param NodeType $nodeType
  * @return string
  */
 public function nodeTypeTag(NodeType $nodeType)
 {
     return 'NodeType_' . $nodeType->getName();
 }
 /**
  * Reorder child nodes for the given node type
  *
  * @param NodeType $nodeType
  * @param string $workspaceName
  * @param boolean $dryRun
  * @return void
  */
 protected function reorderChildNodesByNodeType(NodeType $nodeType, $workspaceName, $dryRun)
 {
     $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();
         if ($childNodes === array()) {
             continue;
         }
         foreach ($this->getNodeDataByNodeTypeAndWorkspace($nodeTypeName, $workspaceName) as $nodeData) {
             /** @var NodeInterface $childNodeBefore */
             $childNodeBefore = null;
             $context = $this->nodeFactory->createContextMatchingNodeData($nodeData);
             $node = $this->nodeFactory->createFromNodeData($nodeData, $context);
             if (!$node instanceof NodeInterface) {
                 continue;
             }
             foreach ($childNodes as $childNodeName => $childNodeType) {
                 $childNode = $node->getNode($childNodeName);
                 if ($childNode) {
                     if ($childNodeBefore) {
                         if ($dryRun === false) {
                             if ($childNodeBefore->getIndex() >= $childNode->getIndex()) {
                                 $childNode->moveAfter($childNodeBefore);
                                 $this->output->outputLine('Moved node named "%s" after node named "%s" in "%s"', array($childNodeName, $childNodeBefore->getName(), $node->getPath()));
                             }
                         } else {
                             $this->output->outputLine('Should move node named "%s" after node named "%s" in "%s"', array($childNodeName, $childNodeBefore->getName(), $node->getPath()));
                         }
                     }
                 } else {
                     $this->output->outputLine('Missing child node named "%s" in "%s".', array($childNodeName, $node->getPath()));
                 }
                 $childNodeBefore = $childNode;
             }
         }
     }
 }
 /**
  * Tries to find a default value for the given property trying:
  * 1) The specific property configuration for the given NodeType
  * 2) The generic configuration for the property type in setings.
  *
  * @param NodeType $nodeType
  * @param string $propertyName
  * @return mixed
  */
 protected function getDefaultValueForProperty(NodeType $nodeType, $propertyName)
 {
     $defaultValues = $nodeType->getDefaultValuesForProperties();
     if (!isset($defaultValues[$propertyName])) {
         return null;
     }
     return $defaultValues[$propertyName];
 }