Although methods contained in this class belong to the public API, you should not need to deal with creating or managing node types manually. New node types should be defined in a NodeTypes.yaml file.
 /**
  * @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('Neos.ContentRepository.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 Neos.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 '';
     }
     $output = 'prototype(' . $nodeType->getName() . ') < prototype(Neos.Neos:Plugin) {' . chr(10);
     list($packageKey, $relativeName) = explode(':', $nodeType->getName(), 2);
     $output .= "\t" . 'package = "' . $packageKey . '"' . chr(10);
     $output .= "\t" . 'subpackage = ""' . chr(10);
     $output .= "\t" . 'controller = "Standard"' . chr(10);
     $output .= "\t" . 'action = "index"' . chr(10);
     $output .= '}' . chr(10);
     return $output;
 }
 /**
  * Generate a TypoScript prototype definition for a given node type
  *
  * A node will be rendered by Neos.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 '';
     }
     $output = 'prototype(' . $nodeType->getName() . ') < prototype(' . $this->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 = Neos.Neos:ConvertUris' . chr(10);
             }
         }
     }
     $output .= '}' . chr(10);
     return $output;
 }
 /**
  * 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 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 defaultValuesForPropertiesHandlesDateTypes()
 {
     $nodeType = new NodeType('Neos.ContentRepository:Base', array(), array('properties' => array('date' => array('type' => 'DateTime', 'defaultValue' => '2014-09-23'))));
     $this->assertEquals($nodeType->getDefaultValuesForProperties(), array('date' => new \DateTime('2014-09-23')));
 }
Example #7
0
 /**
  * Generate a TypoScript prototype definition for a given node type
  *
  * A prototype will be rendererd with the generator-class defined in the
  * nodeType-configuration 'fusion.prototypeGenerator'
  *
  * @param NodeType $nodeType
  * @return string
  * @throws \Neos\Neos\Domain\Exception
  */
 protected function generateTypoScriptForNodeType(NodeType $nodeType)
 {
     if ($nodeType->hasConfiguration('options.fusion.prototypeGenerator') && $nodeType->getConfiguration('options.fusion.prototypeGenerator') !== null) {
         $generatorClassName = $nodeType->getConfiguration('options.fusion.prototypeGenerator');
         if (!class_exists($generatorClassName)) {
             throw new \Neos\Neos\Domain\Exception('Fusion prototype-generator Class ' . $generatorClassName . ' does not exist');
         }
         $generator = $this->objectManager->get($generatorClassName);
         if (!$generator instanceof DefaultPrototypeGeneratorInterface) {
             throw new \Neos\Neos\Domain\Exception('Fusion prototype-generator Class ' . $generatorClassName . ' does not implement interface ' . DefaultPrototypeGeneratorInterface::class);
         }
         return $generator->generate($nodeType);
     }
     return '';
 }
 /**
  * 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();
 }
 /**
  * @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;
 }
 /**
  * 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 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);
     }
 }
 /**
  * Sets the node type of this node.
  *
  * @param \Neos\ContentRepository\Domain\Model\NodeType $nodeType
  * @return void
  */
 public function setNodeType(NodeType $nodeType)
 {
     if ($this->nodeType !== $nodeType->getName()) {
         $this->nodeType = $nodeType->getName();
         $this->addOrUpdate();
     }
 }
 /**
  * @param NodeType $pluginNodeType
  * @return array
  */
 protected function getPluginViewConfigurationsByPluginNodeType(NodeType $pluginNodeType)
 {
     $pluginNodeTypeOptions = $pluginNodeType->getOptions();
     return isset($pluginNodeTypeOptions['pluginViews']) ? $pluginNodeTypeOptions['pluginViews'] : [];
 }
 /**
  * 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];
 }