-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
ee1df74
commit 7a3d5d7
Showing
6 changed files
with
297 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PBaszak\UltraMapper\Mapper\Application\Attribute; | ||
|
||
use Attribute; | ||
use PBaszak\UltraMapper\Mapper\Application\Exception\UltraMapperAttributeValidationException; | ||
use UltraMapper\Mapper\Application\Attribute\UltraMapperAttribute; | ||
|
||
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)] | ||
final class Accessor extends UltraMapperAttribute | ||
{ | ||
public const SETTER = 1; | ||
public const GETTER = 2; | ||
|
||
/** | ||
* The accessor attribute allows you to define your own accessor function that will be executed during the mapping process. | ||
* | ||
* @param string $method The method name that will be executed. It must be a public method inside same class as property. | ||
* @param int $type The type of the accessor. It can be either a setter or a getter. | ||
*/ | ||
public function __construct( | ||
private string $method, | ||
private int $type = self::GETTER, | ||
int $processType = UltraMapperAttribute::PROCESS_DENORMALIZATION | UltraMapperAttribute::PROCESS_NORMALIZATION | UltraMapperAttribute::PROCESS_TRANSFORMATION | UltraMapperAttribute::PROCESS_MAPPING, | ||
array $options = [], | ||
) { | ||
parent::__construct($processType, $options); | ||
} | ||
|
||
public function method(): string | ||
{ | ||
return $this->method; | ||
} | ||
|
||
public function type(): int | ||
{ | ||
return $this->type; | ||
} | ||
|
||
public function validate(\Reflector $reflection): void | ||
{ | ||
if (!$reflection instanceof \ReflectionProperty) { | ||
throw new UltraMapperAttributeValidationException('The accessor attribute can only be applied to properties.', 'Make sure that the function which initialize a validation do it correctly.'); | ||
} | ||
|
||
if (!method_exists($class = $reflection->getDeclaringClass()->getName(), $this->method)) { | ||
throw new UltraMapperAttributeValidationException(sprintf('The method %s does not exist.', $this->method), 'Make sure that the method '.$this->method.' exists in the class '.$class.'.'); | ||
} | ||
|
||
if (self::SETTER !== $this->type && self::GETTER !== $this->type) { | ||
throw new UltraMapperAttributeValidationException(sprintf('The type %d is not supported.', $this->type), 'The type must be either a setter or a getter.'); | ||
} | ||
} | ||
} |
53 changes: 53 additions & 0 deletions
53
src/Mapper/Application/Attribute/ApplyToCollectionItem.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PBaszak\UltraMapper\Mapper\Application\Attribute; | ||
|
||
use Attribute; | ||
use PBaszak\UltraMapper\Mapper\Application\Exception\UltraMapperAttributeValidationException; | ||
use UltraMapper\Mapper\Application\Attribute\UltraMapperAttribute; | ||
|
||
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)] | ||
final class ApplyToCollectionItem extends UltraMapperAttribute | ||
{ | ||
/** | ||
* The apply to collection item attribute allows you to apply the attribute to the collection item. | ||
* | ||
* @param object[] $attributes the attributes that will be applied to the collection item | ||
*/ | ||
public function __construct( | ||
private array $attributes, | ||
int $processType = UltraMapperAttribute::PROCESS_DENORMALIZATION | UltraMapperAttribute::PROCESS_NORMALIZATION | UltraMapperAttribute::PROCESS_TRANSFORMATION | UltraMapperAttribute::PROCESS_MAPPING, | ||
array $options = [], | ||
) { | ||
parent::__construct($processType, $options); | ||
} | ||
|
||
/** | ||
* Returns the attributes. | ||
* | ||
* @return object[] the attributes | ||
*/ | ||
public function attributes(): array | ||
{ | ||
return $this->attributes; | ||
} | ||
|
||
public function validate(\Reflector $reflection): void | ||
{ | ||
if (!$reflection instanceof \ReflectionProperty) { | ||
throw new UltraMapperAttributeValidationException('The apply to collection item attribute can only be applied to properties.', 'Make sure that the function which initialize a validation do it correctly.'); | ||
} | ||
|
||
if (empty($this->attributes)) { | ||
throw new UltraMapperAttributeValidationException('The apply to collection item attribute must have at least one attribute.', 'You should remove unused '.__CLASS__.' attribute in '.$reflection->getDeclaringClass()->getName().'::'.$reflection->getName().' property.'); | ||
} | ||
|
||
foreach ($this->attributes as $attribute) { | ||
if ($attribute instanceof UltraMapperAttribute) { | ||
$attribute->validate($reflection); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PBaszak\UltraMapper\Mapper\Application\Attribute; | ||
|
||
use Attribute; | ||
use PBaszak\UltraMapper\Mapper\Application\Exception\UltraMapperAttributeValidationException; | ||
use UltraMapper\Mapper\Application\Attribute\UltraMapperAttribute; | ||
|
||
#[\Attribute(\Attribute::TARGET_METHOD)] | ||
final class Constructor extends UltraMapperAttribute | ||
{ | ||
/** | ||
* The constructor attribute allows You to define static constructor | ||
* method that will be executed during the mapping process. | ||
*/ | ||
public function __construct( | ||
int $processType = UltraMapperAttribute::PROCESS_DENORMALIZATION | UltraMapperAttribute::PROCESS_NORMALIZATION | UltraMapperAttribute::PROCESS_TRANSFORMATION | UltraMapperAttribute::PROCESS_MAPPING, | ||
array $options = [], | ||
) { | ||
parent::__construct($processType, $options); | ||
} | ||
|
||
public function validate(\Reflector $reflection): void | ||
{ | ||
if (!$reflection instanceof \ReflectionMethod) { | ||
throw new UltraMapperAttributeValidationException('The constructor attribute can only be applied to methods.', 'Make sure that the function which initialize a validation do it correctly.'); | ||
} | ||
|
||
if (!$reflection->isStatic()) { | ||
throw new UltraMapperAttributeValidationException('The constructor attribute can only be applied to static methods.', 'Make sure that the method '.$reflection->getDeclaringClass()->getName().'::'.$reflection->getName().'() is static.'); | ||
} | ||
|
||
if (!$reflection->isPublic()) { | ||
throw new UltraMapperAttributeValidationException('The constructor attribute can only be applied to public methods.', 'Make sure that the method '.$reflection->getDeclaringClass()->getName().'::'.$reflection->getName().'() is public.'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace UltraMapper\Mapper\Application\Attribute; | ||
|
||
use Attribute; | ||
use PBaszak\UltraMapper\Mapper\Application\Exception\UltraMapperAttributeValidationException; | ||
|
||
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::IS_REPEATABLE)] | ||
final class Discriminator extends UltraMapperAttribute | ||
{ | ||
public const DISCRIMINATOR_PROPERTY_IN_SAME_CLASS = 1; | ||
public const DISCRIMINATOR_PROPERTY_IN_PARENT_CLASS = 2; | ||
|
||
/** | ||
* The discriminator attribute allows You to define how to solve multiple types of objects in one property. | ||
* | ||
* @param string $property the property name that will be used as a discriminator | ||
* @param array<int|string, class-string> $map the map of the discriminator values to the class names | ||
* @param int $propertySource where to look for the discriminator property | ||
*/ | ||
public function __construct( | ||
private string $property, | ||
private array $map, | ||
private int $propertySource = self::DISCRIMINATOR_PROPERTY_IN_SAME_CLASS, | ||
int $processType = UltraMapperAttribute::PROCESS_DENORMALIZATION | UltraMapperAttribute::PROCESS_NORMALIZATION | UltraMapperAttribute::PROCESS_TRANSFORMATION | UltraMapperAttribute::PROCESS_MAPPING, | ||
array $options = [], | ||
) { | ||
parent::__construct($processType, $options); | ||
} | ||
|
||
public function property(): string | ||
{ | ||
return $this->property; | ||
} | ||
|
||
/** | ||
* Returns the map. | ||
* | ||
* @return array<int|string, class-string> the map | ||
*/ | ||
public function map(): array | ||
{ | ||
return $this->map; | ||
} | ||
|
||
public function propertySource(): int | ||
{ | ||
return $this->propertySource; | ||
} | ||
|
||
public function validate(\Reflector $reflection): void | ||
{ | ||
if (!$reflection instanceof \ReflectionProperty) { | ||
throw new UltraMapperAttributeValidationException('The discriminator attribute can only be applied to properties.', 'Make sure that the function which initialize a validation do it correctly.'); | ||
} | ||
|
||
if (!in_array($this->propertySource, [self::DISCRIMINATOR_PROPERTY_IN_SAME_CLASS, self::DISCRIMINATOR_PROPERTY_IN_PARENT_CLASS])) { | ||
throw new UltraMapperAttributeValidationException('The property source must be either in the same class or in the parent class.', 'Make sure that the property source is either in the same class or in the parent class.'); | ||
} | ||
|
||
if (empty($this->map)) { | ||
throw new UltraMapperAttributeValidationException('The map must have at least one entry.', 'Make sure that the map has at least one entry.'); | ||
} | ||
|
||
foreach ($this->map as $discriminatorValue => $class) { | ||
if (!class_exists($class, false)) { | ||
throw new UltraMapperAttributeValidationException(sprintf('The class %s does not exist.', $class), 'Make sure that the class '.$class.' exists.'); | ||
} | ||
|
||
if (self::DISCRIMINATOR_PROPERTY_IN_SAME_CLASS === $this->propertySource && !property_exists($class, $this->property)) { | ||
throw new UltraMapperAttributeValidationException(sprintf('The property %s does not exist in the class %s.', $this->property, $class), 'Make sure that the property '.$this->property.' exists in the class '.$class.'.'); | ||
} | ||
} | ||
|
||
if (self::DISCRIMINATOR_PROPERTY_IN_PARENT_CLASS === $this->propertySource && !property_exists($reflection->getDeclaringClass()->getName(), $this->property)) { | ||
throw new UltraMapperAttributeValidationException(sprintf('The property %s does not exist in the parent class %s.', $this->property, $reflection->getDeclaringClass()->getName()), 'Make sure that the property '.$this->property.' exists in the class '.$reflection->getDeclaringClass()->getName().'.'); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace UltraMapper\Mapper\Application\Attribute; | ||
|
||
use PBaszak\UltraMapper\Mapper\Application\Exception\UltraMapperAttributeValidationException; | ||
|
||
abstract class UltraMapperAttribute | ||
{ | ||
public const PROCESS_DENORMALIZATION = 1; | ||
public const PROCESS_NORMALIZATION = 2; | ||
public const PROCESS_TRANSFORMATION = 4; | ||
public const PROCESS_MAPPING = 8; | ||
|
||
public const OPTION_GROUPS = 'groups'; | ||
|
||
/** | ||
* @param int $processType the process type that the attribute should be applied to | ||
* @param array<string, mixed> $options The options used by Your code or the UltraMapper. For example, the `groups` option | ||
* allows you to specify the groups that the attribute should be applied to. | ||
*/ | ||
protected function __construct( | ||
protected int $processType = self::PROCESS_DENORMALIZATION | self::PROCESS_NORMALIZATION | self::PROCESS_TRANSFORMATION | self::PROCESS_MAPPING, | ||
protected array $options = [], | ||
) { | ||
} | ||
|
||
/** | ||
* Returns the process type. | ||
* | ||
* @return int the process type | ||
*/ | ||
public function processType(): int | ||
{ | ||
return $this->processType; | ||
} | ||
|
||
/** | ||
* Returns the options. | ||
* | ||
* @return array<string, mixed> the options | ||
*/ | ||
public function options(): array | ||
{ | ||
return $this->options; | ||
} | ||
|
||
/** | ||
* Validates the attribute. | ||
* | ||
* @param \Reflector $reflection the reflection object that the attribute is attached to | ||
* | ||
* @throws UltraMapperAttributeValidationException | ||
*/ | ||
abstract public function validate(\Reflector $reflection): void; | ||
} |
11 changes: 11 additions & 0 deletions
11
src/Mapper/Application/Exception/UltraMapperAttributeValidationException.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace PBaszak\UltraMapper\Mapper\Application\Exception; | ||
|
||
use PBaszak\UltraMapper\Shared\Application\Exception\UltraMapperException; | ||
|
||
class UltraMapperAttributeValidationException extends UltraMapperException | ||
{ | ||
} |