diff --git a/example/out/Simple/SimpleObjectTransfer.php b/example/out/Simple/SimpleObjectTransfer.php deleted file mode 100644 index 89543ef..0000000 --- a/example/out/Simple/SimpleObjectTransfer.php +++ /dev/null @@ -1,94 +0,0 @@ -weight; - } - - public function getHeight(): int|null - { - return $this->height; - } - - public function getParent(): SimpleObjectTransfer|null - { - return $this->parent; - } - - public function setWeight(int|null $weight): self - { - $this->weight = $weight; - - return $this; - } - - public function setHeight(int|null $height): self - { - $this->height = $height; - - return $this; - } - - public function setParent(SimpleObjectTransfer|null $parent): self - { - $this->parent = $parent; - - return $this; - } - - protected static function attributesMetadata(): array - { - return array ( - 'weight' => - array ( - 'type' => - array ( - 0 => 'int', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'weight', - ), - 'height' => - array ( - 'type' => - array ( - 0 => 'int', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'height', - ), - 'parent' => - array ( - 'type' => - array ( - 0 => 'Transfer\\Simple\\SimpleObjectTransfer', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'parent', - ), - ); - } -} diff --git a/example/out/Simple/SimpleUserTransfer.php b/example/out/Simple/SimpleUserTransfer.php deleted file mode 100644 index 00f8ebd..0000000 --- a/example/out/Simple/SimpleUserTransfer.php +++ /dev/null @@ -1,533 +0,0 @@ -parent; - } - - public function getUsername(): string|null - { - return $this->username; - } - - public function getAge(): int|null - { - return $this->age; - } - - public function getEmail(): string|null - { - return $this->email; - } - - public function getIp(): string|null - { - return $this->ip; - } - - public function getHostname(): string|null - { - return $this->hostname; - } - - public function getSometext(): string|null - { - return $this->sometext; - } - - public function getUrl(): string|null - { - return $this->url; - } - - public function getJson(): string|null - { - return $this->json; - } - - public function getUuid(): string|null - { - return $this->uuid; - } - - public function getCreatedAt(): string|null - { - return $this->created_at; - } - - public function getUpdatedAt(): string|null - { - return $this->updated_at; - } - - public function getTimezone(): string|null - { - return $this->timezone; - } - - public function getCardScheme(): string|null - { - return $this->card_scheme; - } - - public function getBic(): string|null - { - return $this->bic; - } - - public function getCurrency(): string|null - { - return $this->currency; - } - - public function getIban(): string|null - { - return $this->iban; - } - - public function getIsbn(): string|null - { - return $this->isbn; - } - - public function getIssn(): string|null - { - return $this->issn; - } - - public function getIsin(): string|null - { - return $this->isin; - } - - public function setParent(SimpleObjectTransfer|null $parent): self - { - $this->parent = $parent; - - return $this; - } - - public function setUsername(string|null $username): self - { - $this->username = $username; - - return $this; - } - - public function setAge(int|null $age): self - { - $this->age = $age; - - return $this; - } - - public function setEmail(string|null $email): self - { - $this->email = $email; - - return $this; - } - - public function setIp(string|null $ip): self - { - $this->ip = $ip; - - return $this; - } - - public function setHostname(string|null $hostname): self - { - $this->hostname = $hostname; - - return $this; - } - - public function setSometext(string|null $sometext): self - { - $this->sometext = $sometext; - - return $this; - } - - public function setUrl(string|null $url): self - { - $this->url = $url; - - return $this; - } - - public function setJson(string|null $json): self - { - $this->json = $json; - - return $this; - } - - public function setUuid(string|null $uuid): self - { - $this->uuid = $uuid; - - return $this; - } - - public function setCreatedAt(string|null $created_at): self - { - $this->created_at = $created_at; - - return $this; - } - - public function setUpdatedAt(string|null $updated_at): self - { - $this->updated_at = $updated_at; - - return $this; - } - - public function setTimezone(string|null $timezone): self - { - $this->timezone = $timezone; - - return $this; - } - - public function setCardScheme(string|null $card_scheme): self - { - $this->card_scheme = $card_scheme; - - return $this; - } - - public function setBic(string|null $bic): self - { - $this->bic = $bic; - - return $this; - } - - public function setCurrency(string|null $currency): self - { - $this->currency = $currency; - - return $this; - } - - public function setIban(string|null $iban): self - { - $this->iban = $iban; - - return $this; - } - - public function setIsbn(string|null $isbn): self - { - $this->isbn = $isbn; - - return $this; - } - - public function setIssn(string|null $issn): self - { - $this->issn = $issn; - - return $this; - } - - public function setIsin(string|null $isin): self - { - $this->isin = $isin; - - return $this; - } - - protected static function attributesMetadata(): array - { - return array ( - 'parent' => - array ( - 'type' => - array ( - 0 => 'Transfer\\Simple\\SimpleObjectTransfer', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'parent', - ), - 'username' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'username', - ), - 'age' => - array ( - 'type' => - array ( - 0 => 'int', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'age', - ), - 'email' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'email', - ), - 'ip' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'ip', - ), - 'hostname' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'hostname', - ), - 'sometext' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'sometext', - ), - 'url' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'url', - ), - 'json' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'json', - ), - 'uuid' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'uuid', - ), - 'created_at' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'createdAt', - ), - 'updated_at' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'updatedAt', - ), - 'timezone' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'timezone', - ), - 'card_scheme' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'cardScheme', - ), - 'bic' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'bic', - ), - 'currency' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'currency', - ), - 'iban' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'iban', - ), - 'isbn' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'isbn', - ), - 'issn' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'issn', - ), - 'isin' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'isin', - ), - ); - } -} diff --git a/example/out/UserTransfer.php b/example/out/UserTransfer.php deleted file mode 100644 index 2c436aa..0000000 --- a/example/out/UserTransfer.php +++ /dev/null @@ -1,181 +0,0 @@ -username; - } - - public function getBooks(): iterable|null - { - return $this->books; - } - - public function getFirstName(): string|int - { - return $this->first_name; - } - - public function getUpdatedAt(): DateTimeInterface|null - { - return $this->updatedAt; - } - - public function getSomeclass(): AbstractDto|null - { - return $this->someclass; - } - - public function getTestMixed(): mixed - { - return $this->testMixed; - } - - public function setUsername(string|int|null $username): self - { - $this->username = $username; - - return $this; - } - - public function setBooks(iterable|null $books): self - { - if(!$books) { - $this->books = null; - - return $this; - } - - if(!$this->books) { - $this->books = new Collection(); - } - - foreach($books as $item) { - $this->books->add($item); - } - - return $this; - } - - public function setFirstName(string|int $first_name): self - { - $this->first_name = $first_name; - - return $this; - } - - public function setUpdatedAt(DateTimeInterface|null $updatedAt): self - { - $this->updatedAt = $updatedAt; - - return $this; - } - - public function setSomeclass(AbstractDto|null $someclass): self - { - $this->someclass = $someclass; - - return $this; - } - - public function setTestMixed(mixed $testMixed): self - { - $this->testMixed = $testMixed; - - return $this; - } - - protected static function attributesMetadata(): array - { - return array ( - 'username' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'int', - 2 => 'null', - ), - 'required' => false, - 'actionName' => 'username', - ), - 'books' => - array ( - 'type' => - array ( - 0 => 'iterable', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'books', - ), - 'first_name' => - array ( - 'type' => - array ( - 0 => 'string', - 1 => 'int', - ), - 'required' => true, - 'actionName' => 'firstName', - ), - 'updatedAt' => - array ( - 'type' => - array ( - 0 => 'DateTimeInterface', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'updatedAt', - ), - 'someclass' => - array ( - 'type' => - array ( - 0 => 'Micro\\Library\\DTO\\Object\\AbstractDto', - 1 => 'null', - ), - 'required' => false, - 'actionName' => 'someclass', - ), - 'testMixed' => - array ( - 'type' => - array ( - 0 => 'mixed', - ), - 'required' => false, - 'actionName' => 'testMixed', - ), - ); - } -} diff --git a/src/ClassDef/PropertyDefinition.php b/src/ClassDef/PropertyDefinition.php index ce0ebca..c8ad82d 100644 --- a/src/ClassDef/PropertyDefinition.php +++ b/src/ClassDef/PropertyDefinition.php @@ -27,7 +27,7 @@ class PropertyDefinition private array $types = []; /** - * @var array + * @var array> */ private array $attributes = []; @@ -126,11 +126,9 @@ public function setIsCollection(bool $isCollection): void */ public function addAttribute(string $attributeName, array $arguments): self { - if (!\array_key_exists($attributeName, $this->attributes)) { - $this->attributes[$attributeName] = []; - } - - $this->attributes[$attributeName] = array_merge($this->attributes[$attributeName], $arguments); + $this->attributes[] = [ + $attributeName => $arguments, + ]; return $this; } diff --git a/src/Preparation/Processor/Property/Assert/AbstractComparisonStrategy.php b/src/Preparation/Processor/Property/Assert/AbstractComparisonStrategy.php index e573fa7..59569fa 100644 --- a/src/Preparation/Processor/Property/Assert/AbstractComparisonStrategy.php +++ b/src/Preparation/Processor/Property/Assert/AbstractComparisonStrategy.php @@ -18,9 +18,13 @@ abstract class AbstractComparisonStrategy extends AbstractConstraintStrategy protected function generateArguments(array $config): array { $parent = parent::generateArguments($config); + $value = $config['value'] ?? false; + $int = (int) $value; + $float = (float) $value; + $current = [ 'propertyPath' => $config['property_path'] ?? null, - 'value' => $config['value'] ?? null, + 'value' => ($int == $float) ? $int : $float, ]; return array_filter(array_merge($parent, $current)); diff --git a/src/Preparation/Processor/Property/Assert/AbstractConstraintStrategy.php b/src/Preparation/Processor/Property/Assert/AbstractConstraintStrategy.php index bef77a6..a356460 100644 --- a/src/Preparation/Processor/Property/Assert/AbstractConstraintStrategy.php +++ b/src/Preparation/Processor/Property/Assert/AbstractConstraintStrategy.php @@ -21,14 +21,14 @@ abstract class AbstractConstraintStrategy implements PropertyProcessorInterface { public function process(PropertyDefinition $propertyDefinition, ClassDefinition $classDefinition, array $propertyData, array $classList): void { - foreach ($propertyData as $config) { - $validatorData = $config[$this->getValidatorProperty()] ?? null; - if (null === $validatorData) { - continue; - } - - $this->addAttribute($propertyDefinition, $this->getAttributeClassName(), $this->generateArguments($validatorData)); + $validatorProperty = $this->getValidatorProperty(); + if (!isset($propertyData[$validatorProperty])) { + return; } + + $validatorData = $propertyData[$validatorProperty] ?? []; + + $this->addAttribute($propertyDefinition, $this->generateArguments($validatorData)); } protected function stringToBool(string $boolValue): bool @@ -56,7 +56,7 @@ protected function explodeString(string $string, string $separator = ','): array /** * @param array $arguments */ - protected function addAttribute(PropertyDefinition $propertyDefinition, string $attributeClass, array $arguments): void + protected function addAttribute(PropertyDefinition $propertyDefinition, array $arguments): void { $propertyDefinition->addAttribute($this->getAttributeClassName(), $arguments); } @@ -70,7 +70,7 @@ protected function generateArguments(array $config): array { return array_filter([ 'message' => $config['message'] ?? null, - 'groups' => $this->explodeString($config['groups']), + 'groups' => $this->explodeString($config['groups'] ?? 'Default'), ]); } diff --git a/src/Preparation/Processor/Property/AttributeValidationProcessor.php b/src/Preparation/Processor/Property/AttributeValidationProcessor.php index 9bb41e9..58d802a 100644 --- a/src/Preparation/Processor/Property/AttributeValidationProcessor.php +++ b/src/Preparation/Processor/Property/AttributeValidationProcessor.php @@ -32,8 +32,31 @@ public function process(PropertyDefinition $propertyDefinition, ClassDefinition return; } - foreach ($this->validatorProcessor as $processor) { - $processor->process($propertyDefinition, $classDefinition, $propertyData['validation'], $classList); + $propertyValidationConstraints = $propertyData['validation']; + foreach ($propertyValidationConstraints as $constraint) { + $this->processAddConstraints($propertyDefinition, $classDefinition, $constraint, $classList); + } + } + + /** + * @param PropertyDefinition $propertyDefinition + * @param ClassDefinition $classDefinition + * @param array> $constraints + * @param string[] $classList + * + * @return void + */ + protected function processAddConstraints(PropertyDefinition $propertyDefinition, ClassDefinition $classDefinition, array $constraints, array $classList): void + { + foreach ($constraints as $constraint) { + foreach ($this->validatorProcessor as $processor) { + /** + * @phpstan-ignore-next-line + * + * @psalm-suppress InvalidArrayOffset + */ + $processor->process($propertyDefinition, $classDefinition, [$constraint[0] => $constraint[1]], $classList); + } } } } diff --git a/src/Reader/XmlReader.php b/src/Reader/XmlReader.php index f901b27..127d96f 100755 --- a/src/Reader/XmlReader.php +++ b/src/Reader/XmlReader.php @@ -152,11 +152,7 @@ protected function parseValidation(\DOMNode $attribute): array|null $constraintAttributes = []; } - if (!\array_key_exists('groups', $constraintAttributes)) { - $constraintAttributes['groups'] = 'Default'; - } - - $groupConstraints[$constraintNode->nodeName] = $constraintAttributes; + $groupConstraints[] = [$constraintNode->nodeName, $constraintAttributes]; } $constraints[] = $groupConstraints; diff --git a/src/View/Nette/NetteRenderer.php b/src/View/Nette/NetteRenderer.php index d7fc666..2733951 100644 --- a/src/View/Nette/NetteRenderer.php +++ b/src/View/Nette/NetteRenderer.php @@ -94,8 +94,10 @@ protected function provideProperty(ClassType $classType, PropertyDefinition $pro $property->addComment($comment); } - foreach ($propertyDefinition->getAttributes() as $attribute => $arguments) { - $property->addAttribute($attribute, $arguments); + foreach ($propertyDefinition->getAttributes() as $attribute) { + foreach ($attribute as $attrName => $attrArgs) { + $property->addAttribute($attrName, $attrArgs); + } } $classType->addMember($property); diff --git a/tests/Unit/Out/Simple/SimpleObjectTransfer.php b/tests/Unit/Out/Simple/SimpleObjectTransfer.php index a3fd9ad..ee40c10 100644 --- a/tests/Unit/Out/Simple/SimpleObjectTransfer.php +++ b/tests/Unit/Out/Simple/SimpleObjectTransfer.php @@ -13,7 +13,7 @@ final class SimpleObjectTransfer extends \Micro\Library\DTO\Object\AbstractDto { - #[\Symfony\Component\Validator\Constraints\LessThan(groups: ['Default'], value: '10')] + #[\Symfony\Component\Validator\Constraints\LessThan(groups: ['Default'], value: 10)] protected int|null $weight = null; #[\Symfony\Component\Validator\Constraints\LessThan(groups: ['Default'], propertyPath: 'weight')] diff --git a/tests/Unit/Out/Simple/SimpleUserTransfer.php b/tests/Unit/Out/Simple/SimpleUserTransfer.php index 5510e28..558b2af 100644 --- a/tests/Unit/Out/Simple/SimpleUserTransfer.php +++ b/tests/Unit/Out/Simple/SimpleUserTransfer.php @@ -14,13 +14,13 @@ final class SimpleUserTransfer extends \Micro\Library\DTO\Object\AbstractDto { protected SimpleObjectTransfer|null $parent = null; - #[\Symfony\Component\Validator\Constraints\Regex(groups: ['Default'], pattern: '/^(.[aA-zA]+)$/', match: true)] #[\Symfony\Component\Validator\Constraints\Length(groups: ['Default'], max: 50, min: 6)] + #[\Symfony\Component\Validator\Constraints\Regex(groups: ['Default'], pattern: '/^(.[aA-zA]+)$/', match: true)] protected string|null $username = null; #[\Symfony\Component\Validator\Constraints\NotBlank(groups: ['Default'], allowNull: false)] - #[\Symfony\Component\Validator\Constraints\GreaterThan(groups: ['Default'], value: '18')] - #[\Symfony\Component\Validator\Constraints\LessThan(groups: ['Default'], value: '100')] + #[\Symfony\Component\Validator\Constraints\GreaterThan(groups: ['Default'], value: 18)] + #[\Symfony\Component\Validator\Constraints\LessThan(groups: ['Default'], value: 100)] protected int|null $age = null; #[\Symfony\Component\Validator\Constraints\Email(groups: ['Default'], mode: 'html5')] @@ -30,6 +30,7 @@ final class SimpleUserTransfer extends \Micro\Library\DTO\Object\AbstractDto #[\Symfony\Component\Validator\Constraints\Ip(groups: ['Default'], version: '4')] protected string|null $ip = null; + #[\Symfony\Component\Validator\Constraints\Hostname(groups: ['Default'], requireTld: false)] #[\Symfony\Component\Validator\Constraints\Hostname(groups: ['test'], requireTld: true)] protected string|null $hostname = null; diff --git a/tests/Unit/example.xml b/tests/Unit/example.xml index 38c6d9c..70ff1a0 100755 --- a/tests/Unit/example.xml +++ b/tests/Unit/example.xml @@ -6,7 +6,7 @@ - +