diff --git a/.php_cs b/.php_cs new file mode 100644 index 0000000..f11c5e7 --- /dev/null +++ b/.php_cs @@ -0,0 +1,31 @@ +in('Classes') + ->in('Tests') +; + +return PhpCsFixer\Config::create() + ->setRules([ + '@PSR2' => true, + 'single_quote' => true, + 'no_unused_imports' => true, + 'no_useless_else' => true, + 'phpdoc_align' => true, + 'phpdoc_order' => true, + 'phpdoc_scalar' => true, + 'pre_increment' => true, + 'short_scalar_cast' => true, + 'space_after_semicolon' => true, + 'ternary_operator_spaces' => true, + 'trailing_comma_in_multiline_array' => true, + 'semicolon_after_instruction' => true, + 'trim_array_spaces' => true, + 'whitespace_after_comma_in_array' => true, + 'phpdoc_add_missing_param_annotation' => true, + 'binary_operator_spaces' => ['align_equals' => false, 'align_double_arrow' => true], + 'concat_space' => ['spacing' => 'one'], + 'array_syntax' => ['syntax' => 'short'], + ]) + ->setFinder($finder) +; diff --git a/Classes/Command/SchemaCommandController.php b/Classes/Command/SchemaCommandController.php new file mode 100644 index 0000000..adb9726 --- /dev/null +++ b/Classes/Command/SchemaCommandController.php @@ -0,0 +1,121 @@ +configurationService->setPackageKey($packageKey); + $this->outputLine(); + $this->outputFormatted('# Extracting schema.org ...'); + + $this->schemaParserService->setAllSchemaJsonFilename($this->jsonSchema); + + if ($type !== null) { + $nodeTypes = $this->schemaParserService->parseByTypes(explode(',', $type)); + } else { + $nodeTypes = $this->schemaParserService->parseAll(); + } + + $filename = 'NodeTypes.SchemaOrg.' . $name . '.yaml'; + + $this->nodeTypeBuilder + ->setFilename($filename) + ->unlinkExistingFile(); + + $success = $error = 0; + foreach ($nodeTypes as $nodeType) { + /** @var NodeType $nodeType */ + $this->outputLine('+ ' . $nodeType->getName() . ''); + + try { + $existingNodeType = $this->nodeTypeManager->getNodeType($nodeType->getName()); + if ($existingNodeType->getName() === $this->fallbackNodeTypeName) { + throw new NodeTypeNotFoundException(); + } + $this->outputFormatted(' - NodeType "%s" skipped, update is not supported ...', [$existingNodeType->getName()]); + ++$error; + } catch (NodeTypeNotFoundException $exception) { + $filename = $this->nodeTypeBuilder->dump($nodeType); + ++$success; + } + } + + $this->outputLine(); + if ($success > 0) { + $this->outputFormatted('The following file contain your new NodeType: ' . $filename); + } else { + $this->outputFormatted('Nothing to do ...'); + } + + $this->outputLine(); + $this->outputFormatted('We are on Github, Pull request welcome or open an issue if you have trouble ...'); + } catch (\InvalidArgumentException $exception) { + $this->outputLine(); + $this->outputFormatted($exception->getMessage()); + $this->sendAndExit(1); + } + } +} diff --git a/Classes/Domain/Model/FallbackNodeDataLabelGenerator.php b/Classes/Domain/Model/FallbackNodeDataLabelGenerator.php new file mode 100644 index 0000000..2d34aa8 --- /dev/null +++ b/Classes/Domain/Model/FallbackNodeDataLabelGenerator.php @@ -0,0 +1,37 @@ +hasProperty('name') === true && $node->getProperty('name') !== '') { + $label = strip_tags($node->getProperty('name')); + } else { + $label = ($node->getNodeType()->getLabel() ?: $node->getNodeType()->getName()) . ' (' . $node->getName() . ')'; + } + + return $label; + } +} diff --git a/Classes/Domain/Model/NodeType.php b/Classes/Domain/Model/NodeType.php new file mode 100644 index 0000000..04b8b91 --- /dev/null +++ b/Classes/Domain/Model/NodeType.php @@ -0,0 +1,225 @@ +name = (string)$name; + $this->type = (string)$type; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return string + */ + public function getLabel() + { + list(, $label) = explode(':', $this->getName()); + return $label; + } + + /** + * @return bool + */ + public function getAbstract() + { + return $this->abstract; + } + + /** + * @return bool + */ + public function getFinal() + { + return $this->final; + } + + /** + * @return array + */ + public function getDefaultConfiguration() + { + return Arrays::arrayMergeRecursiveOverrule($this->configurationService->getTypeDefaultConfiguration($this->type), [ + 'ui' => [ + 'label' => $this->getLabel(), + ], + ]); + } + + /** + * @return array + */ + public function getConfiguration() + { + return $this->configuration; + } + + /** + * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz' + * @param mixed $value + */ + public function setConfigurationByPath($path, $value) + { + $this->configuration = Arrays::setValueByPath($this->configuration, $path, $value); + } + + /** + * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz' + * @param mixed $value + */ + public function getConfigurationByPath($path) + { + $this->configuration = Arrays::getValueByPath($this->configuration, $path); + } + + /** + * @param string $superTypeName + */ + public function addSuperType($superTypeName) + { + $this->superTypes[$superTypeName] = true; + } + + /** + * @return array + */ + public function getSuperTypes() + { + $superTypes = []; + foreach ($this->superTypes as $superTypeName=>$superTypeStatus) { + if ($superTypeStatus === true) { + $superTypes[] = $superTypeName; + } + } + + return $superTypes; + } + + /** + * @return bool + */ + public function hasSuperTypes() + { + return (bool)count($this->getSuperTypes()); + } + + /** + * @return array + */ + public function getRelatedNodeTypes() + { + return $this->relatedNodeTypes; + } + + /** + * @return array + */ + public function getProperties() + { + return $this->properties; + } + + /** + * @param array $properties + */ + public function setProperties($properties) + { + $this->properties = []; + foreach ($properties as $property) { + $this->initializeRelatedNodeTypes($property); + /** @var Property $property */ + if ($property->isSkipProperty()) { + continue; + } + $propertyName = $property->getName(); + $configuration = $property->getConfiguration(); + + $this->properties[$propertyName] = $this->configurationService->mergePropertyConfigurationWithDefaultConfiguration($propertyName, $this->getName(), $configuration); + } + } + + /** + * @return bool + */ + public function hasProperties() + { + return (bool)count($this->getProperties()); + } + + /** + * @param Property $property + * @return void + */ + protected function initializeRelatedNodeTypes(Property $property) + { + if (substr($property->getType(), 0, 9) !== 'reference') { + return; + } + + $configuration = $property->getConfiguration(); + $nodeTypes = Arrays::getValueByPath($configuration, 'ui.inspector.editorOptions.nodeTypes') ?: []; + foreach ($nodeTypes as $nodeType) { + $this->relatedNodeTypes[$nodeType] = true; + } + } +} diff --git a/Classes/Domain/Model/Property.php b/Classes/Domain/Model/Property.php new file mode 100644 index 0000000..ee4af32 --- /dev/null +++ b/Classes/Domain/Model/Property.php @@ -0,0 +1,169 @@ + 'boolean', + 'Date' => 'date', + 'DateTime' => 'date', + 'Float' => 'float', + 'Number' => 'integer', + 'Integer' => 'integer', + 'Text' => 'string', + 'Time' => 'date', + 'URL' => 'string', + ]; + + /** + * @var string + */ + protected $name; + + /** + * @var string + */ + protected $label; + + /** + * @var string + */ + protected $comment; + + /** + * @var string + */ + protected $type; + + /** + * @var bool + */ + protected $reloadIfChanged; + + /** + * @var array + */ + protected $ui = []; + + /** + * @var bool + */ + protected $skipProperty = false; + + /** + * @param ConfigurationService $configurationService + * @param string $type + * @param string $name + * @param string $label + * @param string $comment + * @param string $groupName + * @param bool $reloadIfChanged + * + */ + public function __construct(ConfigurationService $configurationService, $type, $name, $label, $comment, $groupName, $reloadIfChanged = false) + { + $this->configurationService = $configurationService; + $this->type = $this->convertDataType($type, $name); + $this->name = (string)$name; + $this->label = (string)$label; + $this->comment = (string)$comment; + $this->ui = Arrays::arrayMergeRecursiveOverrule($this->ui, [ + 'label' => $this->label, + 'comment' => $this->comment, + 'inspector' => [ + 'group' => $groupName, + ], + ]); + $this->reloadIfChanged = (bool)$reloadIfChanged; + } + + /** + * @return bool + */ + public function isSkipProperty() + { + return $this->skipProperty; + } + + /** + * @param bool $skipProperty + */ + public function setSkipProperty($skipProperty) + { + $this->skipProperty = $skipProperty; + } + + /** + * @return string + */ + public function getName() + { + return $this->name; + } + + /** + * @return string + */ + public function getType() + { + return $this->type; + } + + /** + * @param string $schemaOrgPropertyName + * @param string $propertyName + * @return string + */ + protected function convertDataType($schemaOrgPropertyName, $propertyName) + { + if (strpos($schemaOrgPropertyName, ':')) { + $type = Functions::substr($propertyName, -1) === 's' ? 'references' : 'reference'; + $schemaOrgPropertyName = $this->configurationService->nodeTypeNameMapping($schemaOrgPropertyName); + $this->ui = Arrays::setValueByPath($this->ui, 'inspector', [ + 'editorOptions' => [ + 'nodeTypes' => [$schemaOrgPropertyName], + ], + ]); + } else { + if (!isset($this->dataTypeMapping[$schemaOrgPropertyName]) && strpos($schemaOrgPropertyName, ':') > 0) { + throw new \InvalidArgumentException(sprintf('Invalid property type (%s)', $schemaOrgPropertyName), 1396192757); + } + $type = (string)$this->dataTypeMapping[$schemaOrgPropertyName]; + } + return $type; + } + + /** + * @return array + */ + public function getConfiguration() + { + $configuration = [ + 'type' => $this->type, + 'ui' => $this->ui, + ]; + + return $configuration; + } +} diff --git a/Classes/Domain/Service/SchemaOrgPrototypeGenerator.php b/Classes/Domain/Service/SchemaOrgPrototypeGenerator.php new file mode 100644 index 0000000..6d25f2c --- /dev/null +++ b/Classes/Domain/Service/SchemaOrgPrototypeGenerator.php @@ -0,0 +1,61 @@ +getName(), ':') === false) { + return ''; + } + $output = ''; + /** @var NodeType $superType */ + foreach ($nodeType->getDeclaredSuperTypes() as $superType) { + + if (!$superType->isAbstract()) { + continue; + } + + $output .= chr(10); + $output .= 'prototype(' . $superType->getName() . '.Schema) < prototype(Neos.Fusion:RawArray) {' . chr(10); + + $output .= "\t" . '\'@context\' = \'http://schema.org\'' . chr(10); + list($packageKey, $relativeName) = explode(':', $superType->getName(), 2); + $output .= "\t" . '\'@type\' = \'' . $relativeName . '\'' . chr(10); + + foreach ($superType->getProperties() as $propertyName => $propertyConfiguration) { + if (isset($propertyName[0]) && $propertyName[0] !== '_') { + $output .= "\t" . $propertyName . ' = ${q(node).property("' . $propertyName . '")}' . chr(10); + if (isset($propertyConfiguration['type']) && $propertyConfiguration['type'] === 'DateTime') { + $output .= "\t" . $propertyName . '.@process.formatDate = ${Date.format(value, \'Y-m-d\')}' . chr(10); + } + $output .= "\t" . $propertyName . '.@if.notEmpty = ${q(node).property("' . $propertyName . '") != null}' . chr(10); + + // todo: handle reference types as nested RawArray + } + } + + $output .= '}' . chr(10); + + } + return $output; + } + + +} diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Command/SchemaCommandController.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Command/SchemaCommandController.php deleted file mode 100644 index 609fbb5..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Command/SchemaCommandController.php +++ /dev/null @@ -1,117 +0,0 @@ -configurationService->setPackageKey($packageKey); - $this->outputLine(); - $this->outputFormatted("# Extracting schema.org ..."); - - $this->schemaParserService->setAllSchemaJsonFilename($this->jsonSchema); - - if ($type !== NULL) { - $nodeTypes = $this->schemaParserService->parseByTypes(explode(',', $type)); - } else { - $nodeTypes = $this->schemaParserService->parseAll(); - } - - $filename = 'NodeTypes.SchemaOrg.' . $name . '.yaml'; - - $this->nodeTypeBuilder - ->setFilename($filename) - ->unlinkExistingFile(); - - $success = $error = 0; - foreach ($nodeTypes as $nodeType) { - /** @var NodeType $nodeType */ - $this->outputLine("+ " . $nodeType->getName() . ""); - - try { - $existingNodeType = $this->nodeTypeManager->getNodeType($nodeType->getName()); - $this->outputFormatted(" - NodeType \"%s\" skipped, update is not supported ...", array($existingNodeType->getName())); - ++$error; - } catch (NodeTypeNotFoundException $exception) { - $filename = $this->nodeTypeBuilder->dump($nodeType); - ++$success; - } - } - - $this->outputLine(); - if ($success > 0) { - $this->outputFormatted("The following file contain your new NodeType: " . $filename); - } else { - $this->outputFormatted("Nothing to do ..."); - } - - $this->outputLine(); - $this->outputFormatted("We are on Github, Pull request welcome or open an issue if you have trouble ..."); - } catch (\InvalidArgumentException $exception) { - $this->outputLine(); - $this->outputFormatted($exception->getMessage()); - $this->sendAndExit(1); - } - } - -} \ No newline at end of file diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/DefaultNodeLabelGenerator.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/DefaultNodeLabelGenerator.php deleted file mode 100644 index 56e9c5a..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/DefaultNodeLabelGenerator.php +++ /dev/null @@ -1,42 +0,0 @@ -hasProperty('name') === TRUE && $node->getProperty('name') !== '') { - $label = strip_tags($node->getProperty('name')); - } else { - $label = ($node->getNodeType()->getLabel() ?: $node->getNodeType()->getName()) . ' (' . $node->getName() . ')'; - } - - return $label; - } -} diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/NodeType.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/NodeType.php deleted file mode 100644 index c5f6ec7..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/NodeType.php +++ /dev/null @@ -1,214 +0,0 @@ -name = (string)$name; - $this->type = (string)$type; - } - - /** - * @return string - */ - public function getName() { - return $this->name; - } - - /** - * @return string - */ - public function getLabel() { - list(, $label) = explode(':', $this->getName()); - return $label; - } - - /** - * @return boolean - */ - public function getAbstract() { - return $this->abstract; - } - - /** - * @return boolean - */ - public function getFinal() { - return $this->final; - } - - /** - * @return array - */ - public function getDefaultConfiguration() { - return Arrays::arrayMergeRecursiveOverrule($this->configurationService->getTypeDefaultConfiguration($this->type), array( - 'ui' => array( - 'label' => $this->getLabel(), - ) - )); - } - - /** - * @return array - */ - public function getConfiguration() { - return $this->configuration; - } - - /** - * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz' - * @param mixed $value - */ - public function setConfigurationByPath($path, $value) { - $this->configuration = Arrays::setValueByPath($this->configuration, $path, $value); - } - - /** - * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz' - * @param mixed $value - */ - public function getConfigurationByPath($path) { - $this->configuration = Arrays::getValueByPath($this->configuration, $path); - } - - /** - * @param string $superTypeName - */ - public function addSuperType($superTypeName) { - $this->superTypes[$superTypeName] = TRUE; - } - - /** - * @return array - */ - public function getSuperTypes() { - $superTypes = array(); - foreach ($this->superTypes as $superTypeName=>$superTypeStatus) { - if ($superTypeStatus === TRUE) { - $superTypes[] = $superTypeName; - } - } - - return $superTypes; - } - - /** - * @return boolean - */ - public function hasSuperTypes() { - return (boolean)count($this->getSuperTypes()); - } - - /** - * @return array - */ - public function getRelatedNodeTypes() { - return $this->relatedNodeTypes; - } - - /** - * @return array - */ - public function getProperties() { - return $this->properties; - } - - /** - * @param array $properties - */ - public function setProperties($properties) { - $this->properties = array(); - foreach ($properties as $property) { - $this->initializeRelatedNodeTypes($property); - /** @var Property $property */ - if ($property->isSkipProperty()) { - continue; - } - $propertyName = $property->getName(); - $configuration = $property->getConfiguration(); - - $this->properties[$propertyName] = $this->configurationService->mergePropertyConfigurationWithDefaultConfiguration($propertyName, $this->getName(), $configuration); - } - } - - /** - * @return boolean - */ - public function hasProperties() { - return (boolean)count($this->getProperties()); - } - - /** - * @param Property $property - * @return void - */ - protected function initializeRelatedNodeTypes(Property $property) { - if (substr($property->getType(), 0, 9) !== 'reference') { - return; - } - - $configuration = $property->getConfiguration(); - $nodeTypes = Arrays::getValueByPath($configuration, 'ui.inspector.editorOptions.nodeTypes') ?: array(); - foreach ($nodeTypes as $nodeType) { - $this->relatedNodeTypes[$nodeType] = TRUE; - } - } - -} \ No newline at end of file diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/Property.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/Property.php deleted file mode 100644 index daaf335..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Domain/Model/Property.php +++ /dev/null @@ -1,167 +0,0 @@ - 'boolean', - 'Date' => 'date', - 'DateTime' => 'date', - 'Float' => 'float', - 'Number' => 'integer', - 'Integer' => 'integer', - 'Text' => 'string', - 'Time' => 'date', - 'URL' => 'string' - ); - - /** - * @var string - */ - protected $name; - - /** - * @var string - */ - protected $label; - - /** - * @var string - */ - protected $comment; - - /** - * @var string - */ - protected $type; - - /** - * @var boolean - */ - protected $reloadIfChanged; - - /** - * @var array - */ - protected $ui = array(); - - /** - * @var boolean - */ - protected $skipProperty = FALSE; - - /** - * @param ConfigurationService $configurationService - * @param string $type - * @param string $name - * @param string $label - * @param string $comment - * @param string $groupName - * @param boolean $reloadIfChanged - * - */ - public function __construct(ConfigurationService $configurationService, $type, $name, $label, $comment, $groupName, $reloadIfChanged = FALSE) { - $this->configurationService = $configurationService; - $this->type = $this->convertDataType($type, $name); - $this->name = (string)$name; - $this->label = (string)$label; - $this->comment = (string)$comment; - $this->ui = Arrays::arrayMergeRecursiveOverrule($this->ui, array( - 'label' => $this->label, - 'comment' => $this->comment, - 'inspector' => array( - 'group' => $groupName - ) - )); - $this->reloadIfChanged = (boolean)$reloadIfChanged; - } - - /** - * @return boolean - */ - public function isSkipProperty() { - return $this->skipProperty; - } - - /** - * @param boolean $skipProperty - */ - public function setSkipProperty($skipProperty) { - $this->skipProperty = $skipProperty; - } - - /** - * @return string - */ - public function getName() { - return $this->name; - } - - /** - * @return string - */ - public function getType() { - return $this->type; - } - - /** - * @param string $schemaOrgPropertyName - * @param string $propertyName - * @return string - */ - protected function convertDataType($schemaOrgPropertyName, $propertyName) { - if (strpos($schemaOrgPropertyName, ':')) { - $type = Functions::substr($propertyName, -1) === 's' ? 'references' : 'reference'; - $schemaOrgPropertyName = $this->configurationService->nodeTypeNameMapping($schemaOrgPropertyName); - $this->ui = Arrays::setValueByPath($this->ui, 'inspector', array( - 'editorOptions' => array( - 'nodeTypes' => array($schemaOrgPropertyName) - ) - )); - } else { - if (!isset($this->dataTypeMapping[$schemaOrgPropertyName]) && strpos($schemaOrgPropertyName, ':') > 0) { - throw new \InvalidArgumentException(sprintf('Invalid property type (%s)', $schemaOrgPropertyName), 1396192757); - } - $type = (string)$this->dataTypeMapping[$schemaOrgPropertyName]; - } - return $type; - } - - /** - * @return array - */ - public function getConfiguration() { - $configuration = array( - 'type' => $this->type, - 'ui' => $this->ui - ); - - return $configuration; - } -} \ No newline at end of file diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Service/ConfigurationService.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Service/ConfigurationService.php deleted file mode 100644 index 34e3c55..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Service/ConfigurationService.php +++ /dev/null @@ -1,154 +0,0 @@ -nodeTypeMapping[$typeName])) { - return $this->nodeTypeMapping[$typeName]; - } - - return $nodeTypeName; - } - - /** - * @param string $type - * @return array - */ - public function getTypeDefaultConfiguration($type) { - $configuration = $this->typeDefaultConfiguration['*']; - if (isset($this->typeDefaultConfiguration[$type])) { - $configuration = Arrays::arrayMergeRecursiveOverrule($configuration, $this->typeDefaultConfiguration[$type]); - } - - return $configuration; - } - - /** - * @param string $propertyName - * @param string $nodeTypeName - * @param array $configuration - * @return array - * @todo add support for property configuration override for a given $nodeTypeName - */ - public function mergePropertyConfigurationWithDefaultConfiguration($propertyName, $nodeTypeName, array $configuration) { - $defaultConfiguration = $this->propertyDefaultConfiguration['*']; - $configuration = Arrays::arrayMergeRecursiveOverrule($defaultConfiguration, $configuration); - if (isset($this->propertyDefaultConfiguration[$propertyName]) && is_array($this->propertyDefaultConfiguration[$propertyName])) { - $configuration = Arrays::arrayMergeRecursiveOverrule($configuration, $this->propertyDefaultConfiguration[$propertyName]); - } - - return $configuration; - } - - /** - * @param string $propertyName - * @param string $nodeTypeName - * @return array - * @todo add support for property configuration override for a given $nodeTypeName - */ - public function getNodeTypeMixinsByProperty($propertyName, $nodeTypeName) { - $mixins = array(); - if (isset($this->propertyMixinsMapping[$propertyName]) && is_array($this->propertyMixinsMapping[$propertyName])) { - $mixins = $this->propertyMixinsMapping[$propertyName]; - } - - return $mixins; - } - - /** - * @param string $propertyName - * @param string $nodeTypeName - * @return array - * @todo add support for property configuration override for a given $nodeTypeName - */ - public function isPropertyBlacklisted($propertyName, $nodeTypeName) { - if (isset($this->propertyBlackList[$propertyName]) && $this->propertyBlackList[$propertyName] === TRUE) { - return TRUE; - } - - return FALSE; - } - - /** - * @return string - */ - public function getPackageKey() { - if (trim($this->packageKey) === '') { - return $this->defaultPackageKey; - } - - return $this->packageKey; - } - - /** - * @param string $packageKey - */ - public function setPackageKey($packageKey) { - $this->packageKey = $packageKey; - } - -} \ No newline at end of file diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Service/NodeTypeBuilder.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Service/NodeTypeBuilder.php deleted file mode 100644 index fea75c8..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Service/NodeTypeBuilder.php +++ /dev/null @@ -1,107 +0,0 @@ -filename = $filename; - return $this; - } - - /** - * @return $this - */ - public function unlinkExistingFile() { - Files::unlink($this->getSavePathAndFilename($this->filename)); - return $this; - } - - /** - * @param NodeType $nodeType - * @return string - */ - public function dump(NodeType $nodeType) { - $filename = $this->getFilename(); - $dumper = new Dumper(); - - $configuration = $nodeType->getDefaultConfiguration(); - if ($nodeType->hasSuperTypes()) { - if (!isset($configuration['superTypes'])) { - $configuration['superTypes'] = $nodeType->getSuperTypes(); - } else { - $configuration['superTypes'] = array_merge($nodeType->getSuperTypes(), $configuration['superTypes']); - } - } - if ($nodeType->hasProperties()) { - $configuration['properties'] = $nodeType->getProperties(); - } - $nodeTypeDefinition = array( - $nodeType->getName() => Arrays::arrayMergeRecursiveOverrule($configuration, $nodeType->getConfiguration()) - ); - $dumper->setIndentation(2); - $yaml = $dumper->dump($nodeTypeDefinition, 12); - - Files::createDirectoryRecursively($this->renderedNodeTypeRootPath); - - $filename = $this->getSavePathAndFilename($filename); - file_put_contents($filename, $yaml . chr(10) . chr(10), FILE_APPEND); - - return str_replace(FLOW_PATH_ROOT, '', $filename); - } - - /** - * @return string - */ - protected function getFilename() { - if (trim($this->filename) === '') { - throw new \InvalidArgumentException("Please set the filename property ...", 1412162107); - } - return $this->filename; - } - - /** - * @param string $filename - * @return string - */ - protected function getSavePathAndFilename($filename) { - return $this->renderedNodeTypeRootPath . $filename; - } - -} \ No newline at end of file diff --git a/Classes/Flowpack/SchemaOrg/NodeTypes/Service/SchemaParserService.php b/Classes/Flowpack/SchemaOrg/NodeTypes/Service/SchemaParserService.php deleted file mode 100644 index feeb6a3..0000000 --- a/Classes/Flowpack/SchemaOrg/NodeTypes/Service/SchemaParserService.php +++ /dev/null @@ -1,272 +0,0 @@ -allSchemaJsonFilename = $jsonSchemaFilename; - $this->schemas = array(); - } - - /** - * @return array - * @throws \InvalidArgumentException - */ - public function getSchemas() { - if ($this->schemas !== array()) { - return $this->schemas; - } - $this->schemas = json_decode(file_get_contents($this->allSchemaJsonFilename), TRUE); - if ($this->schemas === NULL) { - throw new \InvalidArgumentException('Unable to decode the given json string', 1396168377); - } - return $this->schemas; - } - - /** - * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz' - * @return mixed - */ - public function getSchemaConfigurationByPath($path) { - $rawSchema = $this->getSchemas(); - return Arrays::getValueByPath($rawSchema, $path); - } - - /** - * @return array - */ - public function parseAll() { - $schemas = array(); - foreach ($this->getSchemaConfigurationByPath('types') as $type => $configuration) { - $schemas = $this->mergeSchema($schemas, $this->parseByType($type)); - } - ksort($schemas); - return $schemas; - } - - /** - * @param array list of schema type to extract, the ancestors schemas will also be extracted - * @return array - * @throws \InvalidArgumentException - */ - public function parseByTypes(array $types) { - $schemas = array(); - foreach ($types as $type) { - $schemas = $this->mergeSchema($schemas, $this->parseByType($type)); - } - ksort($schemas); - return $schemas; - } - - /** - * @param string $type - * @return array - * @throws \InvalidArgumentException - */ - public function parseByType($type) { - static $parsedTypes = array(); - - if (!$type || isset($parsedTypes[$type])) { - return; - } - - $parsedTypes[$type] = TRUE; - - $schemas = array(); - - $currentRawSchema = $this->getSchemaConfigurationByPath(array('types', $type)); - if ($currentRawSchema === NULL) { - throw new \InvalidArgumentException(sprintf('The given type (%s) is not found', $type), 1396190989); - } - - $typeName = $this->getNodeTypeName($type); - $groupName = strtolower($type); - - $nodeType = new NodeType($typeName, $type); - $inspector = array( - 'label' => $currentRawSchema['label'] - ); - if ($currentRawSchema['comment']) { - $inspector['comment'] = $currentRawSchema['comment']; - } - $nodeType->setConfigurationByPath('ui', array( - 'inspector' => array( - 'groups' => array( - $groupName => $inspector - ) - ) - )); - - foreach ($this->parseSuperTypes($type) as $superTypeName => $configuration) { - $schemas[$superTypeName] = $configuration; - if (!isset($schemas[$typeName]['superTypes']) || !is_array($schemas[$typeName]['superTypes'])) { - $schemas[$typeName]['superTypes'] = array(); - } - } - $superTypes = $this->getSchemaConfigurationByPath(array('types', $type, 'supertypes')); - $superType = trim(array_shift($superTypes)); - if ($superType !== '') { - $nodeType->addSuperType($this->getNodeTypeName($superType)); - } - - $nodeType->setProperties($this->processProperties($currentRawSchema['specific_properties'], $groupName, $nodeType)); - - $this->parseRelatedNodeTypes($nodeType, $schemas); - - $schemas[$typeName] = $nodeType; - - return $schemas; - } - - /** - * @param string $dataType - * @return boolean - */ - public function isSimpleDataType($dataType) { - return $this->getSchemaConfigurationByPath(array('datatypes', $dataType)) ? TRUE : FALSE; - } - - /** - * @param array $specificProperties - * @param string $groupName - * @param NodeType $nodeType - * @return array - * @todo add support for Ranges, when we found a correct solution - */ - protected function processProperties(array $specificProperties, $groupName, NodeType $nodeType) { - $currentProperties = array(); - foreach ($specificProperties as $propertyName) { - $skipProperty = FALSE; - $propertyConfiguration = $this->getSchemaConfigurationByPath(array('properties', $propertyName)); - $type = reset($propertyConfiguration['ranges']); - - if ($this->configurationService->isPropertyBlacklisted($propertyName, $type)) { - continue; - } - - foreach ($this->configurationService->getNodeTypeMixinsByProperty($propertyName, $type) as $mixin) { - $nodeType->addSuperType($mixin); - $skipProperty = TRUE; - } - - $property = new Property( - $this->configurationService, - $this->isSimpleDataType($type) ? $type : $this->getNodeTypeName($type), - $propertyConfiguration['id'], - $propertyConfiguration['label'], - $propertyConfiguration['comment'], - $groupName, - FALSE - ); - - $property->setSkipProperty($skipProperty); - $currentProperties[$propertyName] = $property; - } - return $currentProperties; - } - - /** - * @param string $type - * @return array - */ - protected function parseSuperTypes($type) { - $schemas = array(); - $superTypes = $this->getSchemaConfigurationByPath(array('types', $type, 'supertypes')) ?: array(); - foreach ($superTypes as $superType) { - $schemas = $this->mergeSchema($schemas, $this->parseByType($superType)); - } - - return $schemas; - } - - /** - * @param NodeType $nodeType - * @param array $schema - */ - protected function parseRelatedNodeTypes(NodeType $nodeType, array &$schema) { - foreach ($nodeType->getRelatedNodeTypes() as $nodeType => $status) { - $typeName = $this->getSchemaOrgTypeName($nodeType); - if ($typeName === NULL || isset($schemas[$typeName])) { - continue; - } - $schema = $this->mergeSchema($schema, $this->parseByType($typeName)); - } - } - - /** - * @param array $currentSchemas - * @param array|null $additionalSchemas - * @return array - */ - protected function mergeSchema(array $currentSchemas, $additionalSchemas) { - if (is_array($additionalSchemas)) { - $currentSchemas = Arrays::arrayMergeRecursiveOverrule($currentSchemas, $additionalSchemas); - } - return $currentSchemas; - } - - /** - * @param string $schemaType - * @return string - * @throws \InvalidException - */ - protected function getNodeTypeName($schemaType) { - $schemaType = trim($schemaType); - if ($schemaType === '') { - throw new \InvalidException("Empty super type name is not allowed", 1412115678); - } - return $this->configurationService->getPackageKey() . ':' . $schemaType; - } - - protected function getSchemaOrgTypeName($nodeType) { - if (strpos($nodeType, $this->configurationService->getPackageKey()) === FALSE) { - return NULL; - } - - return str_replace($this->configurationService->getPackageKey() . ':', '', $nodeType); - } - -} \ No newline at end of file diff --git a/Classes/Service/ConfigurationService.php b/Classes/Service/ConfigurationService.php new file mode 100644 index 0000000..d57bd15 --- /dev/null +++ b/Classes/Service/ConfigurationService.php @@ -0,0 +1,155 @@ +nodeTypeMapping[$typeName])) { + return $this->nodeTypeMapping[$typeName]; + } + + return $nodeTypeName; + } + + /** + * @param string $type + * @return array + */ + public function getTypeDefaultConfiguration($type) + { + $configuration = $this->typeDefaultConfiguration['*']; + if (isset($this->typeDefaultConfiguration[$type])) { + $configuration = Arrays::arrayMergeRecursiveOverrule($configuration, $this->typeDefaultConfiguration[$type]); + } + + return $configuration; + } + + /** + * @param string $propertyName + * @param string $nodeTypeName + * @param array $configuration + * @return array + * @todo add support for property configuration override for a given $nodeTypeName + */ + public function mergePropertyConfigurationWithDefaultConfiguration($propertyName, $nodeTypeName, array $configuration) + { + $defaultConfiguration = $this->propertyDefaultConfiguration['*']; + $configuration = Arrays::arrayMergeRecursiveOverrule($defaultConfiguration, $configuration); + if (isset($this->propertyDefaultConfiguration[$propertyName]) && is_array($this->propertyDefaultConfiguration[$propertyName])) { + $configuration = Arrays::arrayMergeRecursiveOverrule($configuration, $this->propertyDefaultConfiguration[$propertyName]); + } + + return $configuration; + } + + /** + * @param string $propertyName + * @param string $nodeTypeName + * @return array + * @todo add support for property configuration override for a given $nodeTypeName + */ + public function getNodeTypeMixinsByProperty($propertyName, $nodeTypeName) + { + $mixins = []; + if (isset($this->propertyMixinsMapping[$propertyName]) && is_array($this->propertyMixinsMapping[$propertyName])) { + $mixins = $this->propertyMixinsMapping[$propertyName]; + } + + return $mixins; + } + + /** + * @param string $propertyName + * @param string $nodeTypeName + * @return boolean + * @todo add support for property configuration override for a given $nodeTypeName + */ + public function isPropertyBlacklisted($propertyName, $nodeTypeName) + { + if (isset($this->propertyBlackList[$propertyName]) && $this->propertyBlackList[$propertyName] === true) { + return true; + } + + return false; + } + + /** + * @return string + */ + public function getPackageKey() + { + if (trim($this->packageKey) === '') { + return $this->defaultPackageKey; + } + + return $this->packageKey; + } + + /** + * @param string $packageKey + */ + public function setPackageKey($packageKey) + { + $this->packageKey = $packageKey; + } +} diff --git a/Classes/Service/NodeTypeBuilder.php b/Classes/Service/NodeTypeBuilder.php new file mode 100644 index 0000000..62b37f2 --- /dev/null +++ b/Classes/Service/NodeTypeBuilder.php @@ -0,0 +1,109 @@ +filename = $filename; + return $this; + } + + /** + * @return $this + */ + public function unlinkExistingFile() + { + Files::unlink($this->getSavePathAndFilename($this->filename)); + return $this; + } + + /** + * @param NodeType $nodeType + * @return string + */ + public function dump(NodeType $nodeType) + { + $filename = $this->getFilename(); + $dumper = new Dumper(); + + $configuration = $nodeType->getDefaultConfiguration(); + if ($nodeType->hasSuperTypes()) { + if (!isset($configuration['superTypes'])) { + $superTypes = $nodeType->getSuperTypes(); + } else { + $superTypes = array_merge($nodeType->getSuperTypes(), $configuration['superTypes']); + } + $configuration['superTypes'] = []; + foreach ($superTypes as $superType) { + $configuration['superTypes'][$superType] = true; + } + } + if ($nodeType->hasProperties()) { + $configuration['properties'] = $nodeType->getProperties(); + } + $nodeTypeDefinition = [ + $nodeType->getName() => Arrays::arrayMergeRecursiveOverrule($configuration, $nodeType->getConfiguration()), + ]; + $dumper->setIndentation(2); + $yaml = $dumper->dump($nodeTypeDefinition, 12); + + Files::createDirectoryRecursively($this->renderedNodeTypeRootPath); + + $filename = $this->getSavePathAndFilename($filename); + file_put_contents($filename, $yaml . chr(10) . chr(10), FILE_APPEND); + + return str_replace(FLOW_PATH_ROOT, '', $filename); + } + + /** + * @return string + */ + protected function getFilename() + { + if (trim($this->filename) === '') { + throw new \InvalidArgumentException('Please set the filename property ...', 1412162107); + } + return $this->filename; + } + + /** + * @param string $filename + * @return string + */ + protected function getSavePathAndFilename($filename) + { + return $this->renderedNodeTypeRootPath . $filename; + } +} diff --git a/Classes/Service/SchemaParserService.php b/Classes/Service/SchemaParserService.php new file mode 100644 index 0000000..b0420b0 --- /dev/null +++ b/Classes/Service/SchemaParserService.php @@ -0,0 +1,279 @@ +allSchemaJsonFilename = $jsonSchemaFilename; + $this->schemas = []; + } + + /** + * @throws \InvalidArgumentException + * @return array + */ + public function getSchemas() + { + if ($this->schemas !== []) { + return $this->schemas; + } + $this->schemas = json_decode(file_get_contents($this->allSchemaJsonFilename), true); + if ($this->schemas === null) { + throw new \InvalidArgumentException('Unable to decode the given json string', 1396168377); + } + return $this->schemas; + } + + /** + * @param array|string $path The path to follow. Either a simple array of keys or a string in the format 'foo.bar.baz' + * @return mixed + */ + public function getSchemaConfigurationByPath($path) + { + $rawSchema = $this->getSchemas(); + return Arrays::getValueByPath($rawSchema, $path); + } + + /** + * @return array + */ + public function parseAll() + { + $schemas = []; + foreach ($this->getSchemaConfigurationByPath('types') as $type => $configuration) { + $schemas = $this->mergeSchema($schemas, $this->parseByType($type)); + } + ksort($schemas); + return $schemas; + } + + /** + * @param array list of schema type to extract, the ancestors schemas will also be extracted + * @throws \InvalidArgumentException + * @return array + */ + public function parseByTypes(array $types) + { + $schemas = []; + foreach ($types as $type) { + $schemas = $this->mergeSchema($schemas, $this->parseByType($type)); + } + ksort($schemas); + return $schemas; + } + + /** + * @param string $type + * @throws \InvalidArgumentException + * @return array + */ + public function parseByType($type) + { + static $parsedTypes = []; + + if (!$type || isset($parsedTypes[$type])) { + return; + } + + $parsedTypes[$type] = true; + + $schemas = []; + + $currentRawSchema = $this->getSchemaConfigurationByPath(['types', $type]); + if ($currentRawSchema === null) { + throw new \InvalidArgumentException(sprintf('The given type (%s) is not found', $type), 1396190989); + } + + $typeName = $this->getNodeTypeName($type); + $groupName = strtolower($type); + + $nodeType = new NodeType($typeName, $type); + $inspector = [ + 'label' => $currentRawSchema['label'], + ]; + if ($currentRawSchema['comment']) { + $inspector['comment'] = $currentRawSchema['comment']; + } + $nodeType->setConfigurationByPath('ui', [ + 'inspector' => [ + 'groups' => [ + $groupName => $inspector, + ], + ], + ]); + + foreach ($this->parseSuperTypes($type) as $superTypeName => $configuration) { + $schemas[$superTypeName] = $configuration; + if (!isset($schemas[$typeName]['superTypes']) || !is_array($schemas[$typeName]['superTypes'])) { + $schemas[$typeName]['superTypes'] = []; + } + } + $superTypes = $this->getSchemaConfigurationByPath(['types', $type, 'supertypes']); + $superType = trim(array_shift($superTypes)); + if ($superType !== '') { + $nodeType->addSuperType($this->getNodeTypeName($superType)); + } + + $nodeType->setProperties($this->processProperties($currentRawSchema['specific_properties'], $groupName, $nodeType)); + + $this->parseRelatedNodeTypes($nodeType, $schemas); + + $schemas[$typeName] = $nodeType; + + return $schemas; + } + + /** + * @param string $dataType + * @return bool + */ + public function isSimpleDataType($dataType) + { + return $this->getSchemaConfigurationByPath(['datatypes', $dataType]) ? true : false; + } + + /** + * @param array $specificProperties + * @param string $groupName + * @param NodeType $nodeType + * @return array + * @todo add support for Ranges, when we found a correct solution + */ + protected function processProperties(array $specificProperties, $groupName, NodeType $nodeType) + { + $currentProperties = []; + foreach ($specificProperties as $propertyName) { + $skipProperty = false; + $propertyConfiguration = $this->getSchemaConfigurationByPath(['properties', $propertyName]); + $type = reset($propertyConfiguration['ranges']); + + if ($this->configurationService->isPropertyBlacklisted($propertyName, $type)) { + continue; + } + + foreach ($this->configurationService->getNodeTypeMixinsByProperty($propertyName, $type) as $mixin) { + $nodeType->addSuperType($mixin); + $skipProperty = true; + } + + $property = new Property( + $this->configurationService, + $this->isSimpleDataType($type) ? $type : $this->getNodeTypeName($type), + $propertyConfiguration['id'], + $propertyConfiguration['label'], + $propertyConfiguration['comment'], + $groupName, + false + ); + + $property->setSkipProperty($skipProperty); + $currentProperties[$propertyName] = $property; + } + return $currentProperties; + } + + /** + * @param string $type + * @return array + */ + protected function parseSuperTypes($type) + { + $schemas = []; + $superTypes = $this->getSchemaConfigurationByPath(['types', $type, 'supertypes']) ?: []; + foreach ($superTypes as $superType) { + $schemas = $this->mergeSchema($schemas, $this->parseByType($superType)); + } + + return $schemas; + } + + /** + * @param NodeType $nodeType + * @param array $schema + */ + protected function parseRelatedNodeTypes(NodeType $nodeType, array &$schema) + { + foreach ($nodeType->getRelatedNodeTypes() as $nodeType => $status) { + $typeName = $this->getSchemaOrgTypeName($nodeType); + if ($typeName === null || isset($schemas[$typeName])) { + continue; + } + $schema = $this->mergeSchema($schema, $this->parseByType($typeName)); + } + } + + /** + * @param array $currentSchemas + * @param array|null $additionalSchemas + * @return array + */ + protected function mergeSchema(array $currentSchemas, $additionalSchemas) + { + if (is_array($additionalSchemas)) { + $currentSchemas = Arrays::arrayMergeRecursiveOverrule($currentSchemas, $additionalSchemas); + } + return $currentSchemas; + } + + /** + * @param string $schemaType + * @throws \InvalidArgumentException + * @return string + */ + protected function getNodeTypeName($schemaType) + { + $schemaType = trim($schemaType); + if ($schemaType === '') { + throw new \InvalidArgumentException('Empty super type name is not allowed', 1412115678); + } + return $this->configurationService->getPackageKey() . ':' . $schemaType; + } + + protected function getSchemaOrgTypeName($nodeType) + { + if (strpos($nodeType, $this->configurationService->getPackageKey()) === false) { + return null; + } + + return str_replace($this->configurationService->getPackageKey() . ':', '', $nodeType); + } +} diff --git a/Configuration/NodeTypes.Mixins.yaml b/Configuration/NodeTypes.Mixins.yaml index d630fd6..eb1afea 100644 --- a/Configuration/NodeTypes.Mixins.yaml +++ b/Configuration/NodeTypes.Mixins.yaml @@ -33,14 +33,14 @@ abstract: TRUE childNodes: articleBody: - type: 'TYPO3.Neos:ContentCollection' + type: 'Neos.Neos:ContentCollection' # Comment mixin 'Flowpack.SchemaOrg.NodeTypes:CommentMixin': abstract: TRUE childNodes: comment: - type: 'TYPO3.Neos:ContentCollection' + type: 'Neos.Neos:ContentCollection' constraints: nodeTypes: '*': FALSE @@ -79,7 +79,7 @@ abstract: TRUE properties: photo: - type: TYPO3\Media\Domain\Model\ImageVariant + type: Neos\Media\Domain\Model\ImageInterface ui: label: 'Image' reloadIfChanged: TRUE @@ -90,7 +90,7 @@ abstract: TRUE properties: photos: - type: TYPO3\Media\Domain\Model\ImageVariant + type: Neos\Media\Domain\Model\ImageInterface ui: label: 'Images' reloadIfChanged: TRUE \ No newline at end of file diff --git a/Configuration/Settings.yaml b/Configuration/Settings.yaml index 0747c43..66b942e 100644 --- a/Configuration/Settings.yaml +++ b/Configuration/Settings.yaml @@ -9,7 +9,7 @@ Flowpack: jsonFilename: 'resource://Flowpack.SchemaOrg.NodeTypes/Private/Schema/All.json' nodeTypeMapping: - ImageObject: 'TYPO3.Neos.NodeTypes:Image' + ImageObject: 'Neos.NodeTypes:Image' propertyBlackList: # todo: add support for relation to an other Document @@ -32,7 +32,7 @@ Flowpack: 'Review': abstract: FALSE superTypes: - - 'TYPO3.Neos.NodeTypes:Page' + - 'Neos.NodeTypes:Page' 'PostalAddress': ui: @@ -49,23 +49,23 @@ Flowpack: 'Event': abstract: FALSE superTypes: - - 'TYPO3.Neos.NodeTypes:Page' + - 'Neos.NodeTypes:Page' 'Place': abstract: FALSE superTypes: - - 'TYPO3.Neos:Content' + - 'Neos.Neos:Content' 'VideoObject': abstract: FALSE superTypes: - - 'TYPO3.Neos:Content' + - 'Neos.Neos:Content' propertyMixinsMapping: 'image': - - 'TYPO3.Neos.NodeTypes:ImageMixin' - - 'TYPO3.Neos.NodeTypes:ImageCaptionMixin' + - 'Neos.NodeTypes:ImageMixin' + - 'Neos.NodeTypes:ImageCaptionMixin' 'description': - 'Flowpack.SchemaOrg.NodeTypes:DescriptionMixin' @@ -103,17 +103,17 @@ Flowpack: type: 'string' validation: validation: - 'TYPO3.Neos/Validation/EmailAddressValidator': [] + 'Neos.Neos/Validation/EmailAddressValidator': [] 'logo': - type: TYPO3\Media\Domain\Model\ImageVariant + type: Neos\Media\Domain\Model\ImageInterface ui: label: 'Image' 'proficiencyLevel': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -127,7 +127,7 @@ Flowpack: 'accessibilityAPI': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -159,7 +159,7 @@ Flowpack: 'accessibilityControl': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -181,7 +181,7 @@ Flowpack: 'accessibilityFeature': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -249,7 +249,7 @@ Flowpack: 'accessibilityHazard': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -270,7 +270,7 @@ Flowpack: 'educationalUse': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -283,7 +283,7 @@ Flowpack: 'interactivityType': ui: inspector: - editor: 'TYPO3.Neos/Inspector/Editors/SelectBoxEditor' + editor: 'Neos.Neos/Inspector/Editors/SelectBoxEditor' editorOptions: values: '': @@ -296,4 +296,4 @@ Flowpack: label: 'mixed' 'associatedMedia': - type: array + type: array diff --git a/README.md b/README.md index 8a813d0..7650615 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ -TYPO3 Neos Utility to create NodeType based on schema.org -========================================================= +Neos Utility to create NodeType based on schema.org +=================================================== This plugin provides a service to create NodeType YAML configuration based on schema.org type. You can found the full schema.org types list here: http://schema.org/docs/full.html @@ -151,7 +151,7 @@ Flowpack: 'Review': abstract: FALSE superTypes: - - 'TYPO3.Neos.NodeTypes:Page' + - 'Neos.NodeTypes:Page' 'PostalAddress': ui: icon: 'icon-building' @@ -167,7 +167,7 @@ Flowpack: SchemaOrg: NodeTypes: nodeTypeMapping: - ImageObject: 'TYPO3.Neos.NodeTypes:Image' + ImageObject: 'Neos.NodeTypes:Image' ``` Configuration: Property Blacklist @@ -195,8 +195,8 @@ Flowpack: NodeTypes: propertyMixinsMapping: 'image': - - 'TYPO3.Neos.NodeTypes:ImageMixin' - - 'TYPO3.Neos.NodeTypes:ImageCaptionMixin' + - 'Neos.NodeTypes:ImageMixin' + - 'Neos.NodeTypes:ImageCaptionMixin' ``` Configuration: Override property configuration @@ -214,5 +214,41 @@ Flowpack: type: 'string' validation: validation: - 'TYPO3.Neos/Validation/EmailAddressValidator': [] -``` \ No newline at end of file + 'Neos.Neos/Validation/EmailAddressValidator': [] +``` + +Fusion prototype generation +--------------------------- + +As you might want to use the generate schema properties to be included as `JSON-LD` in your template and not +copy paste all properties into Fusion or Fluid (Fusion preferred of course), we provide a Fusion-Generator +that auto-generates Fusion prototypes for every abstract NodeType that is used in your node. + +Given you have a nodeType definition and auto-generated the `JobPosting` schema e.g. + +```yaml +'My.Site:Job': + options: + fusion: + prototypeGenerator: Flowpack\SchemaOrg\NodeTypes\Domain\Service\SchemaOrgPrototypeGenerator + superTypes: + 'Neos.NodeTypes:Page': true + 'My.Site:JobPosting': true +``` + +The prototype generator will generate Fusion objects for all abstract superTypes with name `My.Site:JobPosting.Schema` +that is a `Neos.Fusion:RawArray` containing all properties already. + +You can simply use: + +```neosfusion +jobPostingMeta = Neos.Fusion:Tag { + tagName = 'script' + attributes.type = 'application/ld+json' + content = My.Site:JobPosting.Schema { + @process.json = ${Json.stringify(value)} + } +} +``` + +to have a full `JSON-LD` in your frontend without manually mapping all properties. diff --git a/Tests/Unit/Domain/Model/NodeTypeTest.php b/Tests/Unit/Domain/Model/NodeTypeTest.php index da3b7a9..d092d49 100644 --- a/Tests/Unit/Domain/Model/NodeTypeTest.php +++ b/Tests/Unit/Domain/Model/NodeTypeTest.php @@ -1,89 +1,91 @@ assertSame('Foo', $nodeType->getName()); - } + /** + * @test + */ + public function getNameReturnTheName() + { + $nodeType = new NodeType('Foo'); + $this->assertSame('Foo', $nodeType->getName()); + } - /** - * @test - */ - public function getAbstractReturnTheAbstractValueByDefaultFalse() { - $nodeType = new NodeType('Foo'); - $this->assertSame(FALSE, $nodeType->getAbstract()); - $nodeType = new NodeType('Foo', TRUE); - $this->assertSame(TRUE, $nodeType->getAbstract()); - } + /** + * @test + */ + public function getAbstractReturnTheAbstractValueByDefaultFalse() + { + $nodeType = new NodeType('Foo'); + $this->assertSame(false, $nodeType->getAbstract()); + $nodeType = new NodeType('Foo', true); + $this->assertSame(true, $nodeType->getAbstract()); + } - /** - * @test - */ - public function getFinalReturnTheFinalValueByDefaultFalse() { - $nodeType = new NodeType('Foo'); - $this->assertSame(FALSE, $nodeType->getFinal()); - $nodeType = new NodeType('Foo', TRUE, TRUE); - $this->assertSame(TRUE, $nodeType->getFinal()); - } + /** + * @test + */ + public function getFinalReturnTheFinalValueByDefaultFalse() + { + $nodeType = new NodeType('Foo'); + $this->assertSame(false, $nodeType->getFinal()); + $nodeType = new NodeType('Foo', true, true); + $this->assertSame(true, $nodeType->getFinal()); + } - /** - * @test - */ - public function getConfigurationReturnAnArray() { - $nodeType = new NodeType('Foo'); - $this->assertSame(array(), $nodeType->getConfiguration()); - } + /** + * @test + */ + public function getConfigurationReturnAnArray() + { + $nodeType = new NodeType('Foo'); + $this->assertSame([], $nodeType->getConfiguration()); + } - /** - * @test - */ - public function setConfigurationByPathUpdateTheCurrentConfiguration() { - $nodeType = new NodeType('Foo'); - $nodeType->setConfigurationByPath('foo.fii', 'Hello World'); - $this->assertSame(array( - 'foo' => array( - 'fii' => 'Hello World' - ) - ), $nodeType->getConfiguration()); - } + /** + * @test + */ + public function setConfigurationByPathUpdateTheCurrentConfiguration() + { + $nodeType = new NodeType('Foo'); + $nodeType->setConfigurationByPath('foo.fii', 'Hello World'); + $this->assertSame([ + 'foo' => [ + 'fii' => 'Hello World', + ], + ], $nodeType->getConfiguration()); + } - /** - * @test - */ - public function getSuperTypeReturnAnArray() { - $nodeType = new NodeType('Foo'); - $this->assertSame(array(), $nodeType->getSuperTypes()); - } + /** + * @test + */ + public function getSuperTypeReturnAnArray() + { + $nodeType = new NodeType('Foo'); + $this->assertSame([], $nodeType->getSuperTypes()); + } - /** - * @test - */ - public function addSuperTypeRegisterNewSuperType() { - $nodeType = new NodeType('Foo'); - $nodeType->addSuperType('Flowpack.SchemaOrg.NodeTypes:Test'); - $this->assertSame(array( - 'Flowpack.SchemaOrg.NodeTypes:Test' => TRUE - ), $nodeType->getSuperTypes()); - } -} \ No newline at end of file + /** + * @test + */ + public function addSuperTypeRegisterNewSuperType() + { + $nodeType = new NodeType('Foo'); + $nodeType->addSuperType('Flowpack.SchemaOrg.NodeTypes:Test'); + $this->assertSame([ + 'Flowpack.SchemaOrg.NodeTypes:Test' => true, + ], $nodeType->getSuperTypes()); + } +} diff --git a/Tests/Unit/Service/SchemaParserServiceTest.php b/Tests/Unit/Service/SchemaParserServiceTest.php index 1b4bebc..5f7007d 100644 --- a/Tests/Unit/Service/SchemaParserServiceTest.php +++ b/Tests/Unit/Service/SchemaParserServiceTest.php @@ -1,99 +1,101 @@ setAllSchemaJsonFilename(__DIR__ . '/Fixtures/Minimal.json'); - return $parser; - } + /** + * @return SchemaParserService + */ + protected function createParser() + { + parent::setUp(); + $parser = new SchemaParserService(); + $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/Minimal.json'); + return $parser; + } - /** - * @test - * @expectedException InvalidArgumentException - * @expectedExceptionCode 1396190384 - */ - public function setAllSchemaJsonFilenameThrowAnExceptionIfTheFileIsNotFound() { - $parser = $this->createParser(); - $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/NotFound.json'); - } + /** + * @test + * @expectedException \InvalidArgumentException + * @expectedExceptionCode 1396190384 + */ + public function setAllSchemaJsonFilenameThrowAnExceptionIfTheFileIsNotFound() + { + $parser = $this->createParser(); + $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/NotFound.json'); + } - /** - * @test - * @expectedException InvalidArgumentException - * @expectedExceptionCode 1396168377 - */ - public function getSchemasReturnAnExceptionIfTheGivenJsonFileIsNotValid() { - $parser = $this->createParser(); - $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/Invalid.json'); - $parser->getSchemas(); - } + /** + * @test + * @expectedException \InvalidArgumentException + * @expectedExceptionCode 1396168377 + */ + public function getSchemasReturnAnExceptionIfTheGivenJsonFileIsNotValid() + { + $parser = $this->createParser(); + $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/Invalid.json'); + $parser->getSchemas(); + } - /** - * @test - */ - public function setAllSchemaJsonFilenameResetTheProcessedSchemas() { - $parser = $this->createParser(); - $parser->parseByTypes(array('Thing')); - $currentSchemas = $parser->getSchemas(); - $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/Empty.json'); - $this->assertSame(__DIR__ . '/Fixtures/Empty.json', ObjectAccess::getProperty($parser, 'allSchemaJsonFilename', TRUE)); - $this->assertNotSame($currentSchemas, $parser->getSchemas()); - } + /** + * @test + */ + public function setAllSchemaJsonFilenameResetTheProcessedSchemas() + { + $parser = $this->createParser(); + $parser->parseByTypes(['Thing']); + $currentSchemas = $parser->getSchemas(); + $parser->setAllSchemaJsonFilename(__DIR__ . '/Fixtures/Empty.json'); + $this->assertSame(__DIR__ . '/Fixtures/Empty.json', ObjectAccess::getProperty($parser, 'allSchemaJsonFilename', true)); + $this->assertNotSame($currentSchemas, $parser->getSchemas()); + } - /** - * @test - * @expectedException InvalidArgumentException - * @expectedExceptionCode 1396190989 - */ - public function parseByTypeThrowAnExceptionIfTheTypeIsNotFound() { - $parser = $this->createParser(); - $parser->parseByTypes(array('Foo')); - } + /** + * @test + * @expectedException \InvalidArgumentException + * @expectedExceptionCode 1396190989 + */ + public function parseByTypeThrowAnExceptionIfTheTypeIsNotFound() + { + $parser = $this->createParser(); + $parser->parseByTypes(['Foo']); + } - /** - * @test - */ - public function parseByTypesReturnTheGivenSchemaWithAllSuperTypes() { - $parser = $this->createParser(); - $nodeTypes = $parser->parseByTypes(array('Person')); + /** + * @test + */ + public function parseByTypesReturnTheGivenSchemaWithAllSuperTypes() + { + $parser = $this->createParser(); + $nodeTypes = $parser->parseByTypes(['Person']); - $this->assertTrue(count($nodeTypes) === 2); - $keys = array_keys($nodeTypes); + $this->assertTrue(count($nodeTypes) === 2); + $keys = array_keys($nodeTypes); - $this->assertSame('Flowpack.SchemaOrg.NodeTypes:Thing', $keys[0]); - $this->assertSame('Flowpack.SchemaOrg.NodeTypes:Person', $keys[1]); - } + $this->assertSame('Flowpack.SchemaOrg.NodeTypes:Thing', $keys[0]); + $this->assertSame('Flowpack.SchemaOrg.NodeTypes:Person', $keys[1]); + } - /** - * @test - */ - public function parseAllReturnAllAvailableNodeType() { - $parser = $this->createParser(); - $nodeTypes = $parser->parseAll(); - $this->assertSame(548, count($nodeTypes)); - } -} \ No newline at end of file + /** + * @test + */ + public function parseAllReturnAllAvailableNodeType() + { + $parser = $this->createParser(); + $nodeTypes = $parser->parseAll(); + $this->assertSame(548, count($nodeTypes)); + } +} diff --git a/composer.json b/composer.json index b05bc40..3e603d5 100644 --- a/composer.json +++ b/composer.json @@ -1,13 +1,90 @@ { "name": "flowpack/schemaorg-nodetypes", - "type": "typo3-flow-package", - "description": "Add description here", + "type": "neos-package", + "description": "Generate nodeType YAML definitions from schema.org types", "require": { - "typo3/flow": "*" + "neos/flow": "^4.0" }, "autoload": { - "psr-0": { - "Flowpack\\SchemaOrg\\NodeTypes": "Classes" + "psr-4": { + "Flowpack\\SchemaOrg\\NodeTypes\\": "Classes" } + }, + "extra": { + "applied-flow-migrations": [ + "TYPO3.FLOW3-201201261636", + "TYPO3.Fluid-201205031303", + "TYPO3.FLOW3-201205292145", + "TYPO3.FLOW3-201206271128", + "TYPO3.FLOW3-201209201112", + "TYPO3.Flow-201209251426", + "TYPO3.Flow-201211151101", + "TYPO3.Flow-201212051340", + "TYPO3.TypoScript-130516234520", + "TYPO3.TypoScript-130516235550", + "TYPO3.TYPO3CR-130523180140", + "TYPO3.Neos.NodeTypes-201309111655", + "TYPO3.Flow-201310031523", + "TYPO3.Flow-201405111147", + "TYPO3.Neos-201407061038", + "TYPO3.Neos-201409071922", + "TYPO3.TYPO3CR-140911160326", + "TYPO3.Neos-201410010000", + "TYPO3.TYPO3CR-141101082142", + "TYPO3.Neos-20141113115300", + "TYPO3.Fluid-20141113120800", + "TYPO3.Flow-20141113121400", + "TYPO3.Fluid-20141121091700", + "TYPO3.Neos-20141218134700", + "TYPO3.Fluid-20150214130800", + "TYPO3.Neos-20150303231600", + "TYPO3.TYPO3CR-20150510103823", + "TYPO3.Flow-20151113161300", + "TYPO3.Form-20160601101500", + "TYPO3.Flow-20161115140400", + "TYPO3.Flow-20161115140430", + "Neos.Flow-20161124204700", + "Neos.Flow-20161124204701", + "Neos.Twitter.Bootstrap-20161124204912", + "Neos.Form-20161124205254", + "Neos.Flow-20161124224015", + "Neos.Party-20161124225257", + "Neos.Eel-20161124230101", + "Neos.Kickstart-20161124230102", + "Neos.Setup-20161124230842", + "Neos.Imagine-20161124231742", + "Neos.Media-20161124233100", + "Neos.NodeTypes-20161125002300", + "Neos.SiteKickstarter-20161125002311", + "Neos.Neos-20161125002322", + "Neos.ContentRepository-20161125012000", + "Neos.Fusion-20161125013710", + "Neos.Setup-20161125014759", + "Neos.SiteKickstarter-20161125095901", + "Neos.Fusion-20161125104701", + "Neos.NodeTypes-20161125104800", + "Neos.Neos-20161125104802", + "Neos.Kickstarter-20161125110814", + "Neos.Neos-20161125122412", + "Neos.Flow-20161125124112", + "Neos.SwiftMailer-20161130105617", + "TYPO3.FluidAdaptor-20161130112935", + "Neos.Fusion-20161201202543", + "Neos.Neos-20161201222211", + "Neos.Fusion-20161202215034", + "Neos.ContentRepository.Search-20161210231100", + "Neos.Fusion-20161219092345", + "Neos.ContentRepository-20161219093512", + "Neos.Media-20161219094126", + "Neos.Neos-20161219094403", + "Neos.Neos-20161219122512", + "Neos.Fusion-20161219130100", + "Neos.Neos-20161220163741", + "Neos.Neos-20170115114620", + "Neos.Fusion-20170120013047", + "Neos.Flow-20170125103800", + "Neos.Seo-20170127154600", + "Neos.Flow-20170127183102" + ] } -} \ No newline at end of file +}