diff --git a/.github/workflows/run-test.yml b/.github/workflows/run-test.yml index 96cc206..9017ed1 100644 --- a/.github/workflows/run-test.yml +++ b/.github/workflows/run-test.yml @@ -19,7 +19,7 @@ jobs: runs-on: ubuntu-latest strategy: matrix: - php-version: ['8.1', '8.2', '8.3'] + php-version: ['8.2', '8.3'] steps: - uses: shivammathur/setup-php@v2 with: @@ -35,8 +35,6 @@ jobs: ${{ runner.os }}-php-${{ matrix.php-version }}- - name: Install Dependencies run: composer install --no-scripts --no-ansi --no-interaction --no-progress - - name: Run PHP Code Sniffer - run: vendor/bin/phpcs --extensions=php --warning-severity=0 --standard=PSR12 -p ./src - name: Run PHPStan run: vendor/bin/phpstan analyse --no-progress -c phpstan.neon - name: Run unit tests diff --git a/composer.json b/composer.json index afb14f9..3c3aba4 100644 --- a/composer.json +++ b/composer.json @@ -12,8 +12,9 @@ } ], "require": { - "php": ">=8.1", + "php": ">=8.2", "ext-json": "*", + "nette/php-generator": "^4.1", "roadiz/nodetype-contracts": "~1.1.2", "symfony/string": "6.4.*", "symfony/yaml": "6.4.*", @@ -34,15 +35,14 @@ } }, "require-dev": { - "squizlabs/php_codesniffer": "^3.5", "phpstan/phpstan": "^1.5.3", "phpunit/phpunit": "^9.5", - "api-platform/core": "~3.2.14" + "api-platform/core": "~3.3.11" }, "extra": { "branch-alias": { - "dev-main": "2.3.x-dev", - "dev-develop": "2.4.x-dev" + "dev-main": "2.4.x-dev", + "dev-develop": "2.5.x-dev" } } } diff --git a/src/Attribute/AttributeGenerator.php b/src/Attribute/AttributeGenerator.php deleted file mode 100644 index 2b6c07d..0000000 --- a/src/Attribute/AttributeGenerator.php +++ /dev/null @@ -1,117 +0,0 @@ - - */ - protected array $parameters; - - /** - * @param string $className - * @param array $parameters - */ - public function __construct(string $className, array $parameters = []) - { - $this->className = $className; - $this->parameters = $parameters; - } - - public static function wrapString(string $string): string - { - return sprintf('"%s"', str_replace('"', '\\"', $string)); - } - - public function generate(int $currentIndentation = 0): string - { - $formattedParams = []; - if (count($this->parameters) > 3) { - foreach ($this->parameters as $name => $parameter) { - if (empty($parameter)) { - continue; - } - $formattedParams[] = $this->formatProperties($name, $parameter, $currentIndentation); - } - return - str_repeat(' ', $currentIndentation) . - $this->className . - sprintf( - '(%s%s%s)', - PHP_EOL, - implode(',' . PHP_EOL, array_filter($formattedParams)), - PHP_EOL . str_repeat(' ', $currentIndentation), - ); - } elseif (count($this->parameters) > 0) { - foreach ($this->parameters as $name => $parameter) { - if (empty($parameter)) { - continue; - } - $formattedParams[] = $this->formatProperties($name, $parameter, -4); - } - return - str_repeat(' ', $currentIndentation) . - $this->className . - sprintf( - '(%s)', - implode(', ', array_filter($formattedParams)) - ); - } else { - return str_repeat(' ', $currentIndentation) . $this->className; - } - } - - /** - * @param string $name - * @param array $parameter - * @param int $currentIndentation - * @return string - * @throws \JsonException - */ - protected function formatArrayObject(string $name, array $parameter, int $currentIndentation = 0): string - { - $encodedParameterContent = []; - foreach ($parameter as $key => $value) { - if (is_string($key)) { - $encodedParameterContent[] = sprintf( - '%s => %s', - self::wrapString($key), - \json_encode($value, \JSON_THROW_ON_ERROR) - ); - } - } - return sprintf( - '%s%s: %s', - str_repeat(' ', $currentIndentation + 4), - $name, - '[' . implode(', ', $encodedParameterContent) . ']' - ); - } - - protected function formatProperties(string|int $name, mixed $parameter, int $currentIndentation = 0): ?string - { - if (empty($parameter)) { - return null; - } - if (is_string($name) && \is_array($parameter)) { - return $this->formatArrayObject($name, $parameter, $currentIndentation); - } - if (is_string($name) && !empty($name)) { - return sprintf( - '%s%s: %s', - str_repeat(' ', $currentIndentation + 4), - $name, - $parameter - ); - } - return sprintf( - '%s%s', - str_repeat(' ', $currentIndentation + 4), - $parameter - ); - } -} diff --git a/src/Attribute/AttributeListGenerator.php b/src/Attribute/AttributeListGenerator.php deleted file mode 100644 index 61198a3..0000000 --- a/src/Attribute/AttributeListGenerator.php +++ /dev/null @@ -1,47 +0,0 @@ - - */ - public array $attributes; - - /** - * @param AttributeGenerator[] $attributes - */ - public function __construct(array $attributes) - { - $this->attributes = $attributes; - } - - public function generate(int $currentIndentation = 0): string - { - if (count($this->attributes) === 0) { - return ''; - } - if (count($this->attributes) === 1) { - return sprintf( - '%s#[%s]', - str_repeat(' ', $currentIndentation), - reset($this->attributes)->generate() - ); - } - - return sprintf( - '%s#[%s%s%s]', - str_repeat(' ', $currentIndentation), - PHP_EOL, - implode(',' . PHP_EOL, array_map(function (AttributeGenerator $attributeGenerator) use ($currentIndentation) { - return $attributeGenerator->generate($currentIndentation + 4); - }, $this->attributes)), - PHP_EOL . str_repeat(' ', $currentIndentation), - ); - } -} diff --git a/src/EntityGenerator.php b/src/EntityGenerator.php index fc4a5e4..b829a42 100644 --- a/src/EntityGenerator.php +++ b/src/EntityGenerator.php @@ -4,11 +4,15 @@ namespace RZ\Roadiz\EntityGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\PhpFile; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Printer; +use Nette\PhpGenerator\PsrPrinter; use RZ\Roadiz\Contracts\NodeType\NodeTypeFieldInterface; use RZ\Roadiz\Contracts\NodeType\NodeTypeInterface; use RZ\Roadiz\Contracts\NodeType\NodeTypeResolverInterface; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; use RZ\Roadiz\EntityGenerator\Field\AbstractFieldGenerator; use RZ\Roadiz\EntityGenerator\Field\CollectionFieldGenerator; use RZ\Roadiz\EntityGenerator\Field\CustomFormsFieldGenerator; @@ -24,26 +28,24 @@ use Symfony\Component\String\UnicodeString; use Symfony\Component\Yaml\Yaml; -class EntityGenerator implements EntityGeneratorInterface +final class EntityGenerator implements EntityGeneratorInterface { - protected NodeTypeInterface $nodeType; - protected NodeTypeResolverInterface $nodeTypeResolver; - protected DefaultValuesResolverInterface $defaultValuesResolver; - protected array $fieldGenerators; - protected array $options; + /** + * @var AbstractFieldGenerator[] + */ + private array $fieldGenerators; + private array $options; + private Printer $printer; public function __construct( - NodeTypeInterface $nodeType, - NodeTypeResolverInterface $nodeTypeResolver, - DefaultValuesResolverInterface $defaultValuesResolver, - array $options = [] + private readonly NodeTypeInterface $nodeType, + private readonly NodeTypeResolverInterface $nodeTypeResolver, + private readonly DefaultValuesResolverInterface $defaultValuesResolver, + array $options = [], ) { $resolver = new OptionsResolver(); $this->configureOptions($resolver); - $this->nodeType = $nodeType; - $this->nodeTypeResolver = $nodeTypeResolver; - $this->defaultValuesResolver = $defaultValuesResolver; $this->fieldGenerators = []; $this->options = $resolver->resolve($options); @@ -51,11 +53,9 @@ public function __construct( $this->fieldGenerators[] = $this->getFieldGenerator($field); } $this->fieldGenerators = array_filter($this->fieldGenerators); + $this->printer = new PsrPrinter(); } - /** - * @param OptionsResolver $resolver - */ public function configureOptions(OptionsResolver $resolver): void { $resolver->setDefaults([ @@ -73,7 +73,7 @@ public function configureOptions(OptionsResolver $resolver): void 'repository_class', 'namespace', 'use_native_json', - 'use_api_platform_filters' + 'use_api_platform_filters', ]); $resolver->setAllowedTypes('parent_class', 'string'); $resolver->setAllowedTypes('node_class', 'string'); @@ -90,7 +90,7 @@ public function configureOptions(OptionsResolver $resolver): void $normalizeClassName = function (OptionsResolver $resolver, string $className) { return (new UnicodeString($className))->startsWith('\\') ? $className : - '\\' . $className; + '\\'.$className; }; $resolver->setNormalizer('parent_class', $normalizeClassName); @@ -104,11 +104,7 @@ public function configureOptions(OptionsResolver $resolver): void $resolver->setNormalizer('namespace', $normalizeClassName); } - /** - * @param NodeTypeFieldInterface $field - * @return AbstractFieldGenerator|null - */ - protected function getFieldGenerator(NodeTypeFieldInterface $field): ?AbstractFieldGenerator + private function getFieldGenerator(NodeTypeFieldInterface $field): ?AbstractFieldGenerator { if ($field->isYaml()) { return new YamlFieldGenerator($field, $this->defaultValuesResolver, $this->options); @@ -128,9 +124,9 @@ protected function getFieldGenerator(NodeTypeFieldInterface $field): ?AbstractFi if ($field->isManyToMany()) { $configuration = Yaml::parse($field->getDefaultValues() ?? ''); if ( - is_array($configuration) && - isset($configuration['proxy']) && - !empty($configuration['proxy']['classname']) + is_array($configuration) + && isset($configuration['proxy']) + && !empty($configuration['proxy']['classname']) ) { /* * Manually create a Many-to-Many relation using a proxy class @@ -138,10 +134,11 @@ protected function getFieldGenerator(NodeTypeFieldInterface $field): ?AbstractFi */ return new ProxiedManyToManyFieldGenerator($field, $this->defaultValuesResolver, $this->options); } + return new ManyToManyFieldGenerator($field, $this->defaultValuesResolver, $this->options); } if ($field->isNodes()) { - return new NodesFieldGenerator($field, $this->nodeTypeResolver, $this->defaultValuesResolver, $this->options); + return new NodesFieldGenerator($this->nodeTypeResolver, $field, $this->defaultValuesResolver, $this->options); } if (!$field->isVirtual()) { return new NonVirtualFieldGenerator($field, $this->defaultValuesResolver, $this->options); @@ -150,134 +147,87 @@ protected function getFieldGenerator(NodeTypeFieldInterface $field): ?AbstractFi return null; } - /** - * @return string - */ public function getClassContent(): string { - return $this->getClassHeader() . - $this->getClassAnnotations() . - $this->getClassAttributes() . - $this->getClassBody(); - } - - /** - * @return string - */ - protected function getClassBody(): string - { - return 'class ' . $this->nodeType->getSourceEntityClassName() . ' extends ' . $this->options['parent_class'] . ' -{' . $this->getClassProperties() . - $this->getClassConstructor() . - $this->getNodeTypeNameGetter() . - $this->getNodeTypeReachableGetter() . - $this->getNodeTypePublishableGetter() . - $this->getClassCloneMethod() . - $this->getClassMethods() . ' -}' . PHP_EOL; - } - - /** - * @return string - */ - protected function getClassHeader(): string - { - $useStatements = [ - 'use Doctrine\Common\Collections\Collection;', - 'use JMS\Serializer\Annotation as Serializer;', - 'use Symfony\Component\Serializer\Annotation as SymfonySerializer;', - 'use Gedmo\Mapping\Annotation as Gedmo;', - 'use Doctrine\ORM\Mapping as ORM;', - ]; - - if ($this->options['use_api_platform_filters'] === true) { - $useStatements[] = 'use ApiPlatform\Metadata\ApiFilter;'; - $useStatements[] = 'use ApiPlatform\Doctrine\Orm\Filter as OrmFilter;'; - $useStatements[] = 'use ApiPlatform\Serializer\Filter\PropertyFilter;'; - } - /* - * BE CAREFUL, USE statements are required for field generators which - * are using ::class syntax! - */ - return 'options['namespace'], '\\') . '; - -' . implode(PHP_EOL, $useStatements) . PHP_EOL; + $file = new PhpFile(); + $file->setStrictTypes(); + $file->addComment('THIS IS A GENERATED FILE, DO NOT EDIT IT.'); + $file->addComment('IT WILL BE RECREATED AT EACH NODE-TYPE UPDATE.'); + + $namespace = $file + ->addNamespace(trim($this->options['namespace'], '\\')) + ->addUse('ApiPlatform\Metadata\ApiFilter') + ->addUse('ApiPlatform\Metadata\ApiProperty') + ->addUse('ApiPlatform\Serializer\Filter\PropertyFilter') + ->addUse('ApiPlatform\Doctrine\Orm\Filter', 'Filter') + ->addUse('Doctrine\Common\Collections\Collection') + ->addUse($this->options['parent_class']) + ->addUse('Doctrine\ORM\Mapping', 'ORM') + ->addUse('Gedmo\Mapping\Annotation', 'Gedmo') + ->addUse('JMS\Serializer\Annotation', 'JMS') + ->addUse('RZ\Roadiz\CoreBundle\Entity\Node') + ->addUse('RZ\Roadiz\CoreBundle\Entity\Translation') + ->addUse('RZ\Roadiz\CoreBundle\Entity\UserLogEntry') + ->addUse('Symfony\Component\Serializer\Attribute', 'Serializer') + ; + + $classType = $namespace->addClass($this->nodeType->getSourceEntityClassName()) + ->setExtends($this->options['parent_class']) + ->addComment($this->nodeType->getName().' node-source entity.') + ->addComment($this->nodeType->getDescription() ?? ''); + + $this + ->addClassAttributes($classType, $namespace) + ->addClassFields($classType, $namespace) + ->addClassConstructor($classType) + ->addClassCloneMethod($classType) + ->addClassMethods($classType) + ; + + return $this->printer->printFile($file); } - protected function getClassAttributes(): string + private function addClassAttributes(ClassType $classType, PhpNamespace $namespace): self { - $attributeGenerators = [ - new AttributeGenerator('Gedmo\Loggable', [ - 'logEntryClass' => '\RZ\Roadiz\CoreBundle\Entity\UserLogEntry::class', - ]), - new AttributeGenerator('ORM\Entity', [ - 'repositoryClass' => $this->options['repository_class'] . '::class', - ]), - new AttributeGenerator('ORM\Table', [ - 'name' => AttributeGenerator::wrapString($this->nodeType->getSourceEntityTableName()) - ]) - ]; + $classType + ->addAttribute( + 'Gedmo\Mapping\Annotation\Loggable', + ['logEntryClass' => new Literal('UserLogEntry::class')] + ) + ->addAttribute( + 'Doctrine\ORM\Mapping\Entity', + ['repositoryClass' => new Literal($namespace->simplifyName($this->options['repository_class']).'::class')] + ) + ->addAttribute( + 'Doctrine\ORM\Mapping\Table', + ['name' => $this->nodeType->getSourceEntityTableName()] + ) + ; - $indexes = []; - /** @var AbstractFieldGenerator $fieldGenerator */ foreach ($this->fieldGenerators as $fieldGenerator) { - $indexes[] = $fieldGenerator->getFieldIndex(); + $fieldGenerator->addFieldIndex($classType); } - $attributeGenerators = [...$attributeGenerators, ...array_filter($indexes)]; - if ($this->options['use_api_platform_filters'] === true) { - $attributeGenerators[] = new AttributeGenerator('ApiFilter', [ - 'PropertyFilter::class' - ]); + if (true === $this->options['use_api_platform_filters']) { + $classType->addAttribute( + 'ApiPlatform\Metadata\ApiFilter', + [new Literal($namespace->simplifyName('\ApiPlatform\Serializer\Filter\PropertyFilter').'::class')] + ); } - return (new AttributeListGenerator($attributeGenerators))->generate() . PHP_EOL; - } - - /** - * @return string - */ - protected function getClassAnnotations(): string - { - $annotations = [ - $this->nodeType->getName() . ' node-source entity.', - $this->nodeType->getDescription() - ]; - $annotations = array_filter($annotations); - - return ' -/** - * ' . implode(PHP_EOL . ' * ', $annotations) . ' - */' . PHP_EOL; + return $this; } - /** - * @return string - */ - protected function getClassProperties(): string + private function addClassFields(ClassType $classType, PhpNamespace $namespace): self { - $fieldsArray = []; - /** @var AbstractFieldGenerator $fieldGenerator */ foreach ($this->fieldGenerators as $fieldGenerator) { - $fieldsArray[] = $fieldGenerator->getField(); + $fieldGenerator->addField($classType, $namespace); } - $fieldsArray = array_filter($fieldsArray); - return implode('', $fieldsArray); + return $this; } - /** - * @return string - */ - protected function getClassCloneMethod(): string + private function addClassCloneMethod(ClassType $classType): self { $cloneStatements = []; /** @var AbstractFieldGenerator $fieldGenerator */ @@ -286,109 +236,83 @@ protected function getClassCloneMethod(): string } $cloneStatements = array_filter($cloneStatements); - if (count($cloneStatements) === 0) { - return ''; + if (0 === count($cloneStatements)) { + return $this; } - $statementSeparator = PHP_EOL . PHP_EOL . AbstractFieldGenerator::TAB . AbstractFieldGenerator::TAB; - $cloneStatementsString = implode($statementSeparator, $cloneStatements); + $method = $classType + ->addMethod('__clone') + ->setReturnType('void') + ; - return ' - public function __clone() - { - parent::__clone(); + $method->addBody('parent::__clone();'); + + foreach ($cloneStatements as $cloneStatement) { + $method->addBody(''); + $method->addBody($cloneStatement); + } - ' . $cloneStatementsString . ' - }' . PHP_EOL; + return $this; } - /** - * @return string - */ - protected function getClassConstructor(): string + private function addClassConstructor(ClassType $classType): self { - $constructorArray = []; - /** @var AbstractFieldGenerator $fieldGenerator */ + $constructorStatements = []; foreach ($this->fieldGenerators as $fieldGenerator) { - $constructorArray[] = $fieldGenerator->getFieldConstructorInitialization(); + $constructorStatements[] = $fieldGenerator->getFieldConstructorInitialization(); } - $constructorArray = array_filter($constructorArray); - - if (count($constructorArray) > 0) { - return ' - public function __construct(' . $this->options['node_class'] . ' $node, ' . $this->options['translation_class'] . ' $translation) - { - parent::__construct($node, $translation); - - ' . implode(PHP_EOL . AbstractFieldGenerator::TAB . AbstractFieldGenerator::TAB, $constructorArray) . ' - }' . PHP_EOL; + $constructorStatements = array_filter($constructorStatements); + + if (count($constructorStatements) > 0) { + $constructorMethod = $classType->addMethod('__construct'); + $constructorMethod->addParameter('node') + ->setType($this->options['node_class']); + $constructorMethod->addParameter('translation') + ->setType($this->options['translation_class']); + $constructorMethod->addBody('parent::__construct($node, $translation);'); + foreach ($constructorStatements as $constructorStatement) { + $constructorMethod->addBody($constructorStatement); + } } - return ''; - } - - /** - * @return string - */ - protected function getNodeTypeNameGetter(): string - { - return ' - #[ - Serializer\VirtualProperty, - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\SerializedName("@type"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\SerializedName(serializedName: "@type") - ] - public function getNodeTypeName(): string - { - return \'' . $this->nodeType->getName() . '\'; - }' . PHP_EOL; - } - - /** - * @return string - */ - protected function getNodeTypeReachableGetter(): string - { - return ' - /** - * $this->nodeType->isReachable() proxy. - * - * @return bool Does this nodeSource is reachable over network? - */ - public function isReachable(): bool - { - return ' . ($this->nodeType->isReachable() ? 'true' : 'false') . '; - }' . PHP_EOL; - } - - /** - * @return string - */ - protected function getNodeTypePublishableGetter(): string - { - return ' - /** - * $this->nodeType->isPublishable() proxy. - * - * @return bool Does this nodeSource is publishable with date and time? - */ - public function isPublishable(): bool - { - return ' . ($this->nodeType->isPublishable() ? 'true' : 'false') . '; - }' . PHP_EOL; + return $this; } - /** - * @return string - */ - protected function getClassMethods(): string + private function addClassMethods(ClassType $classType): self { - return ' - public function __toString(): string - { - return \'[' . $this->nodeType->getSourceEntityClassName() . '] \' . parent::__toString(); - }'; + $classType->addMethod('getNodeTypeName') + ->setReturnType('string') + ->addAttribute('JMS\Serializer\Annotation\VirtualProperty') + ->addAttribute('JMS\Serializer\Annotation\Groups', [['nodes_sources', 'nodes_sources_default']]) + ->addAttribute('JMS\Serializer\Annotation\SerializedName', ['@type']) + ->addAttribute('Symfony\Component\Serializer\Attribute\Groups', [['nodes_sources', 'nodes_sources_default']]) + ->addAttribute('Symfony\Component\Serializer\Attribute\SerializedName', [ + 'serializedName' => '@type', + ]) + ->setBody('return \''.$this->nodeType->getName().'\';') + ; + + $classType->addMethod('isReachable') + ->addComment('$this->nodeType->isReachable() proxy.') + ->addComment('@return bool Does this nodeSource is reachable over network?') + ->setReturnType('bool') + ->addAttribute('JMS\Serializer\Annotation\VirtualProperty') + ->setBody('return '.($this->nodeType->isReachable() ? 'true' : 'false').';') + ; + + $classType->addMethod('isPublishable') + ->addComment('$this->nodeType->isPublishable() proxy.') + ->addComment('@return bool Does this nodeSource is publishable with date and time?') + ->setReturnType('bool') + ->addAttribute('JMS\Serializer\Annotation\VirtualProperty') + ->setBody('return '.($this->nodeType->isPublishable() ? 'true' : 'false').';') + ; + + $classType->addMethod('__toString') + ->setReturnType('string') + ->setBody('return \'['.$this->nodeType->getSourceEntityClassName().'] \' . parent::__toString();') + ; + + return $this; } } diff --git a/src/EntityGeneratorFactory.php b/src/EntityGeneratorFactory.php index 201b906..a5be093 100644 --- a/src/EntityGeneratorFactory.php +++ b/src/EntityGeneratorFactory.php @@ -8,12 +8,12 @@ use RZ\Roadiz\Contracts\NodeType\NodeTypeResolverInterface; use RZ\Roadiz\EntityGenerator\Field\DefaultValuesResolverInterface; -final class EntityGeneratorFactory +final readonly class EntityGeneratorFactory { public function __construct( - private readonly NodeTypeResolverInterface $nodeTypeResolverBag, - private readonly DefaultValuesResolverInterface $defaultValuesResolver, - private readonly array $options + private NodeTypeResolverInterface $nodeTypeResolverBag, + private DefaultValuesResolverInterface $defaultValuesResolver, + private array $options, ) { } @@ -26,9 +26,9 @@ public function createWithCustomRepository(NodeTypeInterface $nodeType): EntityG { $options = $this->options; $options['repository_class'] = - $options['namespace'] . - '\\Repository\\' . - $nodeType->getSourceEntityClassName() . 'Repository'; + $options['namespace']. + '\\Repository\\'. + $nodeType->getSourceEntityClassName().'Repository'; return new EntityGenerator($nodeType, $this->nodeTypeResolverBag, $this->defaultValuesResolver, $options); } @@ -39,8 +39,8 @@ public function createCustomRepository(NodeTypeInterface $nodeType): RepositoryG 'entity_namespace' => $this->options['namespace'], 'parent_class' => 'RZ\Roadiz\CoreBundle\Repository\NodesSourcesRepository', ]; - $options['namespace'] = $this->options['namespace'] . '\\Repository'; - $options['class_name'] = $nodeType->getSourceEntityClassName() . 'Repository'; + $options['namespace'] = $this->options['namespace'].'\\Repository'; + $options['class_name'] = $nodeType->getSourceEntityClassName().'Repository'; return new RepositoryGenerator($nodeType, $options); } diff --git a/src/Field/AbstractConfigurableFieldGenerator.php b/src/Field/AbstractConfigurableFieldGenerator.php index 12b20d2..032ce88 100644 --- a/src/Field/AbstractConfigurableFieldGenerator.php +++ b/src/Field/AbstractConfigurableFieldGenerator.php @@ -14,27 +14,25 @@ abstract class AbstractConfigurableFieldGenerator extends AbstractFieldGenerator public function __construct( NodeTypeFieldInterface $field, DefaultValuesResolverInterface $defaultValuesResolver, - array $options = [] + array $options = [], ) { parent::__construct($field, $defaultValuesResolver, $options); if (empty($this->field->getDefaultValues())) { - throw new \LogicException('Default values must be a valid YAML for ' . static::class); + throw new \LogicException('Default values must be a valid YAML for '.static::class); } $conf = Yaml::parse($this->field->getDefaultValues()); if (!is_array($conf)) { - throw new \LogicException('YAML for ' . static::class . ' must be an associative array'); + throw new \LogicException('YAML for '.static::class.' must be an associative array'); } $this->configuration = $conf; } /** * Ensure configured classname has a starting backslash. - * - * @return string */ protected function getFullyQualifiedClassName(): string { - return '\\' . trim($this->configuration['classname'], '\\'); + return '\\'.trim($this->configuration['classname'], '\\'); } } diff --git a/src/Field/AbstractFieldGenerator.php b/src/Field/AbstractFieldGenerator.php index e0497db..c27d46b 100644 --- a/src/Field/AbstractFieldGenerator.php +++ b/src/Field/AbstractFieldGenerator.php @@ -4,112 +4,74 @@ namespace RZ\Roadiz\EntityGenerator\Field; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; use RZ\Roadiz\Contracts\NodeType\NodeTypeFieldInterface; use RZ\Roadiz\Contracts\NodeType\SerializableInterface; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; use Symfony\Component\String\UnicodeString; abstract class AbstractFieldGenerator { - public const TAB = ' '; - public const ANNOTATION_PREFIX = AbstractFieldGenerator::TAB . ' *'; - - protected NodeTypeFieldInterface $field; - protected DefaultValuesResolverInterface $defaultValuesResolver; - protected array $options; - public function __construct( - NodeTypeFieldInterface $field, - DefaultValuesResolverInterface $defaultValuesResolver, - array $options = [] + protected readonly NodeTypeFieldInterface $field, + protected readonly DefaultValuesResolverInterface $defaultValuesResolver, + protected array $options = [], ) { - $this->field = $field; - $this->defaultValuesResolver = $defaultValuesResolver; - $this->options = $options; } /** * Generate PHP code for current doctrine field. - * - * @return string */ - public function getField(): string + public function addField(ClassType $classType, PhpNamespace $namespace): void { - return $this->getFieldAnnotation() . - (new AttributeListGenerator( - $this->getFieldAttributes($this->isExcludingFieldFromJmsSerialization()) - ) - )->generate(4) . PHP_EOL . - $this->getFieldDeclaration() . - $this->getFieldGetter() . - $this->getFieldAlternativeGetter() . - $this->getFieldSetter() . PHP_EOL; + $property = $this->getFieldProperty($classType); + + $this + ->addFieldAnnotation($property) + ->addFieldAttributes($property, $namespace, $this->isExcludingFieldFromJmsSerialization()) + ->addFieldGetter($classType, $namespace) + ->addFieldAlternativeGetter($classType) + ->addFieldSetter($classType) + ; } - /** - * @return array - */ - protected function getFieldAutodoc(): array + protected function getFieldProperty(ClassType $classType): Property { - $docs = [ - $this->field->getLabel() . '.', - ]; + return $classType + ->addProperty($this->field->getVarName()) + ->setPrivate() + ->setType($this->getFieldTypeDeclaration()) + ->setValue($this->getFieldDefaultValueDeclaration()); + } + + protected function addFieldAutodoc(Property $property): self + { + $property->addComment($this->field->getLabel().'.'); + if (!empty($this->field->getDescription())) { - $docs[] = $this->field->getDescription() . '.'; + $property->addComment($this->field->getDescription().'.'); } if (!empty($this->field->getDefaultValues())) { - $docs[] = 'Default values: ' . preg_replace( - "#(?:\\r\\n|\\n)#", - PHP_EOL . " * ", - $this->field->getDefaultValues() - ); + $property->addComment('Default values:'); + $property->addComment($this->field->getDefaultValues()); } if (!empty($this->field->getGroupName())) { - $docs[] = 'Group: ' . $this->field->getGroupName() . '.'; + $property->addComment('Group: '.$this->field->getGroupName().'.'); } - return array_map(function ($line) { - return (!empty(trim($line))) ? (' ' . $line) : ($line); - }, $docs); + return $this; } - /** - * @return string - */ - protected function getFieldAnnotation(): string + protected function addFieldAnnotation(Property $property): self { - $autodoc = ''; - $fieldAutoDoc = $this->getFieldAutodoc(); - if (!empty($fieldAutoDoc)) { - $autodoc = PHP_EOL . - static::ANNOTATION_PREFIX . - implode(PHP_EOL . static::ANNOTATION_PREFIX, $fieldAutoDoc); - } - return ' - /**' . $autodoc . ' - * - * (Virtual field, this var is a buffer) - */' . PHP_EOL; - } + $this->addFieldAutodoc($property); - /** - * Generate PHP property declaration block. - */ - protected function getFieldDeclaration(): string - { - $type = $this->getFieldTypeDeclaration(); - if (!empty($type)) { - $type .= ' '; - } - $defaultValue = $this->getFieldDefaultValueDeclaration(); - if (!empty($defaultValue)) { - $defaultValue = ' = ' . $defaultValue; - } - /* - * Buffer var to get referenced entities (documents, nodes, custom-forms, doctrine entities) - */ - return static::TAB . 'private ' . $type . '$' . $this->field->getVarName() . $defaultValue . ';' . PHP_EOL; + $property->addComment('(Virtual field, this var is a buffer)'); + + return $this; } protected function getFieldTypeDeclaration(): string @@ -120,159 +82,146 @@ protected function getFieldTypeDeclaration(): string protected function toPhpDocType(string $typeHint): string { $unicode = new UnicodeString($typeHint); + return $unicode->startsWith('?') ? $unicode->trimStart('?')->append('|null')->toString() : $typeHint; } - protected function getFieldDefaultValueDeclaration(): string + protected function getFieldDefaultValueDeclaration(): Literal|string|null { - return ''; + return null; } - /** - * @return array - */ - protected function getFieldAttributes(bool $exclude = false): array + protected function addFieldAttributes(Property $property, PhpNamespace $namespace, bool $exclude = false): self { - $attributes = []; - if ($exclude) { - $attributes[] = new AttributeGenerator('Serializer\Exclude'); + $property->addAttribute('JMS\Serializer\Annotation\Exclude'); } /* * Symfony serializer is using getter / setter by default */ if (!$this->excludeFromSerialization()) { - $attributes[] = new AttributeGenerator('SymfonySerializer\SerializedName', [ - 'serializedName' => AttributeGenerator::wrapString($this->field->getVarName()) + $property->addAttribute('Symfony\Component\Serializer\Attribute\SerializedName', [ + 'serializedName' => $this->field->getVarName(), ]); - $attributes[] = new AttributeGenerator('SymfonySerializer\Groups', [ - $this->getSerializationGroups() + $property->addAttribute('Symfony\Component\Serializer\Attribute\Groups', [ + $this->getSerializationGroups(), ]); $description = $this->field->getLabel(); if (!empty($this->field->getDescription())) { - $description .= ': ' . $this->field->getDescription(); + $description .= ': '.$this->field->getDescription(); } if ($this->field->isEnum() && null !== $defaultValues = $this->field->getDefaultValues()) { $enumValues = explode(',', $defaultValues); $enumValues = array_filter(array_map('trim', $enumValues)); - $openapiContext = [ + $openapiContext = array_filter([ 'type' => 'string', 'enum' => $enumValues, 'example' => $enumValues[0] ?? null, - ]; + ]); } - $attributes[] = new AttributeGenerator('\ApiPlatform\Metadata\ApiProperty', [ - 'description' => AttributeGenerator::wrapString($description), + + $property->addAttribute('ApiPlatform\Metadata\ApiProperty', array_filter([ + 'description' => $description, + 'example' => $this->field->getPlaceholder(), 'schema' => $openapiContext ?? null, - 'example' => $this->field->getPlaceholder() ? - AttributeGenerator::wrapString($this->field->getPlaceholder()) : - null, - ]); + ])); + if ($this->getSerializationMaxDepth() > 0) { - $attributes[] = new AttributeGenerator('SymfonySerializer\MaxDepth', [ - $this->getSerializationMaxDepth() + $property->addAttribute('Symfony\Component\Serializer\Attribute\MaxDepth', [ + $this->getSerializationMaxDepth(), ]); } } if ( - $this->field->isIndexed() && - $this->options['use_api_platform_filters'] === true + $this->field->isIndexed() + && true === $this->options['use_api_platform_filters'] ) { switch (true) { case $this->field->isString(): - $attributes[] = new AttributeGenerator('ApiFilter', [ - 0 => 'OrmFilter\SearchFilter::class', - 'strategy' => AttributeGenerator::wrapString('partial') + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + 0 => new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\SearchFilter').'::class'), + 'strategy' => 'partial', ]); - $attributes[] = new AttributeGenerator('ApiFilter', [ - 0 => '\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class' + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter').'::class'), ]); break; case $this->field->isMultiple(): case $this->field->isEnum(): - $attributes[] = new AttributeGenerator('ApiFilter', [ - 0 => 'OrmFilter\SearchFilter::class', - 'strategy' => AttributeGenerator::wrapString('exact') + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + 0 => new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\SearchFilter').'::class'), + 'strategy' => 'exact', ]); - $attributes[] = new AttributeGenerator('ApiFilter', [ - 0 => '\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class' + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter').'::class'), ]); break; case $this->field->isBool(): - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\OrderFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\OrderFilter').'::class'), ]); - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\BooleanFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\BooleanFilter').'::class'), ]); break; case $this->field->isManyToOne(): case $this->field->isManyToMany(): - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\ExistsFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\ExistsFilter').'::class'), ]); break; case $this->field->isInteger(): case $this->field->isDecimal(): - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\OrderFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\OrderFilter').'::class'), ]); - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\NumericFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\NumericFilter').'::class'), ]); - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\RangeFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\RangeFilter').'::class'), ]); break; case $this->field->isDate(): case $this->field->isDateTime(): - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\OrderFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\OrderFilter').'::class'), ]); - $attributes[] = new AttributeGenerator('ApiFilter', [ - 'OrmFilter\DateFilter::class', + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\DateFilter').'::class'), ]); break; } } - return $attributes; + return $this; } /** * Generate PHP alternative getter method block. - * - * @return string */ - abstract protected function getFieldGetter(): string; + abstract protected function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self; /** * Generate PHP alternative getter method block. - * - * @return string */ - protected function getFieldAlternativeGetter(): string + protected function addFieldAlternativeGetter(ClassType $classType): self { - return ''; + return $this; } /** * Generate PHP setter method block. - * - * @return string */ - protected function getFieldSetter(): string + protected function addFieldSetter(ClassType $classType): self { - return ''; + return $this; } - /** - * @return string - */ public function getCloneStatements(): string { return ''; @@ -280,40 +229,34 @@ public function getCloneStatements(): string /** * Generate PHP annotation block for Doctrine table indexes. - * - * @return AttributeGenerator|null */ - public function getFieldIndex(): ?AttributeGenerator + public function addFieldIndex(ClassType $classType): self { - return null; + return $this; } /** * Generate PHP property initialization for class constructor. - * - * @return string */ public function getFieldConstructorInitialization(): string { return ''; } - /** - * @return bool - */ protected function excludeFromSerialization(): bool { if ($this->field instanceof SerializableInterface) { return $this->field->isExcludedFromSerialization(); } + return false; } protected function getSerializationExclusionExpression(): ?string { if ( - $this->field instanceof SerializableInterface && - null !== $this->field->getSerializationExclusionExpression() + $this->field instanceof SerializableInterface + && null !== $this->field->getSerializationExclusionExpression() ) { return (new UnicodeString($this->field->getSerializationExclusionExpression())) ->replace('"', '') @@ -321,6 +264,7 @@ protected function getSerializationExclusionExpression(): ?string ->trim() ->toString(); } + return null; } @@ -329,6 +273,7 @@ protected function getSerializationMaxDepth(): int if ($this->field instanceof SerializableInterface && $this->field->getSerializationMaxDepth() > 0) { return $this->field->getSerializationMaxDepth(); } + return 2; } @@ -336,66 +281,64 @@ protected function getDefaultSerializationGroups(): array { return [ 'nodes_sources', - 'nodes_sources_' . ($this->field->getGroupNameCanonical() ?: 'default') + 'nodes_sources_'.($this->field->getGroupNameCanonical() ?: 'default'), ]; } - protected function getSerializationGroups(): string + protected function getSerializationGroups(): array { if ($this->field instanceof SerializableInterface && !empty($this->field->getSerializationGroups())) { $groups = $this->field->getSerializationGroups(); } else { $groups = $this->getDefaultSerializationGroups(); } - return '[' . implode(', ', array_map(function (string $group) { - return '"' . (new UnicodeString($group)) + + return array_map(function (string $group): string { + return (new UnicodeString($group)) ->replaceMatches('/[^A-Za-z0-9]++/', '_') - ->trim('_')->toString() . '"'; - }, $groups)) . ']'; + ->trim('_')->toString(); + }, $groups); } - /** - * @return AttributeGenerator[] - */ - protected function getSerializationAttributes(): array + protected function addSerializationAttributes(Property|Method $property): self { if ($this->excludeFromSerialization()) { - return [ - new AttributeGenerator('Serializer\Exclude'), - new AttributeGenerator('SymfonySerializer\Ignore'), - ]; + $property->addAttribute('JMS\Serializer\Annotation\Exclude'); + $property->addAttribute('Symfony\Component\Serializer\Attribute\Ignore'); + + return $this; } - $attributes = []; - $attributes[] = new AttributeGenerator('Serializer\Groups', [ - $this->getSerializationGroups() + + $property->addAttribute('JMS\Serializer\Annotation\Groups', [ + $this->getSerializationGroups(), ]); if ($this->getSerializationMaxDepth() > 0) { - $attributes[] = new AttributeGenerator('Serializer\MaxDepth', [ - $this->getSerializationMaxDepth() + $property->addAttribute('JMS\Serializer\Annotation\MaxDepth', [ + $this->getSerializationMaxDepth(), ]); } if (null !== $this->getSerializationExclusionExpression()) { - $attributes[] = new AttributeGenerator('Serializer\Exclude', [ - 'if' => AttributeGenerator::wrapString($this->getSerializationExclusionExpression()) + $property->addAttribute('JMS\Serializer\Annotation\Exclude', [ + 'if' => $this->getSerializationExclusionExpression(), ]); } switch (true) { case $this->field->isBool(): - $attributes[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString('bool') + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'bool', ]); break; case $this->field->isInteger(): - $attributes[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString('int') + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'int', ]); break; case $this->field->isDecimal(): - $attributes[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString('double') + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'double', ]); break; case $this->field->isColor(): @@ -406,19 +349,29 @@ protected function getSerializationAttributes(): array case $this->field->isText(): case $this->field->isRichText(): case $this->field->isEnum(): - $attributes[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString('string') + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'string', ]); break; case $this->field->isDateTime(): case $this->field->isDate(): - $attributes[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString('DateTime') + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'DateTime', ]); break; } - return $attributes; + return $this; + } + + protected function hasFieldAlternativeGetter(): bool + { + return false; + } + + protected function hasSerializationAttributes(): bool + { + return true; } protected function isExcludingFieldFromJmsSerialization(): bool diff --git a/src/Field/CollectionFieldGenerator.php b/src/Field/CollectionFieldGenerator.php index ae82fe3..c075b31 100644 --- a/src/Field/CollectionFieldGenerator.php +++ b/src/Field/CollectionFieldGenerator.php @@ -4,6 +4,6 @@ namespace RZ\Roadiz\EntityGenerator\Field; -class CollectionFieldGenerator extends NonVirtualFieldGenerator +final class CollectionFieldGenerator extends NonVirtualFieldGenerator { } diff --git a/src/Field/CustomFormsFieldGenerator.php b/src/Field/CustomFormsFieldGenerator.php index 6adc91d..31e2977 100644 --- a/src/Field/CustomFormsFieldGenerator.php +++ b/src/Field/CustomFormsFieldGenerator.php @@ -4,26 +4,30 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; -class CustomFormsFieldGenerator extends AbstractFieldGenerator +final class CustomFormsFieldGenerator extends AbstractFieldGenerator { - protected function getSerializationAttributes(): array + protected function addSerializationAttributes(Property|Method $property): self { - $attributes = parent::getSerializationAttributes(); - $attributes[] = new AttributeGenerator('Serializer\VirtualProperty'); - $attributes[] = new AttributeGenerator('Serializer\SerializedName', [ - AttributeGenerator::wrapString($this->field->getVarName()) + parent::addSerializationAttributes($property); + $property->addAttribute('JMS\Serializer\Annotation\VirtualProperty'); + $property->addAttribute('JMS\Serializer\Annotation\SerializedName', [ + $this->field->getVarName(), ]); - return $attributes; + return $this; } protected function getDefaultSerializationGroups(): array { $groups = parent::getDefaultSerializationGroups(); $groups[] = 'nodes_sources_custom_forms'; + return $groups; } @@ -32,65 +36,65 @@ protected function getFieldTypeDeclaration(): string return '?array'; } - protected function getFieldDefaultValueDeclaration(): string + protected function getFieldDefaultValueDeclaration(): Literal|string|null { - return 'null'; + return new Literal('null'); } - /** - * @inheritDoc - */ - public function getFieldGetter(): string + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self { - return ' - /** - * @return ' . $this->options['custom_form_class'] . '[] CustomForm array - */ -' . (new AttributeListGenerator($this->getSerializationAttributes()))->generate(4) . ' - public function ' . $this->field->getGetterName() . '(): array - { - if (null === $this->' . $this->field->getVarName() . ') { - if (null !== $this->objectManager) { - $this->' . $this->field->getVarName() . ' = $this->objectManager - ->getRepository(' . $this->options['custom_form_class'] . '::class) - ->findByNodeAndFieldName( - $this->getNode(), - \'' . $this->field->getName() . '\' - ); - } else { - $this->' . $this->field->getVarName() . ' = []; - } - } - return $this->' . $this->field->getVarName() . '; - }' . PHP_EOL; + $method = $classType + ->addMethod($this->field->getGetterName()) + ->setReturnType('array') + ->setVisibility('public') + ->addComment('@return '.$this->options['custom_form_class'].'[] CustomForm array') + ; + $this->addSerializationAttributes($method); + + $method->setBody(<<{$this->field->getVarName()}) { + if (null !== \$this->objectManager) { + \$this->{$this->field->getVarName()} = \$this->objectManager + ->getRepository({$namespace->simplifyName($this->options['custom_form_class'])}::class) + ->findByNodeAndFieldName( + \$this->getNode(), + '{$this->field->getName()}' + ); + } else { + \$this->{$this->field->getVarName()} = []; } +} +return \$this->{$this->field->getVarName()}; +EOF + ); - /** - * Generate PHP setter method block. - * - * @return string - */ - protected function getFieldSetter(): string - { - return ' - /** - * @param ' . $this->options['custom_form_class'] . ' $customForm - * - * @return $this - */ - public function add' . ucfirst($this->field->getVarName()) . '(' . $this->options['custom_form_class'] . ' $customForm): static + return $this; + } + + protected function addFieldSetter(ClassType $classType): self { - if (null !== $this->objectManager) { - $nodeCustomForm = new ' . $this->options['custom_form_proxy_class'] . '( - $this->getNode(), - $customForm - ); - $nodeCustomForm->setFieldName(\'' . $this->field->getName() . '\'); - $this->objectManager->persist($nodeCustomForm); - $this->getNode()->addCustomForm($nodeCustomForm); - $this->' . $this->field->getVarName() . ' = null; - } + $method = $classType + ->addMethod('add'.ucfirst($this->field->getVarName())) + ->setReturnType('static') + ->setVisibility('public') + ->addComment('@return $this') + ; + $method->addParameter('customForm')->setType($this->options['custom_form_class']); + $method->setBody(<<objectManager) { + \$nodeCustomForm = new {$this->options['custom_form_proxy_class']}( + \$this->getNode(), + \$customForm + ); + \$nodeCustomForm->setFieldName('{$this->field->getName()}'); + \$this->objectManager->persist(\$nodeCustomForm); + \$this->getNode()->addCustomForm(\$nodeCustomForm); + \$this->{$this->field->getVarName()} = null; +} +return \$this; +EOF + ); + return $this; - }' . PHP_EOL; } } diff --git a/src/Field/DefaultValuesResolverInterface.php b/src/Field/DefaultValuesResolverInterface.php index 5ec8918..a840135 100644 --- a/src/Field/DefaultValuesResolverInterface.php +++ b/src/Field/DefaultValuesResolverInterface.php @@ -9,14 +9,12 @@ interface DefaultValuesResolverInterface { /** - * @param NodeTypeFieldInterface $field - * @return array All possible default values for given field name across all node-types. + * @return array all possible default values for given field name across all node-types */ public function getDefaultValuesAmongAllFields(NodeTypeFieldInterface $field): array; /** - * @param NodeTypeFieldInterface $field - * @return int Max length of all possible default values for given field name across all node-types. + * @return int max length of all possible default values for given field name across all node-types */ public function getMaxDefaultValuesLengthAmongAllFields(NodeTypeFieldInterface $field): int; } diff --git a/src/Field/DocumentsFieldGenerator.php b/src/Field/DocumentsFieldGenerator.php index be8732e..56adc5f 100644 --- a/src/Field/DocumentsFieldGenerator.php +++ b/src/Field/DocumentsFieldGenerator.php @@ -4,34 +4,36 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; use Symfony\Component\String\UnicodeString; -class DocumentsFieldGenerator extends AbstractFieldGenerator +final class DocumentsFieldGenerator extends AbstractFieldGenerator { - protected function getSerializationAttributes(): array + protected function addSerializationAttributes(Property|Method $property): self { - $annotations = parent::getSerializationAttributes(); - $annotations[] = new AttributeGenerator('Serializer\VirtualProperty'); - $annotations[] = new AttributeGenerator('Serializer\SerializedName', [ - AttributeGenerator::wrapString($this->field->getVarName()) + parent::addSerializationAttributes($property); + $property->addAttribute('JMS\Serializer\Annotation\VirtualProperty'); + $property->addAttribute('JMS\Serializer\Annotation\SerializedName', [ + $this->field->getVarName(), ]); - $annotations[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString( - 'array<' . - (new UnicodeString($this->options['document_class']))->trimStart('\\')->toString() . - '>' - ) + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'array<'. + (new UnicodeString($this->options['document_class']))->trimStart('\\')->toString(). + '>', ]); - return $annotations; + return $this; } protected function getDefaultSerializationGroups(): array { $groups = parent::getDefaultSerializationGroups(); $groups[] = 'nodes_sources_documents'; + return $groups; } @@ -40,67 +42,64 @@ protected function getFieldTypeDeclaration(): string return '?array'; } - protected function getFieldDefaultValueDeclaration(): string + protected function getFieldDefaultValueDeclaration(): Literal|string|null { - return 'null'; + return new Literal('null'); } - /** - * @inheritDoc - */ - public function getFieldGetter(): string + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self { - return ' - /** - * @return ' . $this->options['document_class'] . '[] Documents array - */ -' . (new AttributeListGenerator($this->getSerializationAttributes()))->generate(4) . ' - public function ' . $this->field->getGetterName() . '(): array - { - if (null === $this->' . $this->field->getVarName() . ') { - if (null !== $this->objectManager) { - $this->' . $this->field->getVarName() . ' = $this->objectManager - ->getRepository(' . $this->options['document_class'] . '::class) - ->findByNodeSourceAndFieldName( - $this, - \'' . $this->field->getName() . '\' - ); - } else { - $this->' . $this->field->getVarName() . ' = []; - } - } - return $this->' . $this->field->getVarName() . '; - }' . PHP_EOL; + $getter = $classType->addMethod($this->field->getGetterName()) + ->setReturnType('array') + ->addComment('@return '.$this->options['document_class'].'[]'); + $this->addSerializationAttributes($getter); + $getter->setBody(<<{$this->field->getVarName()}) { + if (null !== \$this->objectManager) { + \$this->{$this->field->getVarName()} = \$this->objectManager + ->getRepository({$namespace->simplifyName($this->options['document_class'])}::class) + ->findByNodeSourceAndFieldName( + \$this, + '{$this->field->getName()}' + ); + } else { + \$this->{$this->field->getVarName()} = []; } +} +return \$this->{$this->field->getVarName()}; +EOF + ); - /** - * Generate PHP setter method block. - * - * @return string - */ - protected function getFieldSetter(): string - { - return ' - /** - * @param ' . $this->options['document_class'] . ' $document - * - * @return $this - */ - public function add' . ucfirst($this->field->getVarName()) . '(' . $this->options['document_class'] . ' $document): static + return $this; + } + + protected function addFieldSetter(ClassType $classType): self { - if (null !== $this->objectManager) { - $nodeSourceDocument = new ' . $this->options['document_proxy_class'] . '( - $this, - $document - ); - $nodeSourceDocument->setFieldName(\'' . $this->field->getName() . '\'); - if (!$this->hasNodesSourcesDocuments($nodeSourceDocument)) { - $this->objectManager->persist($nodeSourceDocument); - $this->addDocumentsByFields($nodeSourceDocument); - $this->' . $this->field->getVarName() . ' = null; - } - } + $setter = $classType->addMethod('add'.ucfirst($this->field->getVarName())) + ->setReturnType('static') + ->addComment('@return $this') + ->setPublic(); + + $setter->addParameter('document') + ->setType($this->options['document_class']); + $setter->setBody(<<objectManager) { + return \$this; +} +\$nodeSourceDocument = new {$this->options['document_proxy_class']}( + \$this, + \$document +); +\$nodeSourceDocument->setFieldName('{$this->field->getName()}'); +if (!\$this->hasNodesSourcesDocuments(\$nodeSourceDocument)) { + \$this->objectManager->persist(\$nodeSourceDocument); + \$this->addDocumentsByFields(\$nodeSourceDocument); + \$this->{$this->field->getVarName()} = null; +} +return \$this; +PHP + ); + return $this; - }' . PHP_EOL; } } diff --git a/src/Field/ManyToManyFieldGenerator.php b/src/Field/ManyToManyFieldGenerator.php index 09039bb..ecc9742 100644 --- a/src/Field/ManyToManyFieldGenerator.php +++ b/src/Field/ManyToManyFieldGenerator.php @@ -4,14 +4,25 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; use Symfony\Component\String\UnicodeString; -class ManyToManyFieldGenerator extends AbstractConfigurableFieldGenerator +final class ManyToManyFieldGenerator extends AbstractConfigurableFieldGenerator { - protected function getFieldAttributes(bool $exclude = false): array + protected function getFieldProperty(ClassType $classType): Property { - $attributes = parent::getFieldAttributes($exclude); + return $classType + ->addProperty($this->field->getVarName()) + ->setPrivate() + ->setType($this->getFieldTypeDeclaration()); + } + + protected function addFieldAttributes(Property $property, PhpNamespace $namespace, bool $exclude = false): self + { + parent::addFieldAttributes($property, $namespace, $exclude); /* * Many Users have Many Groups. @@ -31,102 +42,103 @@ protected function getFieldAttributes(bool $exclude = false): array ; $entityB = $this->field->getName(); $joinColumnParams = [ - 'name' => AttributeGenerator::wrapString($entityA . '_id'), - 'referencedColumnName' => AttributeGenerator::wrapString('id'), - 'onDelete' => AttributeGenerator::wrapString('CASCADE') + 'name' => $entityA.'_id', + 'referencedColumnName' => 'id', + 'onDelete' => 'CASCADE', ]; $inverseJoinColumns = [ - 'name' => AttributeGenerator::wrapString($entityB . '_id'), - 'referencedColumnName' => AttributeGenerator::wrapString('id'), - 'onDelete' => AttributeGenerator::wrapString('CASCADE') + 'name' => $entityB.'_id', + 'referencedColumnName' => 'id', + 'onDelete' => 'CASCADE', ]; - $attributes[] = new AttributeGenerator('ORM\ManyToMany', [ - 'targetEntity' => $this->getFullyQualifiedClassName() . '::class' + $property->addAttribute('Doctrine\ORM\Mapping\ManyToMany', [ + 'targetEntity' => new Literal($this->getFullyQualifiedClassName().'::class'), ]); - $attributes[] = new AttributeGenerator('ORM\JoinTable', [ - 'name' => AttributeGenerator::wrapString($entityA . '_' . $entityB) + $property->addAttribute('Doctrine\ORM\Mapping\JoinTable', [ + 'name' => $entityA.'_'.$entityB, ]); - $attributes[] = new AttributeGenerator('ORM\JoinColumn', $joinColumnParams); - $attributes[] = new AttributeGenerator('ORM\InverseJoinColumn', $inverseJoinColumns); + $property->addAttribute('Doctrine\ORM\Mapping\JoinColumn', $joinColumnParams); + $property->addAttribute('Doctrine\ORM\Mapping\InverseJoinColumn', $inverseJoinColumns); if (count($this->configuration['orderBy']) > 0) { // use default order for Collections $orderBy = []; foreach ($this->configuration['orderBy'] as $order) { - $orderBy[] = AttributeGenerator::wrapString($order['field']) . - ' => ' . - AttributeGenerator::wrapString($order['direction']); + $orderBy[$order['field']] = $order['direction']; } - $attributes[] = new AttributeGenerator('ORM\OrderBy', [ - 0 => '[' . implode(', ', $orderBy) . ']' + $property->addAttribute('Doctrine\ORM\Mapping\OrderBy', [ + $orderBy, ]); } - if ($this->options['use_api_platform_filters'] === true) { - $attributes[] = new AttributeGenerator('ApiFilter', [ - 0 => 'OrmFilter\SearchFilter::class', - 'strategy' => AttributeGenerator::wrapString('exact') + if (true === $this->options['use_api_platform_filters']) { + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + 0 => new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\SearchFilter').'::class'), + 'strategy' => 'exact', ]); } - return [ - ...$attributes, - ...$this->getSerializationAttributes() - ]; + $this->addSerializationAttributes($property); + + return $this; } - /** - * @inheritDoc - */ - public function getFieldAnnotation(): string + public function addFieldAnnotation(Property $property): self { - return ' - /** - *' . implode(PHP_EOL . static::ANNOTATION_PREFIX, $this->getFieldAutodoc()) . ' - * @var CollectiongetFullyQualifiedClassName() . '> - */' . PHP_EOL; + $this->addFieldAutodoc($property); + $property->addComment( + '@var \Doctrine\Common\Collections\CollectiongetFullyQualifiedClassName().'>' + ); + + return $this; } protected function getFieldTypeDeclaration(): string { - return 'Collection'; + return '\Doctrine\Common\Collections\Collection'; } - /** - * @inheritDoc - */ - public function getFieldGetter(): string + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self { - return ' - /** - * @return CollectiongetFullyQualifiedClassName() . '> - */ - public function ' . $this->field->getGetterName() . '(): Collection - { - return $this->' . $this->field->getVarName() . '; - }' . PHP_EOL; + $classType->addMethod($this->field->getGetterName()) + ->setReturnType('\Doctrine\Common\Collections\Collection') + ->setPublic() + ->setBody('return $this->'.$this->field->getVarName().';') + ->addComment( + '@return '. + $namespace->simplifyName('\Doctrine\Common\Collections\Collection'). + 'getFullyQualifiedClassName(). + '>' + ); + + return $this; } - /** - * @inheritDoc - */ - public function getFieldSetter(): string - { - return ' - /** - * @param CollectiongetFullyQualifiedClassName() . '>|' . $this->getFullyQualifiedClassName() . '[] $' . $this->field->getVarName() . ' - * @return $this - */ - public function ' . $this->field->getSetterName() . '(Collection|array $' . $this->field->getVarName() . '): static + public function addFieldSetter(ClassType $classType): self { - if ($' . $this->field->getVarName() . ' instanceof \Doctrine\Common\Collections\Collection) { - $this->' . $this->field->getVarName() . ' = $' . $this->field->getVarName() . '; - } else { - $this->' . $this->field->getVarName() . ' = new \Doctrine\Common\Collections\ArrayCollection($' . $this->field->getVarName() . '); - } + $setter = $classType->addMethod($this->field->getSetterName()) + ->setReturnType('static') + ->addComment( + '@param \Doctrine\Common\Collections\CollectiongetFullyQualifiedClassName(). + '>|array<'.$this->getFullyQualifiedClassName().'> $'.$this->field->getVarName() + ) + ->addComment('@return $this') + ->setPublic(); + + $setter->addParameter($this->field->getVarName()) + ->setType('\Doctrine\Common\Collections\Collection|array'); + + $setter->setBody(<<field->getVarName()} instanceof \Doctrine\Common\Collections\Collection) { + \$this->{$this->field->getVarName()} = \${$this->field->getVarName()}; +} else { + \$this->{$this->field->getVarName()} = new \Doctrine\Common\Collections\ArrayCollection(\${$this->field->getVarName()}); +} +return \$this; +PHP + ); return $this; - }' . PHP_EOL; } protected function isExcludingFieldFromJmsSerialization(): bool @@ -134,11 +146,8 @@ protected function isExcludingFieldFromJmsSerialization(): bool return false; } - /** - * @inheritDoc - */ public function getFieldConstructorInitialization(): string { - return '$this->' . $this->field->getVarName() . ' = new \Doctrine\Common\Collections\ArrayCollection();'; + return '$this->'.$this->field->getVarName().' = new \Doctrine\Common\Collections\ArrayCollection();'; } } diff --git a/src/Field/ManyToOneFieldGenerator.php b/src/Field/ManyToOneFieldGenerator.php index 44cd42e..04d81eb 100644 --- a/src/Field/ManyToOneFieldGenerator.php +++ b/src/Field/ManyToOneFieldGenerator.php @@ -4,40 +4,42 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; -class ManyToOneFieldGenerator extends AbstractConfigurableFieldGenerator +final class ManyToOneFieldGenerator extends AbstractConfigurableFieldGenerator { - protected function getFieldAttributes(bool $exclude = false): array + protected function addFieldAttributes(Property $property, PhpNamespace $namespace, bool $exclude = false): self { - $attributes = parent::getFieldAttributes($exclude); + parent::addFieldAttributes($property, $namespace, $exclude); /* * Many Users have One Address. - * @ORM\ManyToOne(targetEntity="Address") - * @ORM\JoinColumn(name="address_id", referencedColumnName="id", onDelete="SET NULL") + * @\Doctrine\ORM\Mapping\ManyToOne(targetEntity="Address") + * @\Doctrine\ORM\Mapping\JoinColumn(name="address_id", referencedColumnName="id", onDelete="SET NULL") */ $ormParams = [ - 'name' => AttributeGenerator::wrapString($this->field->getName() . '_id'), - 'referencedColumnName' => AttributeGenerator::wrapString('id'), - 'onDelete' => AttributeGenerator::wrapString('SET NULL'), + 'name' => $this->field->getName().'_id', + 'referencedColumnName' => 'id', + 'onDelete' => 'SET NULL', ]; - $attributes[] = new AttributeGenerator('ORM\ManyToOne', [ - 'targetEntity' => $this->getFullyQualifiedClassName() . '::class' + $property->addAttribute('Doctrine\ORM\Mapping\ManyToOne', [ + 'targetEntity' => new Literal($this->getFullyQualifiedClassName().'::class'), ]); - $attributes[] = new AttributeGenerator('ORM\JoinColumn', $ormParams); + $property->addAttribute('Doctrine\ORM\Mapping\JoinColumn', $ormParams); - if ($this->options['use_api_platform_filters'] === true) { - $attributes[] = new AttributeGenerator('ApiFilter', [ - 0 => 'OrmFilter\SearchFilter::class', - 'strategy' => AttributeGenerator::wrapString('exact') + if (true === $this->options['use_api_platform_filters']) { + $property->addAttribute('ApiPlatform\Metadata\ApiFilter', [ + 0 => new Literal($namespace->simplifyName('\ApiPlatform\Doctrine\Orm\Filter\SearchFilter').'::class'), + 'strategy' => 'exact', ]); } - return [ - ...$attributes, - ...$this->getSerializationAttributes() - ]; + $this->addSerializationAttributes($property); + + return $this; } protected function isExcludingFieldFromJmsSerialization(): bool @@ -45,58 +47,52 @@ protected function isExcludingFieldFromJmsSerialization(): bool return false; } - /** - * @inheritDoc - */ - public function getFieldAnnotation(): string + public function addFieldAnnotation(Property $property): self { - return ' - /** - *' . implode(PHP_EOL . static::ANNOTATION_PREFIX, $this->getFieldAutodoc()) . ' - * @var ' . $this->getFullyQualifiedClassName() . '|null - */' . PHP_EOL; + $this->addFieldAutodoc($property); + + return $this; } protected function getFieldTypeDeclaration(): string { - return '?' . $this->getFullyQualifiedClassName(); + return '?'.$this->getFullyQualifiedClassName(); } - protected function getFieldDefaultValueDeclaration(): string + protected function getFieldDefaultValueDeclaration(): Literal|string|null { - return 'null'; + return new Literal('null'); } - /** - * @inheritDoc - */ - public function getFieldGetter(): string + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self { - return ' - /** - * @return ' . $this->getFullyQualifiedClassName() . '|null - */ - public function ' . $this->field->getGetterName() . '(): ?' . $this->getFullyQualifiedClassName() . ' - { - return $this->' . $this->field->getVarName() . '; - }' . PHP_EOL; + $classType->addMethod($this->field->getGetterName()) + ->setReturnType($this->getFieldTypeDeclaration()) + ->setPublic() + ->setBody(<<{$this->field->getVarName()}; +PHP + ); + + return $this; } - /** - * @inheritDoc - */ - public function getFieldSetter(): string + public function addFieldSetter(ClassType $classType): self { - return ' - /** - * @param ' . $this->getFullyQualifiedClassName() . '|null $' . $this->field->getVarName() . ' - * @return $this - */ - public function ' . $this->field->getSetterName() . '(?' . $this->getFullyQualifiedClassName() . ' $' . $this->field->getVarName() . ' = null): static - { - $this->' . $this->field->getVarName() . ' = $' . $this->field->getVarName() . '; + $setter = $classType->addMethod($this->field->getSetterName()) + ->setReturnType('static') + ->addComment('@return $this') + ->setPublic(); + $setter->addParameter($this->field->getVarName()) + ->setType($this->getFieldTypeDeclaration()) + ->setNullable(); + + $setter->setBody(<<{$this->field->getVarName()} = \${$this->field->getVarName()}; +return \$this; +PHP + ); return $this; - }' . PHP_EOL; } } diff --git a/src/Field/NodesFieldGenerator.php b/src/Field/NodesFieldGenerator.php index 9f11d15..3cbcd58 100644 --- a/src/Field/NodesFieldGenerator.php +++ b/src/Field/NodesFieldGenerator.php @@ -4,163 +4,139 @@ namespace RZ\Roadiz\EntityGenerator\Field; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; use RZ\Roadiz\Contracts\NodeType\NodeTypeFieldInterface; use RZ\Roadiz\Contracts\NodeType\NodeTypeResolverInterface; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; use Symfony\Component\String\UnicodeString; -class NodesFieldGenerator extends AbstractFieldGenerator +final class NodesFieldGenerator extends AbstractFieldGenerator { - private NodeTypeResolverInterface $nodeTypeResolver; - public function __construct( + private readonly NodeTypeResolverInterface $nodeTypeResolver, NodeTypeFieldInterface $field, - NodeTypeResolverInterface $nodeTypeResolver, DefaultValuesResolverInterface $defaultValuesResolver, - array $options = [] + array $options = [], ) { parent::__construct($field, $defaultValuesResolver, $options); - $this->nodeTypeResolver = $nodeTypeResolver; } - /** - * Generate PHP code for current doctrine field. - * - * @return string - */ - public function getField(): string + public function addField(ClassType $classType, PhpNamespace $namespace): void { - return $this->getFieldGetter() . - $this->getFieldAlternativeGetter() . - $this->getFieldSetter() . PHP_EOL; + $this->addFieldGetter($classType, $namespace); + $this->addFieldSetter($classType); } - protected function getSerializationAttributes(): array + protected function addSerializationAttributes(Property|Method $property): self { - $annotations = parent::getSerializationAttributes(); - $annotations[] = new AttributeGenerator('Serializer\VirtualProperty'); - $annotations[] = new AttributeGenerator('Serializer\SerializedName', [ - AttributeGenerator::wrapString($this->field->getVarName()) + parent::addSerializationAttributes($property); + $property->addAttribute('JMS\Serializer\Annotation\VirtualProperty'); + $property->addAttribute('JMS\Serializer\Annotation\SerializedName', [ + $this->field->getVarName(), ]); - $annotations[] = new AttributeGenerator('Serializer\Type', [ - AttributeGenerator::wrapString( - 'array<' . - (new UnicodeString($this->options['parent_class']))->trimStart('\\')->toString() . - '>' - ) + $property->addAttribute('JMS\Serializer\Annotation\Type', [ + 'array<'. + (new UnicodeString($this->options['parent_class']))->trimStart('\\')->toString(). + '>', ]); - return $annotations; + return $this; } protected function getDefaultSerializationGroups(): array { $groups = parent::getDefaultSerializationGroups(); $groups[] = 'nodes_sources_nodes'; + return $groups; } - /** - * @return string - */ protected function getFieldSourcesName(): string { - return $this->field->getVarName() . 'Sources'; + return $this->field->getVarName().'Sources'; } - /** - * @return bool - */ + protected function hasOnlyOneNodeType(): bool { if (!empty($this->field->getDefaultValues())) { - return count(explode(',', $this->field->getDefaultValues())) === 1; + return 1 === count(explode(',', $this->field->getDefaultValues())); } + return false; } - /** - * @return string - */ protected function getRepositoryClass(): string { - if (!empty($this->field->getDefaultValues()) && $this->hasOnlyOneNodeType() === true) { + if (!empty($this->field->getDefaultValues()) && true === $this->hasOnlyOneNodeType()) { $nodeTypeName = trim(explode(',', $this->field->getDefaultValues())[0]); $nodeType = $this->nodeTypeResolver->get($nodeTypeName); if (null !== $nodeType) { $className = $nodeType->getSourceEntityFullQualifiedClassName(); + return (new UnicodeString($className))->startsWith('\\') ? $className : - '\\' . $className; + '\\'.$className; } } + return $this->options['parent_class']; } - /** - * @inheritDoc - */ - public function getFieldGetter(): string + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self { - $autodoc = ''; - $fieldAutoDoc = $this->getFieldAutodoc(); - if (!empty($fieldAutoDoc)) { - $autodoc = PHP_EOL . - static::ANNOTATION_PREFIX . - implode(PHP_EOL . static::ANNOTATION_PREFIX, $fieldAutoDoc); - } + $property = $classType->addProperty($this->getFieldSourcesName()) + ->setType('?array') + ->setPrivate() + ->setValue(null) + ->addComment($this->getFieldSourcesName().' NodesSources direct field buffer.') + ->addComment('@var '.$this->getRepositoryClass().'[]|null'); + + $this->addFieldAutodoc($property); + $this->addFieldAttributes($property, $namespace, $this->isExcludingFieldFromJmsSerialization()); + + $getter = $classType->addMethod($this->field->getGetterName().'Sources') + ->setReturnType('array') + ->addComment('@return '.$this->getRepositoryClass().'[]') + ->setPublic(); + $this->addSerializationAttributes($getter); + $getter->setBody(<<{$this->getFieldSourcesName()}) { + if (null !== \$this->objectManager) { + \$this->{$this->getFieldSourcesName()} = \$this->objectManager + ->getRepository({$this->getRepositoryClass()}::class) + ->findByNodesSourcesAndFieldNameAndTranslation( + \$this, + '{$this->field->getName()}' + ); + } else { + \$this->{$this->getFieldSourcesName()} = []; + } +} +return \$this->{$this->getFieldSourcesName()}; +PHP + ); - return ' - /** - * ' . $this->getFieldSourcesName() . ' NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - *' . $autodoc . ' - * @var ' . $this->getRepositoryClass() . '[]|null - */ -' . (new AttributeListGenerator( - $this->getFieldAttributes($this->isExcludingFieldFromJmsSerialization()) - ))->generate(4) . ' - private ?array $' . $this->getFieldSourcesName() . ' = null; - - /** - * @return ' . $this->getRepositoryClass() . '[] ' . $this->field->getVarName() . ' nodes-sources array - */ -' . (new AttributeListGenerator($this->getSerializationAttributes()))->generate(4) . ' - public function ' . $this->field->getGetterName() . 'Sources(): array - { - if (null === $this->' . $this->getFieldSourcesName() . ') { - if (null !== $this->objectManager) { - $this->' . $this->getFieldSourcesName() . ' = $this->objectManager - ->getRepository(' . $this->getRepositoryClass() . '::class) - ->findByNodesSourcesAndFieldNameAndTranslation( - $this, - \'' . $this->field->getName() . '\' - ); - } else { - $this->' . $this->getFieldSourcesName() . ' = []; - } - } - return $this->' . $this->getFieldSourcesName() . '; - }' . PHP_EOL; + return $this; } - /** - * @inheritDoc - */ - public function getFieldSetter(): string - { - return ' - /** - * @param ' . $this->getRepositoryClass() . '[]|null $' . $this->getFieldSourcesName() . ' - * - * @return $this - */ - public function ' . $this->field->getSetterName() . 'Sources(?array $' . $this->getFieldSourcesName() . '): static + public function addFieldSetter(ClassType $classType): self { - $this->' . $this->getFieldSourcesName() . ' = $' . $this->getFieldSourcesName() . '; + $setter = $classType->addMethod($this->field->getSetterName().'Sources') + ->setReturnType('static') + ->addComment('@param '.$this->getRepositoryClass().'[]|null $'.$this->getFieldSourcesName()) + ->addComment('@return $this') + ->setPublic(); + $setter->addParameter($this->getFieldSourcesName()) + ->setType('?array'); + $setter->setBody(<<{$this->getFieldSourcesName()} = \${$this->getFieldSourcesName()}; +return \$this; +PHP + ); return $this; - }' . PHP_EOL; } } diff --git a/src/Field/NonVirtualFieldGenerator.php b/src/Field/NonVirtualFieldGenerator.php index 9a9df5e..e53a771 100644 --- a/src/Field/NonVirtualFieldGenerator.php +++ b/src/Field/NonVirtualFieldGenerator.php @@ -4,45 +4,49 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; class NonVirtualFieldGenerator extends AbstractFieldGenerator { /** * Generate PHP annotation block for Doctrine table indexes. - * - * @return AttributeGenerator|null */ - public function getFieldIndex(): ?AttributeGenerator + public function addFieldIndex(ClassType $classType): self { if ($this->field->isIndexed()) { - return new AttributeGenerator('ORM\Index', [ - 'columns' => '[' . AttributeGenerator::wrapString($this->field->getName()) . ']' - ]); + $classType->addAttribute( + 'Doctrine\ORM\Mapping\Index', + [ + 'columns' => [ + $this->field->getName(), + ], + ] + ); } - return null; + return $this; } - /** - * @return string - */ protected function getDoctrineType(): string { return $this->field->getDoctrineType(); } /** - * @return int|null String field length, returns NULL if length is irrelevant. + * @return int|null string field length, returns NULL if length is irrelevant */ protected function getFieldLength(): ?int { /* * Only set length for string (VARCHAR) type */ - if ($this->getDoctrineType() !== 'string') { + if ('string' !== $this->getDoctrineType()) { return null; } + return match (true) { $this->field->isColor() => 10, $this->field->isCountry() => 5, @@ -57,9 +61,9 @@ protected function isExcludingFieldFromJmsSerialization(): bool return false; } - protected function getFieldAttributes(bool $exclude = false): array + protected function addFieldAttributes(Property $property, PhpNamespace $namespace, bool $exclude = false): self { - $attributes = parent::getFieldAttributes($exclude); + parent::addFieldAttributes($property, $namespace, $exclude); /* * ?string $name = null, @@ -77,9 +81,9 @@ protected function getFieldAttributes(bool $exclude = false): array * ?string $generated = null */ $ormParams = [ - 'name' => AttributeGenerator::wrapString($this->field->getName()), - 'type' => AttributeGenerator::wrapString($this->getDoctrineType()), - 'nullable' => 'true', + 'name' => $this->field->getName(), + 'type' => $this->getDoctrineType(), + 'nullable' => true, ]; $fieldLength = $this->getFieldLength(); @@ -91,119 +95,87 @@ protected function getFieldAttributes(bool $exclude = false): array $ormParams['precision'] = 18; $ormParams['scale'] = 3; } elseif ($this->field->isBool()) { - $ormParams['nullable'] = 'false'; - $ormParams['options'] = '["default" => false]'; + $ormParams['nullable'] = false; + $ormParams['options'] = [ + 'default' => false, + ]; } - $attributes[] = new AttributeGenerator('Gedmo\Versioned'); - $attributes[] = new AttributeGenerator('ORM\Column', $ormParams); + $property->addAttribute('Gedmo\Mapping\Annotation\Versioned'); + $property->addAttribute('Doctrine\ORM\Mapping\Column', $ormParams); - if (empty($this->getFieldAlternativeGetter()) && !empty($this->getSerializationAttributes())) { - return [ - ...$attributes, - ...$this->getSerializationAttributes() - ]; + if (!$this->hasFieldAlternativeGetter() && $this->hasSerializationAttributes()) { + $this->addSerializationAttributes($property); } - return $attributes; + return $this; } - - /** - * @inheritDoc - */ - public function getFieldAnnotation(): string + public function addFieldAnnotation(Property $property): self { - $autodoc = ''; - if (!empty($this->getFieldAutodoc())) { - $autodoc = PHP_EOL . - static::ANNOTATION_PREFIX . - implode(PHP_EOL . static::ANNOTATION_PREFIX, $this->getFieldAutodoc()); - } + $this->addFieldAutodoc($property); - return ' - /**' . $autodoc . ' - */' . PHP_EOL; + return $this; } protected function getFieldTypeDeclaration(): string { - switch (true) { - case $this->field->isBool(): - return 'bool'; - case $this->field->isMultiple(): - return '?array'; - case $this->field->isInteger(): - case $this->field->isDecimal(): - return 'int|float|null'; - case $this->field->isColor(): - case $this->field->isEmail(): - case $this->field->isString(): - case $this->field->isCountry(): - case $this->field->isMarkdown(): - case $this->field->isText(): - case $this->field->isRichText(): - case $this->field->isEnum(): - return '?string'; - case $this->field->isDateTime(): - case $this->field->isDate(): - return '?\DateTime'; - default: - return ''; - } + return match (true) { + $this->field->isBool() => 'bool', + $this->field->isMultiple() => '?array', + $this->field->isInteger(), + $this->field->isDecimal() => 'int|float|null', + $this->field->isColor(), + $this->field->isEmail(), + $this->field->isString(), + $this->field->isCountry(), + $this->field->isMarkdown(), + $this->field->isText(), + $this->field->isRichText(), + $this->field->isEnum() => '?string', + $this->field->isDateTime(), + $this->field->isDate() => '?\DateTime', + default => 'mixed', + }; } - protected function getFieldDefaultValueDeclaration(): string + protected function getFieldDefaultValueDeclaration(): Literal|string|null { - switch (true) { - case $this->field->isBool(): - return 'false'; - default: - return 'null'; - } + return match (true) { + $this->field->isBool() => new Literal('false'), + default => new Literal('null'), + }; } - /** - * @inheritDoc - */ - public function getFieldGetter(): string + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self { $type = $this->getFieldTypeDeclaration(); - if (empty($type)) { - $docType = 'mixed'; - $typeHint = ''; - } else { - $docType = $this->toPhpDocType($type); - $typeHint = ': ' . $type; - } - $assignation = '$this->' . $this->field->getVarName(); + $method = $classType->addMethod($this->field->getGetterName()) + ->setPublic() + ->setReturnType($type) + ->addComment('@return '.$this->toPhpDocType($type)); if ($this->field->isMultiple()) { - $assignation = sprintf('null !== %s ? array_values(%s) : null', $assignation, $assignation); + $method->setBody( + 'return null !== $this->'. + $this->field->getVarName().' ? array_values($this->'.$this->field->getVarName().') : null;' + ); + } else { + $method->setBody('return $this->'.$this->field->getVarName().';'); } - return ' - /** - * @return ' . $docType . ' - */ - public function ' . $this->field->getGetterName() . '()' . $typeHint . ' - { - return ' . $assignation . '; - }' . PHP_EOL; + return $this; } - /** - * @inheritDoc - */ - public function getFieldSetter(): string + public function addFieldSetter(ClassType $classType): self { - $assignation = '$' . $this->field->getVarName(); + $assignation = '$'.$this->field->getVarName(); $nullable = true; $casting = ''; switch (true) { case $this->field->isBool(): - $casting = '(boolean) '; + $casting = '(bool) '; $nullable = false; break; case $this->field->isInteger(): @@ -222,33 +194,23 @@ public function getFieldSetter(): string } $type = $this->getFieldTypeDeclaration(); - if (empty($type)) { - $docType = 'mixed'; - $typeHint = ''; - } else { - $docType = $this->toPhpDocType($type); - $typeHint = $type . ' '; - } if ($nullable && !empty($casting)) { - $assignation = '$this->' . $this->field->getVarName() . ' = null !== $' . $this->field->getVarName() . ' ? - ' . $casting . $assignation . ' : + $assignation = '$this->'.$this->field->getVarName().' = null !== $'.$this->field->getVarName().' ? + '.$casting.$assignation.' : null;'; } else { - $assignation = '$this->' . $this->field->getVarName() . ' = ' . $assignation . ';'; + $assignation = '$this->'.$this->field->getVarName().' = '.$assignation.';'; } - return ' - /** - * @param ' . $docType . ' $' . $this->field->getVarName() . ' - * - * @return $this - */ - public function ' . $this->field->getSetterName() . '(' . $typeHint . '$' . $this->field->getVarName() . '): static - { - ' . $assignation . ' + $method = $classType->addMethod($this->field->getSetterName())->setPublic(); + $method->setReturnType('static')->addComment('@return $this'); + $method->addParameter($this->field->getVarName())->setType($type); + $method + ->addBody($assignation) + ->addBody('return $this;') + ; return $this; - }' . PHP_EOL; } } diff --git a/src/Field/ProxiedManyToManyFieldGenerator.php b/src/Field/ProxiedManyToManyFieldGenerator.php index ccfd13e..22e1499 100644 --- a/src/Field/ProxiedManyToManyFieldGenerator.php +++ b/src/Field/ProxiedManyToManyFieldGenerator.php @@ -4,52 +4,57 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Literal; +use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\PhpNamespace; +use Nette\PhpGenerator\Property; use Symfony\Component\String\UnicodeString; -class ProxiedManyToManyFieldGenerator extends AbstractConfigurableFieldGenerator +final class ProxiedManyToManyFieldGenerator extends AbstractConfigurableFieldGenerator { - protected function getSerializationAttributes(): array + protected function addSerializationAttributes(Property|Method $property): self { - $annotations = parent::getSerializationAttributes(); - if (!$this->excludeFromSerialization()) { - $annotations[] = new AttributeGenerator('Serializer\VirtualProperty'); - $annotations[] = new AttributeGenerator('Serializer\SerializedName', [ - AttributeGenerator::wrapString($this->field->getVarName()) - ]); - $annotations[] = new AttributeGenerator('SymfonySerializer\SerializedName', [ - 'serializedName' => AttributeGenerator::wrapString($this->field->getVarName()) - ]); - $annotations[] = new AttributeGenerator('SymfonySerializer\Groups', [ - $this->getSerializationGroups() + parent::addSerializationAttributes($property); + if ($this->excludeFromSerialization()) { + return $this; + } + + $property->addAttribute('JMS\Serializer\Annotation\VirtualProperty'); + $property->addAttribute('JMS\Serializer\Annotation\SerializedName', [ + $this->field->getVarName(), + ]); + $property->addAttribute('Symfony\Component\Serializer\Attribute\SerializedName', [ + 'serializedName' => $this->field->getVarName(), + ]); + $property->addAttribute('Symfony\Component\Serializer\Attribute\Groups', [ + $this->getSerializationGroups(), + ]); + if ($this->getSerializationMaxDepth() > 0) { + $property->addAttribute('Symfony\Component\Serializer\Attribute\MaxDepth', [ + $this->getSerializationMaxDepth(), ]); - if ($this->getSerializationMaxDepth() > 0) { - $annotations[] = new AttributeGenerator('SymfonySerializer\MaxDepth', [ - $this->getSerializationMaxDepth() - ]); - } } - return $annotations; + + return $this; } /** * Generate PHP property declaration block. */ - protected function getFieldDeclaration(): string + protected function getFieldProperty(ClassType $classType): Property { - /* - * Buffer var to get referenced entities (documents, nodes, cforms, doctrine entities) - */ - return ' private Collection $' . $this->getProxiedVarName() . ';' . PHP_EOL; + return $classType + ->addProperty($this->getProxiedVarName()) + ->setPrivate() + ->addComment('Buffer var to get referenced entities (documents, nodes, cforms, doctrine entities)') + ->setType('\Doctrine\Common\Collections\Collection'); } - protected function getFieldAttributes(bool $exclude = false): array + protected function addFieldAttributes(Property $property, PhpNamespace $namespace, bool $exclude = false): self { - $attributes = []; - - $attributes[] = new AttributeGenerator('Serializer\Exclude'); - $attributes[] = new AttributeGenerator('SymfonySerializer\Ignore'); + $property->addAttribute('JMS\Serializer\Annotation\Exclude'); + $property->addAttribute('Symfony\Component\Serializer\Attribute\Ignore'); /* * Many Users have Many Groups. @@ -59,191 +64,171 @@ protected function getFieldAttributes(bool $exclude = false): array * inverseJoinColumns={@JoinColumn(name="group_id", referencedColumnName="id")} */ $ormParams = [ - 'targetEntity' => '\\' . trim($this->getProxyClassname(), '\\') . '::class', - 'mappedBy' => AttributeGenerator::wrapString($this->configuration['proxy']['self']), - 'orphanRemoval' => 'true', - 'cascade' => '["persist", "remove"]' + 'targetEntity' => new Literal('\\'.trim($this->getProxyClassname(), '\\').'::class'), + 'mappedBy' => $this->configuration['proxy']['self'], + 'orphanRemoval' => true, + 'cascade' => ['persist', 'remove'], ]; - $attributes[] = new AttributeGenerator('ORM\OneToMany', $ormParams); + $property->addAttribute('Doctrine\ORM\Mapping\OneToMany', $ormParams); if (isset($this->configuration['proxy']['orderBy']) && count($this->configuration['proxy']['orderBy']) > 0) { // use default order for Collections $orderBy = []; foreach ($this->configuration['proxy']['orderBy'] as $order) { - $orderBy[] = AttributeGenerator::wrapString($order['field']) . - ' => ' . - AttributeGenerator::wrapString($order['direction']); + $orderBy[$order['field']] = $order['direction']; } - $attributes[] = new AttributeGenerator('ORM\OrderBy', [ - 0 => '[' . implode(', ', $orderBy) . ']' + $property->addAttribute('Doctrine\ORM\Mapping\OrderBy', [ + $orderBy, ]); } - return $attributes; + return $this; } - - /** - * @inheritDoc - */ - public function getFieldAnnotation(): string + public function addFieldAnnotation(Property $property): self { - return ' - /** - * ' . $this->field->getLabel() . ' - * - * @var CollectiongetProxyClassname() . '> - */' . PHP_EOL; - } + $property->addComment($this->field->getLabel().'.'); + $property->addComment('@var \Doctrine\Common\Collections\CollectiongetProxyClassname().'>'); - /** - * @inheritDoc - */ - public function getFieldGetter(): string - { - return ' - /** - * @return CollectiongetProxyClassname() . '> - */ - public function ' . $this->getProxiedGetterName() . '(): Collection - { - return $this->' . $this->getProxiedVarName() . '; - } - - /** - * @return Collection - */ -' . (new AttributeListGenerator($this->getSerializationAttributes()))->generate(4) . ' - public function ' . $this->field->getGetterName() . '(): Collection - { - return $this->' . $this->getProxiedVarName() . '->map(function (' . $this->getProxyClassname() . ' $proxyEntity) { - return $proxyEntity->' . $this->getProxyRelationGetterName() . '(); - }); - }' . PHP_EOL; + return $this; } - /** - * @inheritDoc - */ - public function getFieldSetter(): string - { - return ' - /** - * @param Collection $' . $this->getProxiedVarName() . ' - * @Serializer\VirtualProperty() - * @return $this - */ - public function ' . $this->getProxiedSetterName() . '(Collection $' . $this->getProxiedVarName() . '): static - { - $this->' . $this->getProxiedVarName() . ' = $' . $this->getProxiedVarName() . '; + public function addFieldGetter(ClassType $classType, PhpNamespace $namespace): self + { + $classType->addMethod($this->getProxiedGetterName()) + ->setReturnType('\Doctrine\Common\Collections\Collection') + ->setPublic() + ->setBody('return $this->'.$this->getProxiedVarName().';') + ->addComment( + '@return '. + $namespace->simplifyName('\Doctrine\Common\Collections\Collection'). + 'getProxyClassname(). + '>' + ); + + // Real getter + $getter = $classType->addMethod($this->field->getGetterName()) + ->setPublic() + ->setReturnType('array'); + $this->addSerializationAttributes($getter); + $getter->setBody(<<{$this->getProxiedVarName()}->map(function ({$this->getProxyClassname()} \$proxyEntity) { + return \$proxyEntity->{$this->getProxyRelationGetterName()}(); +})->getValues(); +EOF + ); return $this; } - /** - * @param Collection|array|null $' . $this->field->getVarName() . ' - * @return $this - */ - public function ' . $this->field->getSetterName() . '(Collection|array|null $' . $this->field->getVarName() . ' = null): static - { - foreach ($this->' . $this->getProxiedGetterName() . '() as $item) { - $item->' . $this->getProxySelfSetterName() . '(null); - } - $this->' . $this->getProxiedVarName() . '->clear(); - if (null !== $' . $this->field->getVarName() . ') { - $position = 0; - foreach ($' . $this->field->getVarName() . ' as $single' . ucwords($this->field->getVarName()) . ') { - $proxyEntity = new ' . $this->getProxyClassname() . '(); - $proxyEntity->' . $this->getProxySelfSetterName() . '($this); - if ($proxyEntity instanceof \RZ\Roadiz\Core\AbstractEntities\PositionedInterface) { - $proxyEntity->setPosition(++$position); - } - $proxyEntity->' . $this->getProxyRelationSetterName() . '($single' . ucwords($this->field->getVarName()) . '); - $this->' . $this->getProxiedVarName() . '->add($proxyEntity); - $this->objectManager->persist($proxyEntity); - } + + public function addFieldSetter(ClassType $classType): self + { + $proxySetter = $classType->addMethod($this->getProxiedSetterName()) + ->setReturnType('static') + ->setPublic() + ->addComment('@param \Doctrine\Common\Collections\CollectiongetProxyClassname().'> $'.$this->getProxiedVarName()) + ->addComment('@return $this') + ; + $proxySetter->addParameter($this->getProxiedVarName()) + ->setType('\Doctrine\Common\Collections\Collection'); + + $proxySetter->setBody(<<{$this->getProxiedVarName()} = \${$this->getProxiedVarName()}; +return \$this; +EOF + ); + + $setter = $classType->addMethod($this->field->getSetterName()) + ->setReturnType('static') + ->setPublic() + ->addComment('@return $this') + ; + $setter->addParameter($this->field->getVarName()) + ->setType('\Doctrine\Common\Collections\Collection|array|null'); + + $ucFieldVarName = ucwords($this->field->getVarName()); + + $setter->setBody(<<{$this->getProxiedGetterName()}() as \$item) { + \$item->{$this->getProxySelfSetterName()}(null); +} +\$this->{$this->getProxiedVarName()}->clear(); +if (null !== \${$this->field->getVarName()}) { + \$position = 0; + foreach (\${$this->field->getVarName()} as \$single{$ucFieldVarName}) { + \$proxyEntity = new {$this->getProxyClassname()}(); + \$proxyEntity->{$this->getProxySelfSetterName()}(\$this); + if (\$proxyEntity instanceof \RZ\Roadiz\Core\AbstractEntities\PositionedInterface) { + \$proxyEntity->setPosition(++\$position); } + \$proxyEntity->{$this->getProxyRelationSetterName()}(\$single{$ucFieldVarName}); + \$this->{$this->getProxiedVarName()}->add(\$proxyEntity); + \$this->objectManager->persist(\$proxyEntity); + } +} + +return \$this; +EOF + ); return $this; - }' . PHP_EOL; } - /** - * @inheritDoc - */ public function getFieldConstructorInitialization(): string { - return '$this->' . $this->getProxiedVarName() . ' = new \Doctrine\Common\Collections\ArrayCollection();'; + return '$this->'.$this->getProxiedVarName().' = new \Doctrine\Common\Collections\ArrayCollection();'; } - /** - * @return string - */ protected function getProxiedVarName(): string { - return $this->field->getVarName() . 'Proxy'; + return $this->field->getVarName().'Proxy'; } - /** - * @return string - */ + protected function getProxiedSetterName(): string { - return $this->field->getSetterName() . 'Proxy'; + return $this->field->getSetterName().'Proxy'; } - /** - * @return string - */ + protected function getProxiedGetterName(): string { - return $this->field->getGetterName() . 'Proxy'; + return $this->field->getGetterName().'Proxy'; } - /** - * @return string - */ + protected function getProxySelfSetterName(): string { - return 'set' . ucwords($this->configuration['proxy']['self']); + return 'set'.ucwords($this->configuration['proxy']['self']); } - /** - * @return string - */ + protected function getProxyRelationSetterName(): string { - return 'set' . ucwords($this->configuration['proxy']['relation']); + return 'set'.ucwords($this->configuration['proxy']['relation']); } - /** - * @return string - */ + protected function getProxyRelationGetterName(): string { - return 'get' . ucwords($this->configuration['proxy']['relation']); + return 'get'.ucwords($this->configuration['proxy']['relation']); } - /** - * @return string - */ protected function getProxyClassname(): string { return (new UnicodeString($this->configuration['proxy']['classname']))->startsWith('\\') ? $this->configuration['proxy']['classname'] : - '\\' . $this->configuration['proxy']['classname']; + '\\'.$this->configuration['proxy']['classname']; } - /** - * @return string - */ public function getCloneStatements(): string { - return ' - - $' . $this->getProxiedVarName() . 'Clone = new \Doctrine\Common\Collections\ArrayCollection(); - foreach ($this->' . $this->getProxiedVarName() . ' as $item) { - $itemClone = clone $item; - $itemClone->setNodeSource($this); - $' . $this->getProxiedVarName() . 'Clone->add($itemClone); - $this->objectManager->persist($itemClone); - } - $this->' . $this->getProxiedVarName() . ' = $' . $this->getProxiedVarName() . 'Clone; - '; + return <<getProxiedVarName()}Clone = new \Doctrine\Common\Collections\ArrayCollection(); +foreach (\$this->{$this->getProxiedVarName()} as \$item) { + \$itemClone = clone \$item; + \$itemClone->setNodeSource(\$this); + \${$this->getProxiedVarName()}Clone->add(\$itemClone); + \$this->objectManager->persist(\$itemClone); +} +\$this->{$this->getProxiedVarName()} = \${$this->getProxiedVarName()}Clone; +PHP; } } diff --git a/src/Field/YamlFieldGenerator.php b/src/Field/YamlFieldGenerator.php index c8c381d..e17b3f2 100644 --- a/src/Field/YamlFieldGenerator.php +++ b/src/Field/YamlFieldGenerator.php @@ -4,38 +4,41 @@ namespace RZ\Roadiz\EntityGenerator\Field; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeGenerator; -use RZ\Roadiz\EntityGenerator\Attribute\AttributeListGenerator; +use Nette\PhpGenerator\ClassType; +use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\Property; -class YamlFieldGenerator extends NonVirtualFieldGenerator +final class YamlFieldGenerator extends NonVirtualFieldGenerator { - protected function getSerializationAttributes(): array + protected function addSerializationAttributes(Property|Method $property): self { - $annotations = parent::getSerializationAttributes(); + parent::addSerializationAttributes($property); if (!$this->excludeFromSerialization()) { - $annotations[] = new AttributeGenerator('Serializer\VirtualProperty'); - $annotations[] = new AttributeGenerator('Serializer\SerializedName', [ - AttributeGenerator::wrapString($this->field->getVarName()) + $property->addAttribute('JMS\Serializer\Annotation\VirtualProperty'); + $property->addAttribute('JMS\Serializer\Annotation\SerializedName', [ + $this->field->getVarName(), ]); - $annotations[] = new AttributeGenerator('SymfonySerializer\SerializedName', [ - 'serializedName' => AttributeGenerator::wrapString($this->field->getVarName()) + $property->addAttribute('Symfony\Component\Serializer\Attribute\SerializedName', [ + 'serializedName' => $this->field->getVarName(), ]); - $annotations[] = new AttributeGenerator('SymfonySerializer\Groups', [ - $this->getSerializationGroups() + $property->addAttribute('Symfony\Component\Serializer\Attribute\Groups', [ + $this->getSerializationGroups(), ]); if ($this->getSerializationMaxDepth() > 0) { - $annotations[] = new AttributeGenerator('SymfonySerializer\MaxDepth', [ - $this->getSerializationMaxDepth() + $property->addAttribute('Symfony\Component\Serializer\Attribute\MaxDepth', [ + $this->getSerializationMaxDepth(), ]); } } - return $annotations; + + return $this; } protected function getDefaultSerializationGroups(): array { $groups = parent::getDefaultSerializationGroups(); $groups[] = 'nodes_sources_yaml'; + return $groups; } @@ -44,23 +47,28 @@ protected function isExcludingFieldFromJmsSerialization(): bool return false; } - /** - * @return string - */ - public function getFieldAlternativeGetter(): string + protected function hasFieldAlternativeGetter(): bool { - $assignation = '$this->' . $this->field->getVarName(); - return ' - /** - * @return object|array|null - */ -' . (new AttributeListGenerator($this->getSerializationAttributes()))->generate(4) . ' - public function ' . $this->field->getGetterName() . 'AsObject() + return true; + } + + public function addFieldAlternativeGetter(ClassType $classType): self { - if (null !== ' . $assignation . ') { - return \Symfony\Component\Yaml\Yaml::parse(' . $assignation . '); - } - return null; - }' . PHP_EOL; + $assignation = '$this->'.$this->field->getVarName(); + + $method = $classType->addMethod($this->field->getGetterName().'AsObject') + ->setReturnType('object|array|null') + ->setVisibility('public') + ; + $this->addSerializationAttributes($method); + $method->setBody(<<configureOptions($resolver); - $this->nodeType = $nodeType; $this->options = $resolver->resolve($options); } public function getClassContent(): string { - return $this->getClassHeader() . PHP_EOL . - $this->getClassBody(); + $file = new PhpFile(); + $file->setStrictTypes(); + $file->addComment('THIS IS A GENERATED FILE, DO NOT EDIT IT.'); + $file->addComment('IT WILL BE RECREATED AT EACH NODE-TYPE UPDATE.'); + + $fqcn = $this->options['entity_namespace'].'\\'.$this->nodeType->getSourceEntityClassName(); + $namespace = $file + ->addNamespace(trim($this->options['namespace'], '\\')) + ->addUse('\Doctrine\Persistence\ManagerRegistry') + ->addUse('\RZ\Roadiz\CoreBundle\Preview\PreviewResolverInterface') + ->addUse('\Symfony\Contracts\EventDispatcher\EventDispatcherInterface') + ->addUse('\Symfony\Bundle\SecurityBundle\Security') + ->addUse('\RZ\Roadiz\CoreBundle\SearchEngine\NodeSourceSearchHandlerInterface') + ->addUse($this->options['parent_class']) + ->addUse($fqcn) + ; + + $class = $namespace + ->addClass($this->options['class_name']) + ->setFinal() + ->setExtends($this->options['parent_class']) + ; + + $simplifiedFqcn = $namespace->simplifyName($fqcn); + $class + ->addComment('@extends '.$namespace->simplifyName($this->options['parent_class']).'<'.$simplifiedFqcn.'>') + ->addComment('@method '.$simplifiedFqcn.'|null find($id, $lockMode = null, $lockVersion = null)') + ->addComment('@method '.$simplifiedFqcn.'|null findOneBy(array $criteria, array $orderBy = null)') + ->addComment('@method '.$simplifiedFqcn.'[] findAll()') + ->addComment('@method '.$simplifiedFqcn.'[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null)') + ; + + $constructor = $class->addMethod('__construct') + ->setBody( + 'parent::__construct($registry, $previewResolver, $dispatcher, $security, $nodeSourceSearchHandler, '.$simplifiedFqcn.'::class);' + ); + + $constructor->addParameter('registry') + ->setType('\Doctrine\Persistence\ManagerRegistry'); + $constructor->addParameter('previewResolver') + ->setType('\RZ\Roadiz\CoreBundle\Preview\PreviewResolverInterface'); + $constructor->addParameter('dispatcher') + ->setType('\Symfony\Contracts\EventDispatcher\EventDispatcherInterface'); + $constructor->addParameter('security') + ->setType('\Symfony\Bundle\SecurityBundle\Security'); + $constructor->addParameter('nodeSourceSearchHandler') + ->setType('?\RZ\Roadiz\CoreBundle\SearchEngine\NodeSourceSearchHandlerInterface'); + + return (new PsrPrinter())->printFile($file); } public function configureOptions(OptionsResolver $resolver): void @@ -44,75 +91,11 @@ public function configureOptions(OptionsResolver $resolver): void $normalizeClassName = function (OptionsResolver $resolver, string $className) { return (new UnicodeString($className))->startsWith('\\') ? $className : - '\\' . $className; + '\\'.$className; }; $resolver->setNormalizer('parent_class', $normalizeClassName); $resolver->setNormalizer('entity_namespace', $normalizeClassName); $resolver->setNormalizer('namespace', $normalizeClassName); } - - /** - * @return string - */ - protected function getClassBody(): string - { - return 'class ' . $this->options['class_name'] . ' extends ' . $this->options['parent_class'] . ' -{' . $this->getClassConstructor() . '}' . PHP_EOL; - } - - /** - * @return string - */ - protected function getClassHeader(): string - { - $fqcn = $this->options['entity_namespace'] . '\\' . $this->nodeType->getSourceEntityClassName(); - /* - * BE CAREFUL, USE statements are required for field generators which - * are using ::class syntax! - */ - return 'options['namespace'], '\\') . '; - -use Doctrine\Persistence\ManagerRegistry; -use RZ\Roadiz\CoreBundle\Preview\PreviewResolverInterface; -use RZ\Roadiz\CoreBundle\SearchEngine\NodeSourceSearchHandlerInterface; -use Symfony\Bundle\SecurityBundle\Security; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; - -/** - * @extends ' . $this->options['parent_class'] . '<' . $fqcn . '> - * - * @method ' . $fqcn . '|null find($id, $lockMode = null, $lockVersion = null) - * @method ' . $fqcn . '|null findOneBy(array $criteria, array $orderBy = null) - * @method ' . $fqcn . '[] findAll() - * @method ' . $fqcn . '[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) - */'; - } - - /** - * @return string - */ - protected function getClassConstructor(): string - { - return ' - public function __construct( - ManagerRegistry $registry, - PreviewResolverInterface $previewResolver, - EventDispatcherInterface $dispatcher, - Security $security, - ?NodeSourceSearchHandlerInterface $nodeSourceSearchHandler - ) { - parent::__construct($registry, $previewResolver, $dispatcher, $security, $nodeSourceSearchHandler); - - $this->_entityName = ' . $this->options['entity_namespace'] . '\\' . $this->nodeType->getSourceEntityClassName() . '::class; - }' . PHP_EOL; - } } diff --git a/tests/EntityGeneratorFactoryTest.php b/tests/EntityGeneratorFactoryTest.php index 82185bc..e77e6ee 100644 --- a/tests/EntityGeneratorFactoryTest.php +++ b/tests/EntityGeneratorFactoryTest.php @@ -37,7 +37,7 @@ public function testCreate(): void $generator = $this->getEntityGeneratorFactory(); $this->assertEquals( - file_get_contents(dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSources/NSMock.php'), + file_get_contents(dirname(__DIR__).'/tests/Mocks/GeneratedNodesSources/NSMock.php'), $generator->create($this->getMockNodeType())->getClassContent() ); } @@ -61,13 +61,13 @@ public function testCreateWithCustomRepository(): void /* * Uncomment for generating a mock file from tests */ -// file_put_contents( -// dirname(__DIR__) . '/../test/mocks/GeneratedNodesSourcesWithRepository/NSMock.php', -// $generator->createWithCustomRepository($this->getMockNodeType())->getClassContent() -// ); + // file_put_contents( + // dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php', + // $generator->createWithCustomRepository($this->getMockNodeType())->getClassContent() + // ); $this->assertEquals( - file_get_contents(dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php'), + file_get_contents(dirname(__DIR__).'/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php'), $generator->createWithCustomRepository($this->getMockNodeType())->getClassContent() ); } @@ -91,13 +91,13 @@ public function testCreateCustomRepository(): void /* * Uncomment for generating a mock file from tests */ -// file_put_contents( -// dirname(__DIR__) . '/../test/mocks/GeneratedNodesSourcesWithRepository/NSMockRepository.php', -// $generator->createCustomRepository($this->getMockNodeType())->getClassContent() -// ); + // file_put_contents( + // dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php', + // $generator->createCustomRepository($this->getMockNodeType())->getClassContent() + // ); $this->assertEquals( - file_get_contents(dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php'), + file_get_contents(dirname(__DIR__).'/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php'), $generator->createCustomRepository($this->getMockNodeType())->getClassContent() ); } diff --git a/tests/EntityGeneratorTest.php b/tests/EntityGeneratorTest.php index df91155..e49cbc2 100644 --- a/tests/EntityGeneratorTest.php +++ b/tests/EntityGeneratorTest.php @@ -42,18 +42,18 @@ public function testGetClassContent(): void /* * Uncomment for generating a mock file from tests */ -// file_put_contents( -// dirname(__DIR__) . '/../test/mocks/GeneratedNodesSources/NSMock.php', -// $dumpInstance->getClassContent() -// ); + // file_put_contents( + // dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSources/NSMock.php', + // $generator->getClassContent() + // ); $this->assertEquals( - file_get_contents(dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSources/NSMock.php'), + file_get_contents(dirname(__DIR__).'/tests/Mocks/GeneratedNodesSources/NSMock.php'), $generator->getClassContent() ); /** - * TEST without leading slashs + * TEST without leading slashs. */ $generatorWithoutLeadingSlashes = $this->getEntityGenerator($mockNodeType, [ 'parent_class' => 'mock\Entity\NodesSources', @@ -69,7 +69,7 @@ public function testGetClassContent(): void 'use_api_platform_filters' => true, ]); $this->assertEquals( - file_get_contents(dirname(__DIR__) . '/tests/Mocks/GeneratedNodesSources/NSMock.php'), + file_get_contents(dirname(__DIR__).'/tests/Mocks/GeneratedNodesSources/NSMock.php'), $generatorWithoutLeadingSlashes->getClassContent() ); } diff --git a/tests/Mocks/GeneratedNodesSources/NSMock.php b/tests/Mocks/GeneratedNodesSources/NSMock.php index 5b5e167..f851757 100644 --- a/tests/Mocks/GeneratedNodesSources/NSMock.php +++ b/tests/Mocks/GeneratedNodesSources/NSMock.php @@ -1,55 +1,439 @@ false])] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(1)] + #[JMS\Type('bool')] + private bool $boolIndexed = false; + + /** + * Foo markdown field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * allow_h2: false + * allow_h3: false + * allow_h4: false + * allow_h5: false + * allow_h6: false + * allow_bold: true + * allow_italic: true + * allow_blockquote: false + * allow_image: false + * allow_list: false + * allow_nbsp: true + * allow_nb_hyphen: true + * allow_return: true + * allow_link: false + * allow_hr: false + * allow_preview: true + */ + #[Serializer\SerializedName(serializedName: 'fooMarkdown')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Foo markdown field: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(1)] + #[Gedmo\Versioned] + #[ORM\Column(name: 'foo_markdown', type: 'text', nullable: true)] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(1)] + #[JMS\Type('string')] + private ?string $fooMarkdown = null; + + /** + * Foo excluded markdown field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * allow_h2: false + * allow_h3: false + * allow_h4: false + * allow_h5: false + * allow_h6: false + * allow_bold: true + * allow_italic: true + * allow_blockquote: false + * allow_image: false + * allow_list: false + * allow_nbsp: true + * allow_nb_hyphen: true + * allow_return: true + * allow_link: false + * allow_hr: false + * allow_preview: true + */ + #[Gedmo\Versioned] + #[ORM\Column(name: 'foo_markdown_excluded', type: 'text', nullable: true)] + #[JMS\Exclude] + #[Serializer\Ignore] + private ?string $fooMarkdownExcluded = null; + + /** + * Foo expression excluded decimal. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + */ + #[Serializer\SerializedName(serializedName: 'fooDecimalExcluded')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Foo expression excluded decimal: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + #[ApiFilter(Filter\OrderFilter::class)] + #[ApiFilter(Filter\NumericFilter::class)] + #[ApiFilter(Filter\RangeFilter::class)] + #[Gedmo\Versioned] + #[ORM\Column(name: 'foo_decimal_excluded', type: 'decimal', nullable: true, precision: 18, scale: 3)] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + #[JMS\Exclude(if: 'object.foo == \'test\'')] + #[JMS\Type('double')] + private int|float|null $fooDecimalExcluded = null; + + /** + * Référence à l'événement. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * # Entity class name + * classname: \App\Entity\Base\Event + * # Displayable is the method used to display entity name + * displayable: getName + * # Same as Displayable but for a secondary information + * alt_displayable: getSortingFirstDateTime + * # Same as Displayable but for a secondary information + * thumbnail: getMainDocument + * # Searchable entity fields + * searchable: + * - name + * - slug + * # This order will only be used for explorer + * orderBy: + * - field: sortingLastDateTime + * direction: DESC + */ + #[Serializer\SerializedName(serializedName: 'singleEventReference')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Référence à l\'événement: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToOne(targetEntity: \App\Entity\Base\Event::class)] + #[ORM\JoinColumn(name: 'single_event_reference_id', referencedColumnName: 'id', onDelete: 'SET NULL')] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private ?\App\Entity\Base\Event $singleEventReference = null; + + /** + * Remontée d'événements manuelle. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * # Entity class name + * classname: \App\Entity\Base\Event + * # Displayable is the method used to display entity name + * displayable: getName + * # Same as Displayable but for a secondary information + * alt_displayable: getSortingFirstDateTime + * # Same as Displayable but for a secondary information + * thumbnail: getMainDocument + * # Searchable entity fields + * searchable: + * - name + * - slug + * # This order will only be used for explorer + * orderBy: + * - field: sortingLastDateTime + * direction: DESC + * @var \Doctrine\Common\Collections\Collection + */ + #[Serializer\SerializedName(serializedName: 'eventReferences')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Remontée d\'événements manuelle: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class)] + #[ORM\JoinTable(name: 'node_type_event_references')] + #[ORM\JoinColumn(name: 'node_type_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'event_references_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\OrderBy(['sortingLastDateTime' => 'DESC'])] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private Collection $eventReferences; + + /** + * Buffer var to get referenced entities (documents, nodes, cforms, doctrine entities) + * Remontée d'événements manuelle. + * @var \Doctrine\Common\Collections\Collection + */ + #[JMS\Exclude] + #[Serializer\Ignore] + #[ORM\OneToMany( + targetEntity: \App\Entity\PositionedCity::class, + mappedBy: 'nodeSource', + orphanRemoval: true, + cascade: ['persist', 'remove'], + )] + #[ORM\OrderBy(['position' => 'ASC'])] + private Collection $eventReferencesProxiedProxy; + + /** + * Remontée d'événements manuelle exclue. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * # Entity class name + * classname: \App\Entity\Base\Event + * # Displayable is the method used to display entity name + * displayable: getName + * # Same as Displayable but for a secondary information + * alt_displayable: getSortingFirstDateTime + * # Same as Displayable but for a secondary information + * thumbnail: getMainDocument + * # Searchable entity fields + * searchable: + * - name + * - slug + * # This order will only be used for explorer + * orderBy: + * - field: sortingLastDateTime + * direction: DESC + * @var \Doctrine\Common\Collections\Collection + */ + #[ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class)] + #[ORM\JoinTable(name: 'node_type_event_references_excluded')] + #[ORM\JoinColumn(name: 'node_type_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'event_references_excluded_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\OrderBy(['sortingLastDateTime' => 'DESC'])] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Exclude] + #[Serializer\Ignore] + private Collection $eventReferencesExcluded; + + /** + * Bar documents field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * (Virtual field, this var is a buffer) + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'bar')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_documents'])] + #[ApiProperty(description: 'Bar documents field: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(1)] + private ?array $bar = null; + + /** + * Custom forms field. + * (Virtual field, this var is a buffer) + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'theForms')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_custom_forms'])] + #[ApiProperty(description: 'Custom forms field')] + #[Serializer\MaxDepth(2)] + private ?array $theForms = null; + + /** + * fooBarSources NodesSources direct field buffer. + * @var \mock\Entity\NodesSources[]|null + * ForBar nodes field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'fooBar')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[ApiProperty(description: 'ForBar nodes field: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + private ?array $fooBarSources = null; + + /** + * fooBarHiddenSources NodesSources direct field buffer. + * @var \mock\Entity\NodesSources[]|null + * ForBar hidden nodes field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + */ + #[JMS\Exclude] + private ?array $fooBarHiddenSources = null; + + /** + * fooBarTypedSources NodesSources direct field buffer. + * @var \tests\mocks\GeneratedNodesSources\NSMockTwo[]|null + * ForBar nodes typed field. + * Default values: + * MockTwo + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'fooBarTyped')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[ApiProperty(description: 'ForBar nodes typed field')] + #[Serializer\MaxDepth(2)] + private ?array $fooBarTypedSources = null; + + /** + * ForBar layout enum. + * Default values: + * layout_odd, layout_odd_big_title, layout_even, layout_even_big_title, layout_media_grid + */ + #[Serializer\SerializedName(serializedName: 'layout')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty( + description: 'ForBar layout enum', + schema: [ + 'type' => 'string', + 'enum' => ['layout_odd', 'layout_odd_big_title', 'layout_even', 'layout_even_big_title', 'layout_media_grid'], + 'example' => 'layout_odd', + ], + )] + #[Serializer\MaxDepth(2)] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[ApiFilter(\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class)] + #[Gedmo\Versioned] + #[ORM\Column(name: 'layout', type: 'string', nullable: true, length: 21)] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + #[JMS\Type('string')] + private ?string $layout = null; + + /** + * For many_to_one field. + * Default values: + * classname: \MyCustomEntity + * displayable: getName + */ + #[Serializer\SerializedName(serializedName: 'fooManyToOne')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'For many_to_one field')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToOne(targetEntity: \MyCustomEntity::class)] + #[ORM\JoinColumn(name: 'foo_many_to_one_id', referencedColumnName: 'id', onDelete: 'SET NULL')] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private ?\MyCustomEntity $fooManyToOne = null; + + /** + * For many_to_many field. + * Default values: + * classname: \MyCustomEntity + * displayable: getName + * orderBy: + * - field: name + * direction: asc + * @var \Doctrine\Common\Collections\Collection + */ + #[Serializer\SerializedName(serializedName: 'fooManyToMany')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'For many_to_many field')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToMany(targetEntity: \MyCustomEntity::class)] + #[ORM\JoinTable(name: 'node_type_foo_many_to_many')] + #[ORM\JoinColumn(name: 'node_type_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'foo_many_to_many_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\OrderBy(['name' => 'asc'])] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private Collection $fooManyToMany; + + /** + * Buffer var to get referenced entities (documents, nodes, cforms, doctrine entities) + * For many_to_many proxied field. + * @var \Doctrine\Common\Collections\Collection + */ + #[JMS\Exclude] + #[Serializer\Ignore] + #[ORM\OneToMany( + targetEntity: \Themes\MyTheme\Entities\PositionedCity::class, + mappedBy: 'nodeSource', + orphanRemoval: true, + cascade: ['persist', 'remove'], + )] + #[ORM\OrderBy(['position' => 'ASC'])] + private Collection $fooManyToManyProxiedProxy; /** * @return \DateTime|null @@ -60,40 +444,14 @@ public function getFooDatetime(): ?\DateTime } /** - * @param \DateTime|null $fooDatetime - * * @return $this */ public function setFooDatetime(?\DateTime $fooDatetime): static { $this->fooDatetime = $fooDatetime; - return $this; } - - /** - * Foo field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "foo"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - Gedmo\Versioned, - ORM\Column( - name: "foo", - type: "string", - nullable: true, - length: 250 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("string") - ] - private ?string $foo = null; - /** * @return string|null */ @@ -103,44 +461,16 @@ public function getFoo(): ?string } /** - * @param string|null $foo - * * @return $this */ public function setFoo(?string $foo): static { $this->foo = null !== $foo ? - (string) $foo : - null; - + (string) $foo : + null; return $this; } - - /** - * Foo indexed field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooIndexed"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo indexed field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "partial"), - ApiFilter(\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "fooIndexed", - type: "string", - nullable: true, - length: 250 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("string") - ] - private ?string $fooIndexed = null; - /** * @return string|null */ @@ -150,44 +480,16 @@ public function getFooIndexed(): ?string } /** - * @param string|null $fooIndexed - * * @return $this */ public function setFooIndexed(?string $fooIndexed): static { $this->fooIndexed = null !== $fooIndexed ? - (string) $fooIndexed : - null; - + (string) $fooIndexed : + null; return $this; } - - /** - * Bool indexed field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "boolIndexed"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Bool indexed field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - ApiFilter(OrmFilter\OrderFilter::class), - ApiFilter(OrmFilter\BooleanFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "boolIndexed", - type: "boolean", - nullable: false, - options: ["default" => false] - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("bool") - ] - private bool $boolIndexed = false; - /** * @return bool */ @@ -197,51 +499,14 @@ public function getBoolIndexed(): bool } /** - * @param bool $boolIndexed - * * @return $this */ public function setBoolIndexed(bool $boolIndexed): static { $this->boolIndexed = $boolIndexed; - return $this; } - - /** - * Foo markdown field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: allow_h2: false - * allow_h3: false - * allow_h4: false - * allow_h5: false - * allow_h6: false - * allow_bold: true - * allow_italic: true - * allow_blockquote: false - * allow_image: false - * allow_list: false - * allow_nbsp: true - * allow_nb_hyphen: true - * allow_return: true - * allow_link: false - * allow_hr: false - * allow_preview: true - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooMarkdown"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo markdown field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - Gedmo\Versioned, - ORM\Column(name: "foo_markdown", type: "text", nullable: true), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("string") - ] - private ?string $fooMarkdown = null; - /** * @return string|null */ @@ -251,48 +516,16 @@ public function getFooMarkdown(): ?string } /** - * @param string|null $fooMarkdown - * * @return $this */ public function setFooMarkdown(?string $fooMarkdown): static { $this->fooMarkdown = null !== $fooMarkdown ? - (string) $fooMarkdown : - null; - + (string) $fooMarkdown : + null; return $this; } - - /** - * Foo excluded markdown field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: allow_h2: false - * allow_h3: false - * allow_h4: false - * allow_h5: false - * allow_h6: false - * allow_bold: true - * allow_italic: true - * allow_blockquote: false - * allow_image: false - * allow_list: false - * allow_nbsp: true - * allow_nb_hyphen: true - * allow_return: true - * allow_link: false - * allow_hr: false - * allow_preview: true - */ - #[ - Gedmo\Versioned, - ORM\Column(name: "foo_markdown_excluded", type: "text", nullable: true), - Serializer\Exclude, - SymfonySerializer\Ignore - ] - private ?string $fooMarkdownExcluded = null; - /** * @return string|null */ @@ -302,47 +535,16 @@ public function getFooMarkdownExcluded(): ?string } /** - * @param string|null $fooMarkdownExcluded - * * @return $this */ public function setFooMarkdownExcluded(?string $fooMarkdownExcluded): static { $this->fooMarkdownExcluded = null !== $fooMarkdownExcluded ? - (string) $fooMarkdownExcluded : - null; - + (string) $fooMarkdownExcluded : + null; return $this; } - - /** - * Foo expression excluded decimal. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooDecimalExcluded"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo expression excluded decimal: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2), - ApiFilter(OrmFilter\OrderFilter::class), - ApiFilter(OrmFilter\NumericFilter::class), - ApiFilter(OrmFilter\RangeFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "foo_decimal_excluded", - type: "decimal", - nullable: true, - precision: 18, - scale: 3 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2), - Serializer\Exclude(if: "object.foo == 'test'"), - Serializer\Type("double") - ] - private int|float|null $fooDecimalExcluded = null; - /** * @return int|float|null */ @@ -352,109 +554,28 @@ public function getFooDecimalExcluded(): int|float|null } /** - * @param int|float|null $fooDecimalExcluded - * * @return $this */ public function setFooDecimalExcluded(int|float|null $fooDecimalExcluded): static { $this->fooDecimalExcluded = $fooDecimalExcluded; - return $this; } - - /** - * Référence à l'événement. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: # Entity class name - * classname: \App\Entity\Base\Event - * # Displayable is the method used to display entity name - * displayable: getName - * # Same as Displayable but for a secondary information - * alt_displayable: getSortingFirstDateTime - * # Same as Displayable but for a secondary information - * thumbnail: getMainDocument - * # Searchable entity fields - * searchable: - * - name - * - slug - * # This order will only be used for explorer - * orderBy: - * - field: sortingLastDateTime - * direction: DESC - * @var \App\Entity\Base\Event|null - */ - #[ - SymfonySerializer\SerializedName(serializedName: "singleEventReference"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Référence à l'événement: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToOne(targetEntity: \App\Entity\Base\Event::class), - ORM\JoinColumn(name: "single_event_reference_id", referencedColumnName: "id", onDelete: "SET NULL"), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private ?\App\Entity\Base\Event $singleEventReference = null; - - /** - * @return \App\Entity\Base\Event|null - */ public function getSingleEventReference(): ?\App\Entity\Base\Event { return $this->singleEventReference; } /** - * @param \App\Entity\Base\Event|null $singleEventReference * @return $this */ - public function setSingleEventReference(?\App\Entity\Base\Event $singleEventReference = null): static + public function setSingleEventReference(?\App\Entity\Base\Event $singleEventReference): static { $this->singleEventReference = $singleEventReference; - return $this; } - - /** - * Remontée d'événements manuelle. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: # Entity class name - * classname: \App\Entity\Base\Event - * # Displayable is the method used to display entity name - * displayable: getName - * # Same as Displayable but for a secondary information - * alt_displayable: getSortingFirstDateTime - * # Same as Displayable but for a secondary information - * thumbnail: getMainDocument - * # Searchable entity fields - * searchable: - * - name - * - slug - * # This order will only be used for explorer - * orderBy: - * - field: sortingLastDateTime - * direction: DESC - * @var Collection - */ - #[ - SymfonySerializer\SerializedName(serializedName: "eventReferences"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Remontée d'événements manuelle: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class), - ORM\JoinTable(name: "node_type_event_references"), - ORM\JoinColumn(name: "node_type_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\InverseJoinColumn(name: "event_references_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\OrderBy(["sortingLastDateTime" => "DESC"]), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private Collection $eventReferences; - /** * @return Collection */ @@ -464,7 +585,7 @@ public function getEventReferences(): Collection } /** - * @param Collection|\App\Entity\Base\Event[] $eventReferences + * @param \Doctrine\Common\Collections\Collection|array<\App\Entity\Base\Event> $eventReferences * @return $this */ public function setEventReferences(Collection|array $eventReferences): static @@ -474,29 +595,9 @@ public function setEventReferences(Collection|array $eventReferences): static } else { $this->eventReferences = new \Doctrine\Common\Collections\ArrayCollection($eventReferences); } - return $this; } - - /** - * Remontée d'événements manuelle - * - * @var Collection - */ - #[ - Serializer\Exclude, - SymfonySerializer\Ignore, - ORM\OneToMany( - targetEntity: \App\Entity\PositionedCity::class, - mappedBy: "nodeSource", - orphanRemoval: true, - cascade: ["persist", "remove"] - ), - ORM\OrderBy(["position" => "ASC"]) - ] - private Collection $eventReferencesProxiedProxy; - /** * @return Collection */ @@ -505,41 +606,34 @@ public function getEventReferencesProxiedProxy(): Collection return $this->eventReferencesProxiedProxy; } - /** - * @return Collection - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("eventReferencesProxied"), - SymfonySerializer\SerializedName(serializedName: "eventReferencesProxied"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\MaxDepth(2) - ] - public function getEventReferencesProxied(): Collection + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('eventReferencesProxied')] + #[Serializer\SerializedName(serializedName: 'eventReferencesProxied')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[Serializer\MaxDepth(2)] + public function getEventReferencesProxied(): array { return $this->eventReferencesProxiedProxy->map(function (\App\Entity\PositionedCity $proxyEntity) { return $proxyEntity->getCity(); - }); + })->getValues(); } /** - * @param Collection $eventReferencesProxiedProxy - * @Serializer\VirtualProperty() + * @param \Doctrine\Common\Collections\Collection $eventReferencesProxiedProxy * @return $this */ public function setEventReferencesProxiedProxy(Collection $eventReferencesProxiedProxy): static { $this->eventReferencesProxiedProxy = $eventReferencesProxiedProxy; - return $this; } + /** - * @param Collection|array|null $eventReferencesProxied * @return $this */ - public function setEventReferencesProxied(Collection|array|null $eventReferencesProxied = null): static + public function setEventReferencesProxied(Collection|array|null $eventReferencesProxied): static { foreach ($this->getEventReferencesProxiedProxy() as $item) { $item->setNodeSource(null); @@ -562,40 +656,6 @@ public function setEventReferencesProxied(Collection|array|null $eventReferences return $this; } - - /** - * Remontée d'événements manuelle exclue. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: # Entity class name - * classname: \App\Entity\Base\Event - * # Displayable is the method used to display entity name - * displayable: getName - * # Same as Displayable but for a secondary information - * alt_displayable: getSortingFirstDateTime - * # Same as Displayable but for a secondary information - * thumbnail: getMainDocument - * # Searchable entity fields - * searchable: - * - name - * - slug - * # This order will only be used for explorer - * orderBy: - * - field: sortingLastDateTime - * direction: DESC - * @var Collection - */ - #[ - ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class), - ORM\JoinTable(name: "node_type_event_references_excluded"), - ORM\JoinColumn(name: "node_type_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\InverseJoinColumn(name: "event_references_excluded_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\OrderBy(["sortingLastDateTime" => "DESC"]), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Exclude, - SymfonySerializer\Ignore - ] - private Collection $eventReferencesExcluded; - /** * @return Collection */ @@ -605,7 +665,7 @@ public function getEventReferencesExcluded(): Collection } /** - * @param Collection|\App\Entity\Base\Event[] $eventReferencesExcluded + * @param \Doctrine\Common\Collections\Collection|array<\App\Entity\Base\Event> $eventReferencesExcluded * @return $this */ public function setEventReferencesExcluded(Collection|array $eventReferencesExcluded): static @@ -615,36 +675,17 @@ public function setEventReferencesExcluded(Collection|array $eventReferencesExcl } else { $this->eventReferencesExcluded = new \Doctrine\Common\Collections\ArrayCollection($eventReferencesExcluded); } - return $this; } - - /** - * Bar documents field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * - * (Virtual field, this var is a buffer) - */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "bar"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_documents"]), - \ApiPlatform\Metadata\ApiProperty(description: "Bar documents field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1) - ] - private ?array $bar = null; - /** - * @return \mock\Entity\Document[] Documents array + * @return \mock\Entity\Document[] */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_documents"]), - Serializer\MaxDepth(1), - Serializer\VirtualProperty, - Serializer\SerializedName("bar"), - Serializer\Type("array") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_documents'])] + #[JMS\MaxDepth(1)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('bar')] + #[JMS\Type('array')] public function getBar(): array { if (null === $this->bar) { @@ -663,51 +704,33 @@ public function getBar(): array } /** - * @param \mock\Entity\Document $document - * * @return $this */ public function addBar(\mock\Entity\Document $document): static { - if (null !== $this->objectManager) { - $nodeSourceDocument = new \mock\Entity\NodesSourcesDocument( - $this, - $document - ); - $nodeSourceDocument->setFieldName('bar'); - if (!$this->hasNodesSourcesDocuments($nodeSourceDocument)) { - $this->objectManager->persist($nodeSourceDocument); - $this->addDocumentsByFields($nodeSourceDocument); - $this->bar = null; - } + if (null === $this->objectManager) { + return $this; + } + $nodeSourceDocument = new \mock\Entity\NodesSourcesDocument( + $this, + $document + ); + $nodeSourceDocument->setFieldName('bar'); + if (!$this->hasNodesSourcesDocuments($nodeSourceDocument)) { + $this->objectManager->persist($nodeSourceDocument); + $this->addDocumentsByFields($nodeSourceDocument); + $this->bar = null; } return $this; } - - /** - * Custom forms field. - * - * (Virtual field, this var is a buffer) - */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "theForms"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_custom_forms"]), - \ApiPlatform\Metadata\ApiProperty(description: "Custom forms field"), - SymfonySerializer\MaxDepth(2) - ] - private ?array $theForms = null; - /** * @return \mock\Entity\CustomForm[] CustomForm array */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_custom_forms"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("theForms") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_custom_forms'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('theForms')] public function getTheForms(): array { if (null === $this->theForms) { @@ -726,8 +749,6 @@ public function getTheForms(): array } /** - * @param \mock\Entity\CustomForm $customForm - * * @return $this */ public function addTheForms(\mock\Entity\CustomForm $customForm): static @@ -745,34 +766,14 @@ public function addTheForms(\mock\Entity\CustomForm $customForm): static return $this; } - /** - * fooBarSources NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - * - * ForBar nodes field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * @var \mock\Entity\NodesSources[]|null + * @return \mock\Entity\NodesSources[] */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "fooBar"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - \ApiPlatform\Metadata\ApiProperty(description: "ForBar nodes field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2) - ] - private ?array $fooBarSources = null; - - /** - * @return \mock\Entity\NodesSources[] fooBar nodes-sources array - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("fooBar"), - Serializer\Type("array") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooBar')] + #[JMS\Type('array')] public function getFooBarSources(): array { if (null === $this->fooBarSources) { @@ -792,38 +793,22 @@ public function getFooBarSources(): array /** * @param \mock\Entity\NodesSources[]|null $fooBarSources - * * @return $this */ public function setFooBarSources(?array $fooBarSources): static { $this->fooBarSources = $fooBarSources; - return $this; } - - /** - * fooBarHiddenSources NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - * - * ForBar hidden nodes field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * @var \mock\Entity\NodesSources[]|null - */ - #[Serializer\Exclude] - private ?array $fooBarHiddenSources = null; - /** - * @return \mock\Entity\NodesSources[] fooBarHidden nodes-sources array + * @return \mock\Entity\NodesSources[] */ - #[ - Serializer\Exclude, - SymfonySerializer\Ignore, - Serializer\VirtualProperty, - Serializer\SerializedName("fooBarHidden"), - Serializer\Type("array") - ] + #[JMS\Exclude] + #[Serializer\Ignore] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooBarHidden')] + #[JMS\Type('array')] public function getFooBarHiddenSources(): array { if (null === $this->fooBarHiddenSources) { @@ -843,44 +828,22 @@ public function getFooBarHiddenSources(): array /** * @param \mock\Entity\NodesSources[]|null $fooBarHiddenSources - * * @return $this */ public function setFooBarHiddenSources(?array $fooBarHiddenSources): static { $this->fooBarHiddenSources = $fooBarHiddenSources; - return $this; } - /** - * fooBarTypedSources NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - * - * ForBar nodes typed field. - * Default values: MockTwo - * @var \tests\mocks\GeneratedNodesSources\NSMockTwo[]|null + * @return \tests\mocks\GeneratedNodesSources\NSMockTwo[] */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "fooBarTyped"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - \ApiPlatform\Metadata\ApiProperty(description: "ForBar nodes typed field"), - SymfonySerializer\MaxDepth(2) - ] - private ?array $fooBarTypedSources = null; - - /** - * @return \tests\mocks\GeneratedNodesSources\NSMockTwo[] fooBarTyped nodes-sources array - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("fooBarTyped"), - Serializer\Type("array") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooBarTyped')] + #[JMS\Type('array')] public function getFooBarTypedSources(): array { if (null === $this->fooBarTypedSources) { @@ -900,41 +863,14 @@ public function getFooBarTypedSources(): array /** * @param \tests\mocks\GeneratedNodesSources\NSMockTwo[]|null $fooBarTypedSources - * * @return $this */ public function setFooBarTypedSources(?array $fooBarTypedSources): static { $this->fooBarTypedSources = $fooBarTypedSources; - return $this; } - - /** - * ForBar layout enum. - * Default values: light, dark, transparent - */ - #[ - SymfonySerializer\SerializedName(serializedName: "layout"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "ForBar layout enum", schema: ["type" => "string", "enum" => ["light","dark","transparent"], "example" => "light"]), - SymfonySerializer\MaxDepth(2), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - ApiFilter(\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "layout", - type: "string", - nullable: true, - length: 11 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2), - Serializer\Type("string") - ] - private ?string $layout = null; - /** * @return string|null */ @@ -944,84 +880,30 @@ public function getLayout(): ?string } /** - * @param string|null $layout - * * @return $this */ public function setLayout(?string $layout): static { $this->layout = null !== $layout ? - (string) $layout : - null; - + (string) $layout : + null; return $this; } - - /** - * For many_to_one field. - * Default values: classname: \MyCustomEntity - * displayable: getName - * @var \MyCustomEntity|null - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooManyToOne"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "For many_to_one field"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToOne(targetEntity: \MyCustomEntity::class), - ORM\JoinColumn(name: "foo_many_to_one_id", referencedColumnName: "id", onDelete: "SET NULL"), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private ?\MyCustomEntity $fooManyToOne = null; - - /** - * @return \MyCustomEntity|null - */ public function getFooManyToOne(): ?\MyCustomEntity { return $this->fooManyToOne; } /** - * @param \MyCustomEntity|null $fooManyToOne * @return $this */ - public function setFooManyToOne(?\MyCustomEntity $fooManyToOne = null): static + public function setFooManyToOne(?\MyCustomEntity $fooManyToOne): static { $this->fooManyToOne = $fooManyToOne; - return $this; } - - /** - * For many_to_many field. - * Default values: classname: \MyCustomEntity - * displayable: getName - * orderBy: - * - field: name - * direction: asc - * @var Collection - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooManyToMany"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "For many_to_many field"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToMany(targetEntity: \MyCustomEntity::class), - ORM\JoinTable(name: "node_type_foo_many_to_many"), - ORM\JoinColumn(name: "node_type_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\InverseJoinColumn(name: "foo_many_to_many_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\OrderBy(["name" => "asc"]), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private Collection $fooManyToMany; - /** * @return Collection */ @@ -1031,7 +913,7 @@ public function getFooManyToMany(): Collection } /** - * @param Collection|\MyCustomEntity[] $fooManyToMany + * @param \Doctrine\Common\Collections\Collection|array<\MyCustomEntity> $fooManyToMany * @return $this */ public function setFooManyToMany(Collection|array $fooManyToMany): static @@ -1041,29 +923,9 @@ public function setFooManyToMany(Collection|array $fooManyToMany): static } else { $this->fooManyToMany = new \Doctrine\Common\Collections\ArrayCollection($fooManyToMany); } - return $this; } - - /** - * For many_to_many proxied field - * - * @var Collection - */ - #[ - Serializer\Exclude, - SymfonySerializer\Ignore, - ORM\OneToMany( - targetEntity: \Themes\MyTheme\Entities\PositionedCity::class, - mappedBy: "nodeSource", - orphanRemoval: true, - cascade: ["persist", "remove"] - ), - ORM\OrderBy(["position" => "ASC"]) - ] - private Collection $fooManyToManyProxiedProxy; - /** * @return Collection */ @@ -1072,41 +934,34 @@ public function getFooManyToManyProxiedProxy(): Collection return $this->fooManyToManyProxiedProxy; } - /** - * @return Collection - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\VirtualProperty, - Serializer\SerializedName("fooManyToManyProxied"), - SymfonySerializer\SerializedName(serializedName: "fooManyToManyProxied"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\MaxDepth(1) - ] - public function getFooManyToManyProxied(): Collection + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(1)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooManyToManyProxied')] + #[Serializer\SerializedName(serializedName: 'fooManyToManyProxied')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[Serializer\MaxDepth(1)] + public function getFooManyToManyProxied(): array { return $this->fooManyToManyProxiedProxy->map(function (\Themes\MyTheme\Entities\PositionedCity $proxyEntity) { return $proxyEntity->getCity(); - }); + })->getValues(); } /** - * @param Collection $fooManyToManyProxiedProxy - * @Serializer\VirtualProperty() + * @param \Doctrine\Common\Collections\Collection $fooManyToManyProxiedProxy * @return $this */ public function setFooManyToManyProxiedProxy(Collection $fooManyToManyProxiedProxy): static { $this->fooManyToManyProxiedProxy = $fooManyToManyProxiedProxy; - return $this; } + /** - * @param Collection|array|null $fooManyToManyProxied * @return $this */ - public function setFooManyToManyProxied(Collection|array|null $fooManyToManyProxied = null): static + public function setFooManyToManyProxied(Collection|array|null $fooManyToManyProxied): static { foreach ($this->getFooManyToManyProxiedProxy() as $item) { $item->setNodeSource(null); @@ -1129,11 +984,9 @@ public function setFooManyToManyProxied(Collection|array|null $fooManyToManyProx return $this; } - public function __construct(\mock\Entity\Node $node, \mock\Entity\Translation $translation) { parent::__construct($node, $translation); - $this->eventReferences = new \Doctrine\Common\Collections\ArrayCollection(); $this->eventReferencesProxiedProxy = new \Doctrine\Common\Collections\ArrayCollection(); $this->eventReferencesExcluded = new \Doctrine\Common\Collections\ArrayCollection(); @@ -1141,13 +994,34 @@ public function __construct(\mock\Entity\Node $node, \mock\Entity\Translation $t $this->fooManyToManyProxiedProxy = new \Doctrine\Common\Collections\ArrayCollection(); } - #[ - Serializer\VirtualProperty, - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\SerializedName("@type"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\SerializedName(serializedName: "@type") - ] + public function __clone(): void + { + parent::__clone(); + + $eventReferencesProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); + foreach ($this->eventReferencesProxiedProxy as $item) { + $itemClone = clone $item; + $itemClone->setNodeSource($this); + $eventReferencesProxiedProxyClone->add($itemClone); + $this->objectManager->persist($itemClone); + } + $this->eventReferencesProxiedProxy = $eventReferencesProxiedProxyClone; + + $fooManyToManyProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); + foreach ($this->fooManyToManyProxiedProxy as $item) { + $itemClone = clone $item; + $itemClone->setNodeSource($this); + $fooManyToManyProxiedProxyClone->add($itemClone); + $this->objectManager->persist($itemClone); + } + $this->fooManyToManyProxiedProxy = $fooManyToManyProxiedProxyClone; + } + + #[JMS\VirtualProperty] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\SerializedName('@type')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[Serializer\SerializedName(serializedName: '@type')] public function getNodeTypeName(): string { return 'Mock'; @@ -1155,9 +1029,9 @@ public function getNodeTypeName(): string /** * $this->nodeType->isReachable() proxy. - * * @return bool Does this nodeSource is reachable over network? */ + #[JMS\VirtualProperty] public function isReachable(): bool { return true; @@ -1165,37 +1039,14 @@ public function isReachable(): bool /** * $this->nodeType->isPublishable() proxy. - * * @return bool Does this nodeSource is publishable with date and time? */ + #[JMS\VirtualProperty] public function isPublishable(): bool { return true; } - public function __clone() - { - parent::__clone(); - - $eventReferencesProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); - foreach ($this->eventReferencesProxiedProxy as $item) { - $itemClone = clone $item; - $itemClone->setNodeSource($this); - $eventReferencesProxiedProxyClone->add($itemClone); - $this->objectManager->persist($itemClone); - } - $this->eventReferencesProxiedProxy = $eventReferencesProxiedProxyClone; - - $fooManyToManyProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); - foreach ($this->fooManyToManyProxiedProxy as $item) { - $itemClone = clone $item; - $itemClone->setNodeSource($this); - $fooManyToManyProxiedProxyClone->add($itemClone); - $this->objectManager->persist($itemClone); - } - $this->fooManyToManyProxiedProxy = $fooManyToManyProxiedProxyClone; - } - public function __toString(): string { return '[NSMock] ' . parent::__toString(); diff --git a/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php b/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php index e91fb63..94dbfba 100644 --- a/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php +++ b/tests/Mocks/GeneratedNodesSourcesWithRepository/NSMock.php @@ -1,55 +1,439 @@ false])] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(1)] + #[JMS\Type('bool')] + private bool $boolIndexed = false; + + /** + * Foo markdown field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * allow_h2: false + * allow_h3: false + * allow_h4: false + * allow_h5: false + * allow_h6: false + * allow_bold: true + * allow_italic: true + * allow_blockquote: false + * allow_image: false + * allow_list: false + * allow_nbsp: true + * allow_nb_hyphen: true + * allow_return: true + * allow_link: false + * allow_hr: false + * allow_preview: true + */ + #[Serializer\SerializedName(serializedName: 'fooMarkdown')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Foo markdown field: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(1)] + #[Gedmo\Versioned] + #[ORM\Column(name: 'foo_markdown', type: 'text', nullable: true)] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(1)] + #[JMS\Type('string')] + private ?string $fooMarkdown = null; + + /** + * Foo excluded markdown field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * allow_h2: false + * allow_h3: false + * allow_h4: false + * allow_h5: false + * allow_h6: false + * allow_bold: true + * allow_italic: true + * allow_blockquote: false + * allow_image: false + * allow_list: false + * allow_nbsp: true + * allow_nb_hyphen: true + * allow_return: true + * allow_link: false + * allow_hr: false + * allow_preview: true + */ + #[Gedmo\Versioned] + #[ORM\Column(name: 'foo_markdown_excluded', type: 'text', nullable: true)] + #[JMS\Exclude] + #[Serializer\Ignore] + private ?string $fooMarkdownExcluded = null; + + /** + * Foo expression excluded decimal. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + */ + #[Serializer\SerializedName(serializedName: 'fooDecimalExcluded')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Foo expression excluded decimal: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + #[ApiFilter(Filter\OrderFilter::class)] + #[ApiFilter(Filter\NumericFilter::class)] + #[ApiFilter(Filter\RangeFilter::class)] + #[Gedmo\Versioned] + #[ORM\Column(name: 'foo_decimal_excluded', type: 'decimal', nullable: true, precision: 18, scale: 3)] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + #[JMS\Exclude(if: 'object.foo == \'test\'')] + #[JMS\Type('double')] + private int|float|null $fooDecimalExcluded = null; + + /** + * Référence à l'événement. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * # Entity class name + * classname: \App\Entity\Base\Event + * # Displayable is the method used to display entity name + * displayable: getName + * # Same as Displayable but for a secondary information + * alt_displayable: getSortingFirstDateTime + * # Same as Displayable but for a secondary information + * thumbnail: getMainDocument + * # Searchable entity fields + * searchable: + * - name + * - slug + * # This order will only be used for explorer + * orderBy: + * - field: sortingLastDateTime + * direction: DESC + */ + #[Serializer\SerializedName(serializedName: 'singleEventReference')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Référence à l\'événement: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToOne(targetEntity: \App\Entity\Base\Event::class)] + #[ORM\JoinColumn(name: 'single_event_reference_id', referencedColumnName: 'id', onDelete: 'SET NULL')] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private ?\App\Entity\Base\Event $singleEventReference = null; + + /** + * Remontée d'événements manuelle. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * # Entity class name + * classname: \App\Entity\Base\Event + * # Displayable is the method used to display entity name + * displayable: getName + * # Same as Displayable but for a secondary information + * alt_displayable: getSortingFirstDateTime + * # Same as Displayable but for a secondary information + * thumbnail: getMainDocument + * # Searchable entity fields + * searchable: + * - name + * - slug + * # This order will only be used for explorer + * orderBy: + * - field: sortingLastDateTime + * direction: DESC + * @var \Doctrine\Common\Collections\Collection + */ + #[Serializer\SerializedName(serializedName: 'eventReferences')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'Remontée d\'événements manuelle: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class)] + #[ORM\JoinTable(name: 'node_type_event_references')] + #[ORM\JoinColumn(name: 'node_type_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'event_references_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\OrderBy(['sortingLastDateTime' => 'DESC'])] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private Collection $eventReferences; + + /** + * Buffer var to get referenced entities (documents, nodes, cforms, doctrine entities) + * Remontée d'événements manuelle. + * @var \Doctrine\Common\Collections\Collection + */ + #[JMS\Exclude] + #[Serializer\Ignore] + #[ORM\OneToMany( + targetEntity: \App\Entity\PositionedCity::class, + mappedBy: 'nodeSource', + orphanRemoval: true, + cascade: ['persist', 'remove'], + )] + #[ORM\OrderBy(['position' => 'ASC'])] + private Collection $eventReferencesProxiedProxy; + + /** + * Remontée d'événements manuelle exclue. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * Default values: + * # Entity class name + * classname: \App\Entity\Base\Event + * # Displayable is the method used to display entity name + * displayable: getName + * # Same as Displayable but for a secondary information + * alt_displayable: getSortingFirstDateTime + * # Same as Displayable but for a secondary information + * thumbnail: getMainDocument + * # Searchable entity fields + * searchable: + * - name + * - slug + * # This order will only be used for explorer + * orderBy: + * - field: sortingLastDateTime + * direction: DESC + * @var \Doctrine\Common\Collections\Collection + */ + #[ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class)] + #[ORM\JoinTable(name: 'node_type_event_references_excluded')] + #[ORM\JoinColumn(name: 'node_type_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'event_references_excluded_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\OrderBy(['sortingLastDateTime' => 'DESC'])] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Exclude] + #[Serializer\Ignore] + private Collection $eventReferencesExcluded; + + /** + * Bar documents field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + * (Virtual field, this var is a buffer) + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'bar')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_documents'])] + #[ApiProperty(description: 'Bar documents field: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(1)] + private ?array $bar = null; + + /** + * Custom forms field. + * (Virtual field, this var is a buffer) + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'theForms')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_custom_forms'])] + #[ApiProperty(description: 'Custom forms field')] + #[Serializer\MaxDepth(2)] + private ?array $theForms = null; + + /** + * fooBarSources NodesSources direct field buffer. + * @var \mock\Entity\NodesSources[]|null + * ForBar nodes field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'fooBar')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[ApiProperty(description: 'ForBar nodes field: Maecenas sed diam eget risus varius blandit sit amet non magna')] + #[Serializer\MaxDepth(2)] + private ?array $fooBarSources = null; + + /** + * fooBarHiddenSources NodesSources direct field buffer. + * @var \mock\Entity\NodesSources[]|null + * ForBar hidden nodes field. + * Maecenas sed diam eget risus varius blandit sit amet non magna. + */ + #[JMS\Exclude] + private ?array $fooBarHiddenSources = null; + + /** + * fooBarTypedSources NodesSources direct field buffer. + * @var \tests\mocks\GeneratedNodesSources\NSMockTwo[]|null + * ForBar nodes typed field. + * Default values: + * MockTwo + */ + #[JMS\Exclude] + #[Serializer\SerializedName(serializedName: 'fooBarTyped')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[ApiProperty(description: 'ForBar nodes typed field')] + #[Serializer\MaxDepth(2)] + private ?array $fooBarTypedSources = null; + + /** + * ForBar layout enum. + * Default values: + * layout_odd, layout_odd_big_title, layout_even, layout_even_big_title, layout_media_grid + */ + #[Serializer\SerializedName(serializedName: 'layout')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty( + description: 'ForBar layout enum', + schema: [ + 'type' => 'string', + 'enum' => ['layout_odd', 'layout_odd_big_title', 'layout_even', 'layout_even_big_title', 'layout_media_grid'], + 'example' => 'layout_odd', + ], + )] + #[Serializer\MaxDepth(2)] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[ApiFilter(\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class)] + #[Gedmo\Versioned] + #[ORM\Column(name: 'layout', type: 'string', nullable: true, length: 21)] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + #[JMS\Type('string')] + private ?string $layout = null; + + /** + * For many_to_one field. + * Default values: + * classname: \MyCustomEntity + * displayable: getName + */ + #[Serializer\SerializedName(serializedName: 'fooManyToOne')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'For many_to_one field')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToOne(targetEntity: \MyCustomEntity::class)] + #[ORM\JoinColumn(name: 'foo_many_to_one_id', referencedColumnName: 'id', onDelete: 'SET NULL')] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private ?\MyCustomEntity $fooManyToOne = null; + + /** + * For many_to_many field. + * Default values: + * classname: \MyCustomEntity + * displayable: getName + * orderBy: + * - field: name + * direction: asc + * @var \Doctrine\Common\Collections\Collection + */ + #[Serializer\SerializedName(serializedName: 'fooManyToMany')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[ApiProperty(description: 'For many_to_many field')] + #[Serializer\MaxDepth(2)] + #[ORM\ManyToMany(targetEntity: \MyCustomEntity::class)] + #[ORM\JoinTable(name: 'node_type_foo_many_to_many')] + #[ORM\JoinColumn(name: 'node_type_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\InverseJoinColumn(name: 'foo_many_to_many_id', referencedColumnName: 'id', onDelete: 'CASCADE')] + #[ORM\OrderBy(['name' => 'asc'])] + #[ApiFilter(Filter\SearchFilter::class, strategy: 'exact')] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + private Collection $fooManyToMany; + + /** + * Buffer var to get referenced entities (documents, nodes, cforms, doctrine entities) + * For many_to_many proxied field. + * @var \Doctrine\Common\Collections\Collection + */ + #[JMS\Exclude] + #[Serializer\Ignore] + #[ORM\OneToMany( + targetEntity: \Themes\MyTheme\Entities\PositionedCity::class, + mappedBy: 'nodeSource', + orphanRemoval: true, + cascade: ['persist', 'remove'], + )] + #[ORM\OrderBy(['position' => 'ASC'])] + private Collection $fooManyToManyProxiedProxy; /** * @return \DateTime|null @@ -60,40 +444,14 @@ public function getFooDatetime(): ?\DateTime } /** - * @param \DateTime|null $fooDatetime - * * @return $this */ public function setFooDatetime(?\DateTime $fooDatetime): static { $this->fooDatetime = $fooDatetime; - return $this; } - - /** - * Foo field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "foo"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - Gedmo\Versioned, - ORM\Column( - name: "foo", - type: "string", - nullable: true, - length: 250 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("string") - ] - private ?string $foo = null; - /** * @return string|null */ @@ -103,44 +461,16 @@ public function getFoo(): ?string } /** - * @param string|null $foo - * * @return $this */ public function setFoo(?string $foo): static { $this->foo = null !== $foo ? - (string) $foo : - null; - + (string) $foo : + null; return $this; } - - /** - * Foo indexed field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooIndexed"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo indexed field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "partial"), - ApiFilter(\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "fooIndexed", - type: "string", - nullable: true, - length: 250 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("string") - ] - private ?string $fooIndexed = null; - /** * @return string|null */ @@ -150,44 +480,16 @@ public function getFooIndexed(): ?string } /** - * @param string|null $fooIndexed - * * @return $this */ public function setFooIndexed(?string $fooIndexed): static { $this->fooIndexed = null !== $fooIndexed ? - (string) $fooIndexed : - null; - + (string) $fooIndexed : + null; return $this; } - - /** - * Bool indexed field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "boolIndexed"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Bool indexed field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - ApiFilter(OrmFilter\OrderFilter::class), - ApiFilter(OrmFilter\BooleanFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "boolIndexed", - type: "boolean", - nullable: false, - options: ["default" => false] - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("bool") - ] - private bool $boolIndexed = false; - /** * @return bool */ @@ -197,51 +499,14 @@ public function getBoolIndexed(): bool } /** - * @param bool $boolIndexed - * * @return $this */ public function setBoolIndexed(bool $boolIndexed): static { $this->boolIndexed = $boolIndexed; - return $this; } - - /** - * Foo markdown field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: allow_h2: false - * allow_h3: false - * allow_h4: false - * allow_h5: false - * allow_h6: false - * allow_bold: true - * allow_italic: true - * allow_blockquote: false - * allow_image: false - * allow_list: false - * allow_nbsp: true - * allow_nb_hyphen: true - * allow_return: true - * allow_link: false - * allow_hr: false - * allow_preview: true - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooMarkdown"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo markdown field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1), - Gedmo\Versioned, - ORM\Column(name: "foo_markdown", type: "text", nullable: true), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\Type("string") - ] - private ?string $fooMarkdown = null; - /** * @return string|null */ @@ -251,48 +516,16 @@ public function getFooMarkdown(): ?string } /** - * @param string|null $fooMarkdown - * * @return $this */ public function setFooMarkdown(?string $fooMarkdown): static { $this->fooMarkdown = null !== $fooMarkdown ? - (string) $fooMarkdown : - null; - + (string) $fooMarkdown : + null; return $this; } - - /** - * Foo excluded markdown field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: allow_h2: false - * allow_h3: false - * allow_h4: false - * allow_h5: false - * allow_h6: false - * allow_bold: true - * allow_italic: true - * allow_blockquote: false - * allow_image: false - * allow_list: false - * allow_nbsp: true - * allow_nb_hyphen: true - * allow_return: true - * allow_link: false - * allow_hr: false - * allow_preview: true - */ - #[ - Gedmo\Versioned, - ORM\Column(name: "foo_markdown_excluded", type: "text", nullable: true), - Serializer\Exclude, - SymfonySerializer\Ignore - ] - private ?string $fooMarkdownExcluded = null; - /** * @return string|null */ @@ -302,47 +535,16 @@ public function getFooMarkdownExcluded(): ?string } /** - * @param string|null $fooMarkdownExcluded - * * @return $this */ public function setFooMarkdownExcluded(?string $fooMarkdownExcluded): static { $this->fooMarkdownExcluded = null !== $fooMarkdownExcluded ? - (string) $fooMarkdownExcluded : - null; - + (string) $fooMarkdownExcluded : + null; return $this; } - - /** - * Foo expression excluded decimal. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooDecimalExcluded"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Foo expression excluded decimal: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2), - ApiFilter(OrmFilter\OrderFilter::class), - ApiFilter(OrmFilter\NumericFilter::class), - ApiFilter(OrmFilter\RangeFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "foo_decimal_excluded", - type: "decimal", - nullable: true, - precision: 18, - scale: 3 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2), - Serializer\Exclude(if: "object.foo == 'test'"), - Serializer\Type("double") - ] - private int|float|null $fooDecimalExcluded = null; - /** * @return int|float|null */ @@ -352,109 +554,28 @@ public function getFooDecimalExcluded(): int|float|null } /** - * @param int|float|null $fooDecimalExcluded - * * @return $this */ public function setFooDecimalExcluded(int|float|null $fooDecimalExcluded): static { $this->fooDecimalExcluded = $fooDecimalExcluded; - return $this; } - - /** - * Référence à l'événement. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: # Entity class name - * classname: \App\Entity\Base\Event - * # Displayable is the method used to display entity name - * displayable: getName - * # Same as Displayable but for a secondary information - * alt_displayable: getSortingFirstDateTime - * # Same as Displayable but for a secondary information - * thumbnail: getMainDocument - * # Searchable entity fields - * searchable: - * - name - * - slug - * # This order will only be used for explorer - * orderBy: - * - field: sortingLastDateTime - * direction: DESC - * @var \App\Entity\Base\Event|null - */ - #[ - SymfonySerializer\SerializedName(serializedName: "singleEventReference"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Référence à l'événement: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToOne(targetEntity: \App\Entity\Base\Event::class), - ORM\JoinColumn(name: "single_event_reference_id", referencedColumnName: "id", onDelete: "SET NULL"), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private ?\App\Entity\Base\Event $singleEventReference = null; - - /** - * @return \App\Entity\Base\Event|null - */ public function getSingleEventReference(): ?\App\Entity\Base\Event { return $this->singleEventReference; } /** - * @param \App\Entity\Base\Event|null $singleEventReference * @return $this */ - public function setSingleEventReference(?\App\Entity\Base\Event $singleEventReference = null): static + public function setSingleEventReference(?\App\Entity\Base\Event $singleEventReference): static { $this->singleEventReference = $singleEventReference; - return $this; } - - /** - * Remontée d'événements manuelle. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: # Entity class name - * classname: \App\Entity\Base\Event - * # Displayable is the method used to display entity name - * displayable: getName - * # Same as Displayable but for a secondary information - * alt_displayable: getSortingFirstDateTime - * # Same as Displayable but for a secondary information - * thumbnail: getMainDocument - * # Searchable entity fields - * searchable: - * - name - * - slug - * # This order will only be used for explorer - * orderBy: - * - field: sortingLastDateTime - * direction: DESC - * @var Collection - */ - #[ - SymfonySerializer\SerializedName(serializedName: "eventReferences"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "Remontée d'événements manuelle: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class), - ORM\JoinTable(name: "node_type_event_references"), - ORM\JoinColumn(name: "node_type_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\InverseJoinColumn(name: "event_references_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\OrderBy(["sortingLastDateTime" => "DESC"]), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private Collection $eventReferences; - /** * @return Collection */ @@ -464,7 +585,7 @@ public function getEventReferences(): Collection } /** - * @param Collection|\App\Entity\Base\Event[] $eventReferences + * @param \Doctrine\Common\Collections\Collection|array<\App\Entity\Base\Event> $eventReferences * @return $this */ public function setEventReferences(Collection|array $eventReferences): static @@ -474,29 +595,9 @@ public function setEventReferences(Collection|array $eventReferences): static } else { $this->eventReferences = new \Doctrine\Common\Collections\ArrayCollection($eventReferences); } - return $this; } - - /** - * Remontée d'événements manuelle - * - * @var Collection - */ - #[ - Serializer\Exclude, - SymfonySerializer\Ignore, - ORM\OneToMany( - targetEntity: \App\Entity\PositionedCity::class, - mappedBy: "nodeSource", - orphanRemoval: true, - cascade: ["persist", "remove"] - ), - ORM\OrderBy(["position" => "ASC"]) - ] - private Collection $eventReferencesProxiedProxy; - /** * @return Collection */ @@ -505,41 +606,34 @@ public function getEventReferencesProxiedProxy(): Collection return $this->eventReferencesProxiedProxy; } - /** - * @return Collection - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("eventReferencesProxied"), - SymfonySerializer\SerializedName(serializedName: "eventReferencesProxied"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\MaxDepth(2) - ] - public function getEventReferencesProxied(): Collection + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('eventReferencesProxied')] + #[Serializer\SerializedName(serializedName: 'eventReferencesProxied')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[Serializer\MaxDepth(2)] + public function getEventReferencesProxied(): array { return $this->eventReferencesProxiedProxy->map(function (\App\Entity\PositionedCity $proxyEntity) { return $proxyEntity->getCity(); - }); + })->getValues(); } /** - * @param Collection $eventReferencesProxiedProxy - * @Serializer\VirtualProperty() + * @param \Doctrine\Common\Collections\Collection $eventReferencesProxiedProxy * @return $this */ public function setEventReferencesProxiedProxy(Collection $eventReferencesProxiedProxy): static { $this->eventReferencesProxiedProxy = $eventReferencesProxiedProxy; - return $this; } + /** - * @param Collection|array|null $eventReferencesProxied * @return $this */ - public function setEventReferencesProxied(Collection|array|null $eventReferencesProxied = null): static + public function setEventReferencesProxied(Collection|array|null $eventReferencesProxied): static { foreach ($this->getEventReferencesProxiedProxy() as $item) { $item->setNodeSource(null); @@ -562,40 +656,6 @@ public function setEventReferencesProxied(Collection|array|null $eventReferences return $this; } - - /** - * Remontée d'événements manuelle exclue. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * Default values: # Entity class name - * classname: \App\Entity\Base\Event - * # Displayable is the method used to display entity name - * displayable: getName - * # Same as Displayable but for a secondary information - * alt_displayable: getSortingFirstDateTime - * # Same as Displayable but for a secondary information - * thumbnail: getMainDocument - * # Searchable entity fields - * searchable: - * - name - * - slug - * # This order will only be used for explorer - * orderBy: - * - field: sortingLastDateTime - * direction: DESC - * @var Collection - */ - #[ - ORM\ManyToMany(targetEntity: \App\Entity\Base\Event::class), - ORM\JoinTable(name: "node_type_event_references_excluded"), - ORM\JoinColumn(name: "node_type_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\InverseJoinColumn(name: "event_references_excluded_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\OrderBy(["sortingLastDateTime" => "DESC"]), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Exclude, - SymfonySerializer\Ignore - ] - private Collection $eventReferencesExcluded; - /** * @return Collection */ @@ -605,7 +665,7 @@ public function getEventReferencesExcluded(): Collection } /** - * @param Collection|\App\Entity\Base\Event[] $eventReferencesExcluded + * @param \Doctrine\Common\Collections\Collection|array<\App\Entity\Base\Event> $eventReferencesExcluded * @return $this */ public function setEventReferencesExcluded(Collection|array $eventReferencesExcluded): static @@ -615,36 +675,17 @@ public function setEventReferencesExcluded(Collection|array $eventReferencesExcl } else { $this->eventReferencesExcluded = new \Doctrine\Common\Collections\ArrayCollection($eventReferencesExcluded); } - return $this; } - - /** - * Bar documents field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * - * (Virtual field, this var is a buffer) - */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "bar"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_documents"]), - \ApiPlatform\Metadata\ApiProperty(description: "Bar documents field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(1) - ] - private ?array $bar = null; - /** - * @return \mock\Entity\Document[] Documents array + * @return \mock\Entity\Document[] */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_documents"]), - Serializer\MaxDepth(1), - Serializer\VirtualProperty, - Serializer\SerializedName("bar"), - Serializer\Type("array") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_documents'])] + #[JMS\MaxDepth(1)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('bar')] + #[JMS\Type('array')] public function getBar(): array { if (null === $this->bar) { @@ -663,51 +704,33 @@ public function getBar(): array } /** - * @param \mock\Entity\Document $document - * * @return $this */ public function addBar(\mock\Entity\Document $document): static { - if (null !== $this->objectManager) { - $nodeSourceDocument = new \mock\Entity\NodesSourcesDocument( - $this, - $document - ); - $nodeSourceDocument->setFieldName('bar'); - if (!$this->hasNodesSourcesDocuments($nodeSourceDocument)) { - $this->objectManager->persist($nodeSourceDocument); - $this->addDocumentsByFields($nodeSourceDocument); - $this->bar = null; - } + if (null === $this->objectManager) { + return $this; + } + $nodeSourceDocument = new \mock\Entity\NodesSourcesDocument( + $this, + $document + ); + $nodeSourceDocument->setFieldName('bar'); + if (!$this->hasNodesSourcesDocuments($nodeSourceDocument)) { + $this->objectManager->persist($nodeSourceDocument); + $this->addDocumentsByFields($nodeSourceDocument); + $this->bar = null; } return $this; } - - /** - * Custom forms field. - * - * (Virtual field, this var is a buffer) - */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "theForms"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_custom_forms"]), - \ApiPlatform\Metadata\ApiProperty(description: "Custom forms field"), - SymfonySerializer\MaxDepth(2) - ] - private ?array $theForms = null; - /** * @return \mock\Entity\CustomForm[] CustomForm array */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_custom_forms"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("theForms") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_custom_forms'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('theForms')] public function getTheForms(): array { if (null === $this->theForms) { @@ -726,8 +749,6 @@ public function getTheForms(): array } /** - * @param \mock\Entity\CustomForm $customForm - * * @return $this */ public function addTheForms(\mock\Entity\CustomForm $customForm): static @@ -745,34 +766,14 @@ public function addTheForms(\mock\Entity\CustomForm $customForm): static return $this; } - /** - * fooBarSources NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - * - * ForBar nodes field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * @var \mock\Entity\NodesSources[]|null + * @return \mock\Entity\NodesSources[] */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "fooBar"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - \ApiPlatform\Metadata\ApiProperty(description: "ForBar nodes field: Maecenas sed diam eget risus varius blandit sit amet non magna"), - SymfonySerializer\MaxDepth(2) - ] - private ?array $fooBarSources = null; - - /** - * @return \mock\Entity\NodesSources[] fooBar nodes-sources array - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("fooBar"), - Serializer\Type("array") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooBar')] + #[JMS\Type('array')] public function getFooBarSources(): array { if (null === $this->fooBarSources) { @@ -792,38 +793,22 @@ public function getFooBarSources(): array /** * @param \mock\Entity\NodesSources[]|null $fooBarSources - * * @return $this */ public function setFooBarSources(?array $fooBarSources): static { $this->fooBarSources = $fooBarSources; - return $this; } - - /** - * fooBarHiddenSources NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - * - * ForBar hidden nodes field. - * Maecenas sed diam eget risus varius blandit sit amet non magna. - * @var \mock\Entity\NodesSources[]|null - */ - #[Serializer\Exclude] - private ?array $fooBarHiddenSources = null; - /** - * @return \mock\Entity\NodesSources[] fooBarHidden nodes-sources array + * @return \mock\Entity\NodesSources[] */ - #[ - Serializer\Exclude, - SymfonySerializer\Ignore, - Serializer\VirtualProperty, - Serializer\SerializedName("fooBarHidden"), - Serializer\Type("array") - ] + #[JMS\Exclude] + #[Serializer\Ignore] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooBarHidden')] + #[JMS\Type('array')] public function getFooBarHiddenSources(): array { if (null === $this->fooBarHiddenSources) { @@ -843,44 +828,22 @@ public function getFooBarHiddenSources(): array /** * @param \mock\Entity\NodesSources[]|null $fooBarHiddenSources - * * @return $this */ public function setFooBarHiddenSources(?array $fooBarHiddenSources): static { $this->fooBarHiddenSources = $fooBarHiddenSources; - return $this; } - /** - * fooBarTypedSources NodesSources direct field buffer. - * (Virtual field, this var is a buffer) - * - * ForBar nodes typed field. - * Default values: MockTwo - * @var \tests\mocks\GeneratedNodesSources\NSMockTwo[]|null + * @return \tests\mocks\GeneratedNodesSources\NSMockTwo[] */ - #[ - Serializer\Exclude, - SymfonySerializer\SerializedName(serializedName: "fooBarTyped"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - \ApiPlatform\Metadata\ApiProperty(description: "ForBar nodes typed field"), - SymfonySerializer\MaxDepth(2) - ] - private ?array $fooBarTypedSources = null; - - /** - * @return \tests\mocks\GeneratedNodesSources\NSMockTwo[] fooBarTyped nodes-sources array - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default", "nodes_sources_nodes"]), - Serializer\MaxDepth(2), - Serializer\VirtualProperty, - Serializer\SerializedName("fooBarTyped"), - Serializer\Type("array") - ] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default', 'nodes_sources_nodes'])] + #[JMS\MaxDepth(2)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooBarTyped')] + #[JMS\Type('array')] public function getFooBarTypedSources(): array { if (null === $this->fooBarTypedSources) { @@ -900,41 +863,14 @@ public function getFooBarTypedSources(): array /** * @param \tests\mocks\GeneratedNodesSources\NSMockTwo[]|null $fooBarTypedSources - * * @return $this */ public function setFooBarTypedSources(?array $fooBarTypedSources): static { $this->fooBarTypedSources = $fooBarTypedSources; - return $this; } - - /** - * ForBar layout enum. - * Default values: light, dark, transparent - */ - #[ - SymfonySerializer\SerializedName(serializedName: "layout"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "ForBar layout enum", schema: ["type" => "string", "enum" => ["light","dark","transparent"], "example" => "light"]), - SymfonySerializer\MaxDepth(2), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - ApiFilter(\RZ\Roadiz\CoreBundle\Api\Filter\NotFilter::class), - Gedmo\Versioned, - ORM\Column( - name: "layout", - type: "string", - nullable: true, - length: 11 - ), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2), - Serializer\Type("string") - ] - private ?string $layout = null; - /** * @return string|null */ @@ -944,84 +880,30 @@ public function getLayout(): ?string } /** - * @param string|null $layout - * * @return $this */ public function setLayout(?string $layout): static { $this->layout = null !== $layout ? - (string) $layout : - null; - + (string) $layout : + null; return $this; } - - /** - * For many_to_one field. - * Default values: classname: \MyCustomEntity - * displayable: getName - * @var \MyCustomEntity|null - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooManyToOne"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "For many_to_one field"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToOne(targetEntity: \MyCustomEntity::class), - ORM\JoinColumn(name: "foo_many_to_one_id", referencedColumnName: "id", onDelete: "SET NULL"), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private ?\MyCustomEntity $fooManyToOne = null; - - /** - * @return \MyCustomEntity|null - */ public function getFooManyToOne(): ?\MyCustomEntity { return $this->fooManyToOne; } /** - * @param \MyCustomEntity|null $fooManyToOne * @return $this */ - public function setFooManyToOne(?\MyCustomEntity $fooManyToOne = null): static + public function setFooManyToOne(?\MyCustomEntity $fooManyToOne): static { $this->fooManyToOne = $fooManyToOne; - return $this; } - - /** - * For many_to_many field. - * Default values: classname: \MyCustomEntity - * displayable: getName - * orderBy: - * - field: name - * direction: asc - * @var Collection - */ - #[ - SymfonySerializer\SerializedName(serializedName: "fooManyToMany"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - \ApiPlatform\Metadata\ApiProperty(description: "For many_to_many field"), - SymfonySerializer\MaxDepth(2), - ORM\ManyToMany(targetEntity: \MyCustomEntity::class), - ORM\JoinTable(name: "node_type_foo_many_to_many"), - ORM\JoinColumn(name: "node_type_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\InverseJoinColumn(name: "foo_many_to_many_id", referencedColumnName: "id", onDelete: "CASCADE"), - ORM\OrderBy(["name" => "asc"]), - ApiFilter(OrmFilter\SearchFilter::class, strategy: "exact"), - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(2) - ] - private Collection $fooManyToMany; - /** * @return Collection */ @@ -1031,7 +913,7 @@ public function getFooManyToMany(): Collection } /** - * @param Collection|\MyCustomEntity[] $fooManyToMany + * @param \Doctrine\Common\Collections\Collection|array<\MyCustomEntity> $fooManyToMany * @return $this */ public function setFooManyToMany(Collection|array $fooManyToMany): static @@ -1041,29 +923,9 @@ public function setFooManyToMany(Collection|array $fooManyToMany): static } else { $this->fooManyToMany = new \Doctrine\Common\Collections\ArrayCollection($fooManyToMany); } - return $this; } - - /** - * For many_to_many proxied field - * - * @var Collection - */ - #[ - Serializer\Exclude, - SymfonySerializer\Ignore, - ORM\OneToMany( - targetEntity: \Themes\MyTheme\Entities\PositionedCity::class, - mappedBy: "nodeSource", - orphanRemoval: true, - cascade: ["persist", "remove"] - ), - ORM\OrderBy(["position" => "ASC"]) - ] - private Collection $fooManyToManyProxiedProxy; - /** * @return Collection */ @@ -1072,41 +934,34 @@ public function getFooManyToManyProxiedProxy(): Collection return $this->fooManyToManyProxiedProxy; } - /** - * @return Collection - */ - #[ - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\MaxDepth(1), - Serializer\VirtualProperty, - Serializer\SerializedName("fooManyToManyProxied"), - SymfonySerializer\SerializedName(serializedName: "fooManyToManyProxied"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\MaxDepth(1) - ] - public function getFooManyToManyProxied(): Collection + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\MaxDepth(1)] + #[JMS\VirtualProperty] + #[JMS\SerializedName('fooManyToManyProxied')] + #[Serializer\SerializedName(serializedName: 'fooManyToManyProxied')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[Serializer\MaxDepth(1)] + public function getFooManyToManyProxied(): array { return $this->fooManyToManyProxiedProxy->map(function (\Themes\MyTheme\Entities\PositionedCity $proxyEntity) { return $proxyEntity->getCity(); - }); + })->getValues(); } /** - * @param Collection $fooManyToManyProxiedProxy - * @Serializer\VirtualProperty() + * @param \Doctrine\Common\Collections\Collection $fooManyToManyProxiedProxy * @return $this */ public function setFooManyToManyProxiedProxy(Collection $fooManyToManyProxiedProxy): static { $this->fooManyToManyProxiedProxy = $fooManyToManyProxiedProxy; - return $this; } + /** - * @param Collection|array|null $fooManyToManyProxied * @return $this */ - public function setFooManyToManyProxied(Collection|array|null $fooManyToManyProxied = null): static + public function setFooManyToManyProxied(Collection|array|null $fooManyToManyProxied): static { foreach ($this->getFooManyToManyProxiedProxy() as $item) { $item->setNodeSource(null); @@ -1129,11 +984,9 @@ public function setFooManyToManyProxied(Collection|array|null $fooManyToManyProx return $this; } - public function __construct(\mock\Entity\Node $node, \mock\Entity\Translation $translation) { parent::__construct($node, $translation); - $this->eventReferences = new \Doctrine\Common\Collections\ArrayCollection(); $this->eventReferencesProxiedProxy = new \Doctrine\Common\Collections\ArrayCollection(); $this->eventReferencesExcluded = new \Doctrine\Common\Collections\ArrayCollection(); @@ -1141,13 +994,34 @@ public function __construct(\mock\Entity\Node $node, \mock\Entity\Translation $t $this->fooManyToManyProxiedProxy = new \Doctrine\Common\Collections\ArrayCollection(); } - #[ - Serializer\VirtualProperty, - Serializer\Groups(["nodes_sources", "nodes_sources_default"]), - Serializer\SerializedName("@type"), - SymfonySerializer\Groups(["nodes_sources", "nodes_sources_default"]), - SymfonySerializer\SerializedName(serializedName: "@type") - ] + public function __clone(): void + { + parent::__clone(); + + $eventReferencesProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); + foreach ($this->eventReferencesProxiedProxy as $item) { + $itemClone = clone $item; + $itemClone->setNodeSource($this); + $eventReferencesProxiedProxyClone->add($itemClone); + $this->objectManager->persist($itemClone); + } + $this->eventReferencesProxiedProxy = $eventReferencesProxiedProxyClone; + + $fooManyToManyProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); + foreach ($this->fooManyToManyProxiedProxy as $item) { + $itemClone = clone $item; + $itemClone->setNodeSource($this); + $fooManyToManyProxiedProxyClone->add($itemClone); + $this->objectManager->persist($itemClone); + } + $this->fooManyToManyProxiedProxy = $fooManyToManyProxiedProxyClone; + } + + #[JMS\VirtualProperty] + #[JMS\Groups(['nodes_sources', 'nodes_sources_default'])] + #[JMS\SerializedName('@type')] + #[Serializer\Groups(['nodes_sources', 'nodes_sources_default'])] + #[Serializer\SerializedName(serializedName: '@type')] public function getNodeTypeName(): string { return 'Mock'; @@ -1155,9 +1029,9 @@ public function getNodeTypeName(): string /** * $this->nodeType->isReachable() proxy. - * * @return bool Does this nodeSource is reachable over network? */ + #[JMS\VirtualProperty] public function isReachable(): bool { return true; @@ -1165,37 +1039,14 @@ public function isReachable(): bool /** * $this->nodeType->isPublishable() proxy. - * * @return bool Does this nodeSource is publishable with date and time? */ + #[JMS\VirtualProperty] public function isPublishable(): bool { return true; } - public function __clone() - { - parent::__clone(); - - $eventReferencesProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); - foreach ($this->eventReferencesProxiedProxy as $item) { - $itemClone = clone $item; - $itemClone->setNodeSource($this); - $eventReferencesProxiedProxyClone->add($itemClone); - $this->objectManager->persist($itemClone); - } - $this->eventReferencesProxiedProxy = $eventReferencesProxiedProxyClone; - - $fooManyToManyProxiedProxyClone = new \Doctrine\Common\Collections\ArrayCollection(); - foreach ($this->fooManyToManyProxiedProxy as $item) { - $itemClone = clone $item; - $itemClone->setNodeSource($this); - $fooManyToManyProxiedProxyClone->add($itemClone); - $this->objectManager->persist($itemClone); - } - $this->fooManyToManyProxiedProxy = $fooManyToManyProxiedProxyClone; - } - public function __toString(): string { return '[NSMock] ' . parent::__toString(); diff --git a/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php b/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php index 0f8cab8..3ad1e9c 100644 --- a/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php +++ b/tests/Mocks/GeneratedNodesSourcesWithRepository/Repository/NSMockRepository.php @@ -1,38 +1,38 @@ - * - * @method \RZ\Roadiz\EntityGenerator\Tests\Mocks\GeneratedNodesSourcesWithRepository\NSMock|null find($id, $lockMode = null, $lockVersion = null) - * @method \RZ\Roadiz\EntityGenerator\Tests\Mocks\GeneratedNodesSourcesWithRepository\NSMock|null findOneBy(array $criteria, array $orderBy = null) - * @method \RZ\Roadiz\EntityGenerator\Tests\Mocks\GeneratedNodesSourcesWithRepository\NSMock[] findAll() - * @method \RZ\Roadiz\EntityGenerator\Tests\Mocks\GeneratedNodesSourcesWithRepository\NSMock[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) + * @extends NodesSourcesRepository + * @method NSMock|null find($id, $lockMode = null, $lockVersion = null) + * @method NSMock|null findOneBy(array $criteria, array $orderBy = null) + * @method NSMock[] findAll() + * @method NSMock[] findBy(array $criteria, array $orderBy = null, $limit = null, $offset = null) */ -class NSMockRepository extends \RZ\Roadiz\CoreBundle\Repository\NodesSourcesRepository +final class NSMockRepository extends NodesSourcesRepository { public function __construct( ManagerRegistry $registry, PreviewResolverInterface $previewResolver, EventDispatcherInterface $dispatcher, Security $security, - ?NodeSourceSearchHandlerInterface $nodeSourceSearchHandler + ?NodeSourceSearchHandlerInterface $nodeSourceSearchHandler, ) { - parent::__construct($registry, $previewResolver, $dispatcher, $security, $nodeSourceSearchHandler); - - $this->_entityName = \RZ\Roadiz\EntityGenerator\Tests\Mocks\GeneratedNodesSourcesWithRepository\NSMock::class; + parent::__construct($registry, $previewResolver, $dispatcher, $security, $nodeSourceSearchHandler, NSMock::class); } } diff --git a/tests/NodeTypeAwareTestTrait.php b/tests/NodeTypeAwareTestTrait.php index 6a64ef8..2fdacf9 100644 --- a/tests/NodeTypeAwareTestTrait.php +++ b/tests/NodeTypeAwareTestTrait.php @@ -17,177 +17,177 @@ protected function getMockNodeType(): NodeTypeInterface ->method('getFields') ->willReturn( new ArrayCollection([ - (new SimpleNodeTypeField()) - ->setName('foo_datetime') - ->setTypeName('datetime') - ->setDoctrineType('datetime') - ->setSerializationGroups([ - 'nodes_sources', - 'nodes_sources_default', - 'foo_datetime' - ]) - ->setVirtual(false) - ->setLabel('Foo DateTime field') - ->setIndexed(true), - (new SimpleNodeTypeField()) - ->setName('foo') - ->setTypeName('string') - ->setVirtual(false) - ->setSerializationMaxDepth(1) - ->setLabel('Foo field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('fooIndexed') - ->setTypeName('string') - ->setVirtual(false) - ->setSerializationMaxDepth(1) - ->setLabel('Foo indexed field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(true), - (new SimpleNodeTypeField()) - ->setName('boolIndexed') - ->setTypeName('bool') - ->setDoctrineType('boolean') - ->setVirtual(false) - ->setSerializationMaxDepth(1) - ->setLabel('Bool indexed field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(true), - (new SimpleNodeTypeField()) - ->setName('foo_markdown') - ->setTypeName('markdown') - ->setDoctrineType('text') - ->setVirtual(false) - ->setSerializationMaxDepth(1) - ->setLabel('Foo markdown field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setDefaultValues("allow_h2: false\r\nallow_h3: false\r\nallow_h4: false\r\nallow_h5: false\r\nallow_h6: false\r\nallow_bold: true\r\nallow_italic: true\r\nallow_blockquote: false\r\nallow_image: false\r\nallow_list: false\r\nallow_nbsp: true\r\nallow_nb_hyphen: true\r\nallow_return: true\r\nallow_link: false\r\nallow_hr: false\r\nallow_preview: true") - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_markdown_excluded') - ->setTypeName('markdown') - ->setDoctrineType('text') - ->setVirtual(false) - ->setExcludedFromSerialization(true) - ->setLabel('Foo excluded markdown field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setDefaultValues("allow_h2: false\r\nallow_h3: false\r\nallow_h4: false\r\nallow_h5: false\r\nallow_h6: false\r\nallow_bold: true\r\nallow_italic: true\r\nallow_blockquote: false\r\nallow_image: false\r\nallow_list: false\r\nallow_nbsp: true\r\nallow_nb_hyphen: true\r\nallow_return: true\r\nallow_link: false\r\nallow_hr: false\r\nallow_preview: true") - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_decimal_excluded') - ->setTypeName('decimal') - ->setDoctrineType('decimal') - ->setVirtual(false) - ->setSerializationExclusionExpression('object.foo == \'test\'') - ->setLabel('Foo expression excluded decimal') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(true), - (new SimpleNodeTypeField()) - ->setName('single_event_reference') - ->setTypeName('many_to_one') - ->setVirtual(false) - ->setLabel("Référence à l'événement") - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC") - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('event_references') - ->setTypeName('many_to_many') - ->setVirtual(false) - ->setLabel("Remontée d'événements manuelle") - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC") - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('event_references_proxied') - ->setTypeName('many_to_many') - ->setVirtual(false) - ->setLabel("Remontée d'événements manuelle") - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC\r\n# Use a proxy entity\r\nproxy:\r\n classname: \\App\\Entity\\PositionedCity\r\n self: nodeSource\r\n relation: city\r\n # This order will preserve position\r\n orderBy:\r\n - field: position\r\n direction: ASC") - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('event_references_excluded') - ->setTypeName('many_to_many') - ->setVirtual(false) - ->setExcludedFromSerialization(true) - ->setLabel("Remontée d'événements manuelle exclue") - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC") - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('bar') - ->setTypeName('documents') - ->setSerializationMaxDepth(1) - ->setVirtual(true) - ->setLabel('Bar documents field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('the_forms') - ->setTypeName('custom_forms') - ->setVirtual(true) - ->setLabel('Custom forms field') - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_bar') - ->setTypeName('nodes') - ->setVirtual(true) - ->setLabel('ForBar nodes field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_bar_hidden') - ->setTypeName('nodes') - ->setVirtual(true) - ->setExcludedFromSerialization(true) - ->setLabel('ForBar hidden nodes field') - ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') - ->setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_bar_typed') - ->setTypeName('nodes') - ->setVirtual(true) - ->setLabel('ForBar nodes typed field') - ->setIndexed(false) - ->setDefaultValues('MockTwo'), - (new SimpleNodeTypeField()) - ->setName('layout') - ->setTypeName('enum') - ->setLabel('ForBar layout enum') - ->setIndexed(true) - ->setDefaultValues('light, dark, transparent'), - (new SimpleNodeTypeField()) - ->setName('foo_many_to_one') - ->setTypeName('many_to_one') - ->setVirtual(false) - ->setLabel('For many_to_one field') - ->setDefaultValues(<<setName('foo_datetime') + ->setTypeName('datetime') + ->setDoctrineType('datetime') + ->setSerializationGroups([ + 'nodes_sources', + 'nodes_sources_default', + 'foo_datetime', + ]) + ->setVirtual(false) + ->setLabel('Foo DateTime field') + ->setIndexed(true), + (new SimpleNodeTypeField()) + ->setName('foo') + ->setTypeName('string') + ->setVirtual(false) + ->setSerializationMaxDepth(1) + ->setLabel('Foo field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('fooIndexed') + ->setTypeName('string') + ->setVirtual(false) + ->setSerializationMaxDepth(1) + ->setLabel('Foo indexed field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(true), + (new SimpleNodeTypeField()) + ->setName('boolIndexed') + ->setTypeName('bool') + ->setDoctrineType('boolean') + ->setVirtual(false) + ->setSerializationMaxDepth(1) + ->setLabel('Bool indexed field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(true), + (new SimpleNodeTypeField()) + ->setName('foo_markdown') + ->setTypeName('markdown') + ->setDoctrineType('text') + ->setVirtual(false) + ->setSerializationMaxDepth(1) + ->setLabel('Foo markdown field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setDefaultValues("allow_h2: false\r\nallow_h3: false\r\nallow_h4: false\r\nallow_h5: false\r\nallow_h6: false\r\nallow_bold: true\r\nallow_italic: true\r\nallow_blockquote: false\r\nallow_image: false\r\nallow_list: false\r\nallow_nbsp: true\r\nallow_nb_hyphen: true\r\nallow_return: true\r\nallow_link: false\r\nallow_hr: false\r\nallow_preview: true") + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_markdown_excluded') + ->setTypeName('markdown') + ->setDoctrineType('text') + ->setVirtual(false) + ->setExcludedFromSerialization(true) + ->setLabel('Foo excluded markdown field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setDefaultValues("allow_h2: false\r\nallow_h3: false\r\nallow_h4: false\r\nallow_h5: false\r\nallow_h6: false\r\nallow_bold: true\r\nallow_italic: true\r\nallow_blockquote: false\r\nallow_image: false\r\nallow_list: false\r\nallow_nbsp: true\r\nallow_nb_hyphen: true\r\nallow_return: true\r\nallow_link: false\r\nallow_hr: false\r\nallow_preview: true") + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_decimal_excluded') + ->setTypeName('decimal') + ->setDoctrineType('decimal') + ->setVirtual(false) + ->setSerializationExclusionExpression('object.foo == \'test\'') + ->setLabel('Foo expression excluded decimal') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(true), + (new SimpleNodeTypeField()) + ->setName('single_event_reference') + ->setTypeName('many_to_one') + ->setVirtual(false) + ->setLabel("Référence à l'événement") + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC") + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('event_references') + ->setTypeName('many_to_many') + ->setVirtual(false) + ->setLabel("Remontée d'événements manuelle") + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC") + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('event_references_proxied') + ->setTypeName('many_to_many') + ->setVirtual(false) + ->setLabel("Remontée d'événements manuelle") + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC\r\n# Use a proxy entity\r\nproxy:\r\n classname: \\App\\Entity\\PositionedCity\r\n self: nodeSource\r\n relation: city\r\n # This order will preserve position\r\n orderBy:\r\n - field: position\r\n direction: ASC") + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('event_references_excluded') + ->setTypeName('many_to_many') + ->setVirtual(false) + ->setExcludedFromSerialization(true) + ->setLabel("Remontée d'événements manuelle exclue") + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setDefaultValues("# Entity class name\r\nclassname: \\App\\Entity\\Base\\Event\r\n# Displayable is the method used to display entity name\r\ndisplayable: getName\r\n# Same as Displayable but for a secondary information\r\nalt_displayable: getSortingFirstDateTime\r\n# Same as Displayable but for a secondary information\r\nthumbnail: getMainDocument\r\n# Searchable entity fields\r\nsearchable:\r\n - name\r\n - slug\r\n# This order will only be used for explorer\r\norderBy:\r\n - field: sortingLastDateTime\r\n direction: DESC") + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('bar') + ->setTypeName('documents') + ->setSerializationMaxDepth(1) + ->setVirtual(true) + ->setLabel('Bar documents field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('the_forms') + ->setTypeName('custom_forms') + ->setVirtual(true) + ->setLabel('Custom forms field') + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_bar') + ->setTypeName('nodes') + ->setVirtual(true) + ->setLabel('ForBar nodes field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_bar_hidden') + ->setTypeName('nodes') + ->setVirtual(true) + ->setExcludedFromSerialization(true) + ->setLabel('ForBar hidden nodes field') + ->setDescription('Maecenas sed diam eget risus varius blandit sit amet non magna') + ->setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_bar_typed') + ->setTypeName('nodes') + ->setVirtual(true) + ->setLabel('ForBar nodes typed field') + ->setIndexed(false) + ->setDefaultValues('MockTwo'), + (new SimpleNodeTypeField()) + ->setName('layout') + ->setTypeName('enum') + ->setLabel('ForBar layout enum') + ->setIndexed(true) + ->setDefaultValues('layout_odd, layout_odd_big_title, layout_even, layout_even_big_title, layout_media_grid'), + (new SimpleNodeTypeField()) + ->setName('foo_many_to_one') + ->setTypeName('many_to_one') + ->setVirtual(false) + ->setLabel('For many_to_one field') + ->setDefaultValues(<<setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_many_to_many') - ->setTypeName('many_to_many') - ->setVirtual(false) - ->setLabel('For many_to_many field') - ->setDefaultValues(<<setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_many_to_many') + ->setTypeName('many_to_many') + ->setVirtual(false) + ->setLabel('For many_to_many field') + ->setDefaultValues(<<setIndexed(false), - (new SimpleNodeTypeField()) - ->setName('foo_many_to_many_proxied') - ->setTypeName('many_to_many') - ->setVirtual(false) - ->setSerializationMaxDepth(1) - ->setLabel('For many_to_many proxied field') - ->setDefaultValues(<<setIndexed(false), + (new SimpleNodeTypeField()) + ->setName('foo_many_to_many_proxied') + ->setTypeName('many_to_many') + ->setVirtual(false) + ->setSerializationMaxDepth(1) + ->setLabel('For many_to_many proxied field') + ->setDefaultValues(<<setIndexed(false), + ->setIndexed(false), ]) ); @@ -222,6 +222,7 @@ classname: Themes\MyTheme\Entities\PositionedCity $mockNodeType ->method('isPublishable') ->willReturn(true); + return $mockNodeType; } @@ -233,11 +234,13 @@ function (string $nodeTypeName): NodeTypeInterface { $mockNodeType = $this->createStub(NodeTypeInterface::class); $mockNodeType ->method('getSourceEntityFullQualifiedClassName') - ->willReturn('tests\mocks\GeneratedNodesSources\NS' . $nodeTypeName) + ->willReturn('tests\mocks\GeneratedNodesSources\NS'.$nodeTypeName) ; + return $mockNodeType; } ); + return $mockNodeTypeResolver; } diff --git a/tests/SimpleNodeTypeField.php b/tests/SimpleNodeTypeField.php index befe9ca..9ac846f 100644 --- a/tests/SimpleNodeTypeField.php +++ b/tests/SimpleNodeTypeField.php @@ -32,309 +32,207 @@ final class SimpleNodeTypeField implements NodeTypeFieldInterface, SerializableI private string $nodeTypeName = 'NodeType'; private string $doctrineType = 'string'; - /** - * @return string|null - */ public function getDescription(): ?string { return $this->description; } - /** - * @param string|null $description - * @return SimpleNodeTypeField - */ public function setDescription(?string $description): SimpleNodeTypeField { $this->description = $description; + return $this; } - /** - * @return string - */ public function getLabel(): string { return $this->label ?? ''; } - /** - * @param string|null $label - * @return SimpleNodeTypeField - */ public function setLabel(?string $label): SimpleNodeTypeField { $this->label = $label; + return $this; } - /** - * @return string - */ public function getName(): string { return $this->name ?? ''; } - /** - * @param string|null $name - * @return SimpleNodeTypeField - */ public function setName(?string $name): SimpleNodeTypeField { $this->name = $name; + return $this; } - /** - * @return string|null - */ public function getPlaceholder(): ?string { return $this->placeholder; } - /** - * @param string|null $placeholder - * @return SimpleNodeTypeField - */ public function setPlaceholder(?string $placeholder): SimpleNodeTypeField { $this->placeholder = $placeholder; + return $this; } - /** - * @return string|null - */ public function getDefaultValues(): ?string { return $this->defaultValues; } - /** - * @param string|null $defaultValues - * @return SimpleNodeTypeField - */ public function setDefaultValues(?string $defaultValues): SimpleNodeTypeField { $this->defaultValues = $defaultValues; + return $this; } - /** - * @return string|null - */ public function getGroupName(): ?string { return $this->groupName; } - /** - * @param string|null $groupName - * @return SimpleNodeTypeField - */ public function setGroupName(?string $groupName): SimpleNodeTypeField { $this->groupName = $groupName; + return $this; } - /** - * @return int|null - */ public function getMinLength(): ?int { return $this->minLength; } - /** - * @param int|null $minLength - * @return SimpleNodeTypeField - */ public function setMinLength(?int $minLength): SimpleNodeTypeField { $this->minLength = $minLength; + return $this; } - /** - * @return int|null - */ public function getMaxLength(): ?int { return $this->maxLength; } - /** - * @param int|null $maxLength - * @return SimpleNodeTypeField - */ public function setMaxLength(?int $maxLength): SimpleNodeTypeField { $this->maxLength = $maxLength; + return $this; } - /** - * @return bool - */ public function isVisible(): bool { return $this->visible; } - /** - * @param bool $visible - * @return SimpleNodeTypeField - */ public function setVisible(bool $visible): SimpleNodeTypeField { $this->visible = $visible; + return $this; } - /** - * @return bool - */ public function isUniversal(): bool { return $this->universal; } - /** - * @param bool $universal - * @return SimpleNodeTypeField - */ public function setUniversal(bool $universal): SimpleNodeTypeField { $this->universal = $universal; + return $this; } - /** - * @return bool - */ public function isSearchable(): bool { return $this->searchable; } - /** - * @param bool $searchable - * @return SimpleNodeTypeField - */ public function setSearchable(bool $searchable): SimpleNodeTypeField { $this->searchable = $searchable; + return $this; } - /** - * @return bool - */ public function isVirtual(): bool { return $this->virtual; } - /** - * @param bool $virtual - * @return SimpleNodeTypeField - */ public function setVirtual(bool $virtual): SimpleNodeTypeField { $this->virtual = $virtual; + return $this; } - /** - * @return bool - */ public function isIndexed(): bool { return $this->indexed; } - /** - * @param bool $indexed - * @return SimpleNodeTypeField - */ public function setIndexed(bool $indexed): SimpleNodeTypeField { $this->indexed = $indexed; + return $this; } - /** - * @return bool - */ public function isExpanded(): bool { return $this->expanded; } - /** - * @param bool $expanded - * @return SimpleNodeTypeField - */ public function setExpanded(bool $expanded): SimpleNodeTypeField { $this->expanded = $expanded; + return $this; } - /** - * @return string - */ public function getTypeName(): string { return $this->typeName; } - /** - * @param string $typeName - * @return SimpleNodeTypeField - */ public function setTypeName(string $typeName): SimpleNodeTypeField { $this->typeName = $typeName; + return $this; } - /** - * @return string - */ public function getNodeTypeName(): string { return $this->nodeTypeName; } - /** - * @param string $nodeTypeName - * @return SimpleNodeTypeField - */ public function setNodeTypeName(string $nodeTypeName): SimpleNodeTypeField { $this->nodeTypeName = $nodeTypeName; + return $this; } - /** - * @return string - */ public function getDoctrineType(): string { return $this->doctrineType; } - /** - * @param string $doctrineType - * @return SimpleNodeTypeField - */ public function setDoctrineType(string $doctrineType): SimpleNodeTypeField { $this->doctrineType = $doctrineType; + return $this; } @@ -345,12 +243,12 @@ public function getVarName(): string public function getGetterName(): string { - return (new UnicodeString('get ' . $this->getName()))->camel()->toString(); + return (new UnicodeString('get '.$this->getName()))->camel()->toString(); } public function getSetterName(): string { - return (new UnicodeString('set ' . $this->getName()))->camel()->toString(); + return (new UnicodeString('set '.$this->getName()))->camel()->toString(); } public function getGroupNameCanonical(): ?string @@ -365,223 +263,199 @@ public function getType() public function isString(): bool { - return $this->typeName === 'string'; + return 'string' === $this->typeName; } public function isText(): bool { - return $this->typeName === 'text'; + return 'text' === $this->typeName; } public function isDate(): bool { - return $this->typeName === 'date'; + return 'date' === $this->typeName; } public function isDateTime(): bool { - return $this->typeName === 'datetime'; + return 'datetime' === $this->typeName; } public function isRichText(): bool { - return $this->typeName === 'richtext'; + return 'richtext' === $this->typeName; } public function isMarkdown(): bool { - return $this->typeName === 'markdown'; + return 'markdown' === $this->typeName; } public function isBool(): bool { - return $this->typeName === 'bool'; + return 'bool' === $this->typeName; } public function isInteger(): bool { - return $this->typeName === 'integer'; + return 'integer' === $this->typeName; } public function isDecimal(): bool { - return $this->typeName === 'decimal'; + return 'decimal' === $this->typeName; } public function isEmail(): bool { - return $this->typeName === 'email'; + return 'email' === $this->typeName; } public function isDocuments(): bool { - return $this->typeName === 'documents'; + return 'documents' === $this->typeName; } public function isPassword(): bool { - return $this->typeName === 'password'; + return 'password' === $this->typeName; } public function isColor(): bool { - return $this->typeName === 'color'; + return 'color' === $this->typeName; } public function isGeoTag(): bool { - return $this->typeName === 'geotag'; + return 'geotag' === $this->typeName; } public function isNodes(): bool { - return $this->typeName === 'nodes'; + return 'nodes' === $this->typeName; } public function isUser(): bool { - return $this->typeName === 'user'; + return 'user' === $this->typeName; } public function isEnum(): bool { - return $this->typeName === 'enum'; + return 'enum' === $this->typeName; } public function isChildrenNodes(): bool { - return $this->typeName === 'children'; + return 'children' === $this->typeName; } public function isCustomForms(): bool { - return $this->typeName === 'custom_forms'; + return 'custom_forms' === $this->typeName; } public function isMultiple(): bool { - return $this->typeName === 'multiple'; + return 'multiple' === $this->typeName; } public function isMultiGeoTag(): bool { - return $this->typeName === 'multi_geotag'; + return 'multi_geotag' === $this->typeName; } public function isJson(): bool { - return $this->typeName === 'json'; + return 'json' === $this->typeName; } public function isYaml(): bool { - return $this->typeName === 'yaml'; + return 'yaml' === $this->typeName; } public function isCss(): bool { - return $this->typeName === 'css'; + return 'css' === $this->typeName; } public function isManyToMany(): bool { - return $this->typeName === 'many_to_many'; + return 'many_to_many' === $this->typeName; } public function isManyToOne(): bool { - return $this->typeName === 'many_to_one'; + return 'many_to_one' === $this->typeName; } public function isCountry(): bool { - return $this->typeName === 'country'; + return 'country' === $this->typeName; } public function isSingleProvider(): bool { - return $this->typeName === 'single_provider'; + return 'single_provider' === $this->typeName; } public function isMultiProvider(): bool { - return $this->typeName === 'multi_provider'; + return 'multi_provider' === $this->typeName; } public function isCollection(): bool { - return $this->typeName === 'collection'; + return 'collection' === $this->typeName; } - /** - * @return array - */ public function getSerializationGroups(): array { return $this->serializationGroups; } - /** - * @param array $serializationGroups - * @return SimpleNodeTypeField - */ public function setSerializationGroups(array $serializationGroups): SimpleNodeTypeField { $this->serializationGroups = $serializationGroups; + return $this; } - /** - * @return bool - */ public function isExcludedFromSerialization(): bool { return $this->excludedFromSerialization; } - /** - * @param bool $excludedFromSerialization - * @return SimpleNodeTypeField - */ public function setExcludedFromSerialization(bool $excludedFromSerialization): SimpleNodeTypeField { $this->excludedFromSerialization = $excludedFromSerialization; + return $this; } - /** - * @return string|null - */ public function getSerializationExclusionExpression(): ?string { return $this->serializationExclusionExpression; } - /** - * @param string|null $serializationExclusionExpression - * @return SimpleNodeTypeField - */ public function setSerializationExclusionExpression(?string $serializationExclusionExpression): SimpleNodeTypeField { $this->serializationExclusionExpression = $serializationExclusionExpression; + return $this; } - /** - * @return int|null - */ public function getSerializationMaxDepth(): ?int { return $this->serializationMaxDepth; } - /** - * @param int|null $serializationMaxDepth - * @return SimpleNodeTypeField - */ public function setSerializationMaxDepth(?int $serializationMaxDepth): SimpleNodeTypeField { $this->serializationMaxDepth = $serializationMaxDepth; + return $this; } }