Skip to content

Commit b95d730

Browse files
committed
fix: Matching better organization
1 parent 9c9b4d3 commit b95d730

20 files changed

+468
-19
lines changed

README.md

+23-2
Original file line numberDiff line numberDiff line change
@@ -8,23 +8,44 @@
88

99
## Attributes
1010

11+
### Groups & Ignore<hr>
12+
13+
`#[Ignore()]` is like `#[Groups()]` with empty array of groups. If You do not define the groups for property, then `Default` will be assignment as a property group. Only `Origin` can decide about group assignment in the process.
14+
15+
| Declaration place | Normalization | Denormalization | Transformation |
16+
|:-:|:-:|:-:|:-:|
17+
| **Origin** | Source: ✔️<br>Target: ✔️ | Source: ✔️<br>Target: ✔️ | Source: ✔️<br>Target: ✔️ |
18+
| **Source** | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✖️ |
19+
| **Target** | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✖️ |
20+
21+
| Declaration place | Mapping |
22+
|:-:|:-:|
23+
| **Origin** | Source: ✔️<br>Target: ✔️ |
24+
| **Source** | Source: ✖️<br>Target: ✖️ |
25+
| **Target** | Source: ✖️<br>Target: ✖️ |
26+
27+
###### legend: ✖️ - *has no effect*, ✔️ - *affects*, ➖ - *not implemented*
28+
29+
> **INFO**<br>
30+
> The table is implemented by `PBaszak\UltraMapper\Mapper\Domain\Matcher\Matcher::matchClassBlueprints()`.
31+
1132
### TargetProperty<hr>
1233

1334
The behavior of the `#[TargetProperty()]` attribute depends on the class in which you declare it (*origin*, *source*, *target*). The table below presents the relationship between the declaration place and the active process, and how the attribute changes the name (or path) of the property. Placing an attribute in an origin class has no effect on any process unless the origin class is also a source class, a target class, or both.
1435

15-
##### NAME
16-
1736
Target Property attribute works like `Symfony\SerializedName` for Normalization, Denormalization and Transformation. It changes property name when data are normalized.
1837

1938
| Declaration place | Normalization | Denormalization | Transformation |
2039
|:-:|:-:|:-:|:-:|
40+
| **Origin** | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✖️ |
2141
| **Source** | Source: ✖️<br>Target: ✖️ | Source: ✔️<br>Target: ✖️ | Source: ✔️<br>Target: ✖️ |
2242
| **Target** | Source: ✖️<br>Target: ✔️ | Source: ✖️<br>Target: ✖️ | Source: ✖️<br>Target: ✔️ |
2343

2444
Target Property attribute links properties from different blueprints for Mapping. It works with other processes or alone.
2545

2646
| Declaration place | Mapping |
2747
|:-:|:-:|
48+
| **Origin** | Source: ✖️<br>Target: ✖️ |
2849
| **Source** | Source: ✖️<br>Target: ✔️ |
2950
| **Target** | Source: ✔️<br>Target: ✖️ |
3051

src/Blueprint/Application/Model/Assets/PropertyBlueprint.php

+15
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PBaszak\UltraMapper\Blueprint\Application\Enum\Visibility;
88
use PBaszak\UltraMapper\Blueprint\Application\Model\Type;
9+
use PBaszak\UltraMapper\Mapper\Application\Attribute\Groups;
910
use PBaszak\UltraMapper\Shared\Infrastructure\Normalization\Normalizable;
1011

1112
class PropertyBlueprint implements Normalizable
@@ -96,6 +97,20 @@ public function getReflection(): \ReflectionProperty
9697
return new \ReflectionProperty($this->class->name, $this->originName);
9798
}
9899

100+
/**
101+
* @return object[]
102+
*/
103+
public function getAttributes(string $class): array
104+
{
105+
/** @var array<AttributeBlueprint> $attrs */
106+
$attrs = $this->attributes[$class];
107+
108+
/** @var object[] $attrs */
109+
array_walk($attrs, fn (AttributeBlueprint $attr): object => $attr->newInstance());
110+
111+
return $attrs;
112+
}
113+
99114
public function normalize(): array
100115
{
101116
return [

src/Mapper/Application/Attribute/Groups.php

+6
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class Groups implements AttributeInterface
1818
*/
1919
public function __construct(
2020
public readonly string|array $groups,
21+
public int $processType = self::DENORMALIZATION | self::NORMALIZATION | self::TRANSFORMATION | self::MAPPING,
2122
public readonly array $options = []
2223
) {
2324
}
@@ -26,4 +27,9 @@ public function validate(\ReflectionProperty|\ReflectionParameter|\ReflectionCla
2627
{
2728
// todo implement
2829
}
30+
31+
public function getProcessType(): int
32+
{
33+
return $this->processType;
34+
}
2935
}

src/Mapper/Application/Attribute/Ignore.php

+5-12
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,6 @@ class Ignore implements AttributeInterface
1313
{
1414
use ThrowAttributeValidationExceptionTrait;
1515

16-
public const DENORMALIZATION = 1; // 0001
17-
public const NORMALIZATION = 2; // 0010
18-
public const MAPPING = 4; // 0100
19-
public const TRANSFORMATION = 8; // 1000
20-
21-
public const PROCESS_TYPE_MAP = [
22-
Process::DENORMALIZATION_PROCESS => self::DENORMALIZATION,
23-
Process::NORMALIZATION_PROCESS => self::NORMALIZATION,
24-
Process::MAPPING_PROCESS => self::MAPPING,
25-
Process::TRANSFORMATION_PROCESS => self::TRANSFORMATION,
26-
];
27-
2816
/**
2917
* @param array<string, mixed> $options Options are for modificators of the mapping process. If You need them, You can use them.
3018
*/
@@ -38,4 +26,9 @@ public function validate(\ReflectionProperty|\ReflectionParameter|\ReflectionCla
3826
{
3927
// todo implement
4028
}
29+
30+
public function getProcessType(): int
31+
{
32+
return $this->processType;
33+
}
4134
}

src/Mapper/Application/Contract/AttributeInterface.php

+16
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,23 @@
44

55
namespace PBaszak\UltraMapper\Mapper\Application\Contract;
66

7+
use PBaszak\UltraMapper\Mapper\Domain\Model\Process;
8+
79
interface AttributeInterface
810
{
11+
public const DENORMALIZATION = 1; // 0001
12+
public const NORMALIZATION = 2; // 0010
13+
public const MAPPING = 4; // 0100
14+
public const TRANSFORMATION = 8; // 1000
15+
16+
public const PROCESS_TYPE_MAP = [
17+
Process::DENORMALIZATION_PROCESS => self::DENORMALIZATION,
18+
Process::NORMALIZATION_PROCESS => self::NORMALIZATION,
19+
Process::MAPPING_PROCESS => self::MAPPING,
20+
Process::TRANSFORMATION_PROCESS => self::TRANSFORMATION,
21+
];
22+
923
public function validate(\ReflectionProperty|\ReflectionParameter|\ReflectionClass $reflection): void;
24+
25+
public function getProcessType(): int;
1026
}

src/Mapper/Application/Model/Context.php

+12
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,16 @@ public function __construct(
1515
public bool $isCollection = false,
1616
) {
1717
}
18+
19+
/**
20+
* @param string[] $groups
21+
*
22+
* @return bool Success if the group is matching.
23+
*/
24+
public function isGroupMatching(array $groups): bool
25+
{
26+
$groups = empty($groups) ? ['Default'] : $groups;
27+
28+
return !empty(array_intersect($this->groups, $groups));
29+
}
1830
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PBaszak\UltraMapper\Mapper\Domain\Matcher\Contract;
6+
7+
use PBaszak\UltraMapper\Blueprint\Application\Model\Assets\ClassBlueprint;
8+
use PBaszak\UltraMapper\Mapper\Application\Model\Context;
9+
use PBaszak\UltraMapper\Mapper\Domain\Model\Process;
10+
11+
interface ClassMatchingStrategy
12+
{
13+
/**
14+
* Method checks if the strategy conditions are met.
15+
*
16+
* @return bool Success if the conditions are met.
17+
*/
18+
public function isStrategyConditionsMet(
19+
Context $context,
20+
Process $process,
21+
ClassBlueprint $origin,
22+
ClassBlueprint $source,
23+
ClassBlueprint $target
24+
): bool;
25+
26+
/**
27+
* Method matches classes in the way defined by the strategy.
28+
*
29+
* @return void
30+
*/
31+
public function matchClasses(
32+
Context $context,
33+
Process $process,
34+
ClassBlueprint $origin,
35+
ClassBlueprint $source,
36+
ClassBlueprint $target
37+
): void;
38+
}

src/Mapper/Domain/Contract/MatcherInterface.php src/Mapper/Domain/Matcher/Contract/MatcherInterface.php

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace PBaszak\UltraMapper\Mapper\Domain\Contract;
5+
namespace PBaszak\UltraMapper\Mapper\Domain\Matcher\Contract;
66

77
use PBaszak\UltraMapper\Blueprint\Application\Model\Blueprint;
88
use PBaszak\UltraMapper\Mapper\Application\Contract\MapperInterface;
@@ -16,9 +16,12 @@ interface MatcherInterface
1616
public const OPTION_SOURCE = MapperInterface::FROM_PROCESS_USE;
1717
public const OPTION_TARGET = MapperInterface::TO_PROCESS_USE;
1818

19+
/**
20+
* Main method of the matcher. It matches blueprints and their all assets.
21+
*/
1922
public function matchBlueprints(
2023
Context $context,
21-
Process $processType,
24+
Process $process,
2225
Blueprint $origin,
2326
Blueprint $source,
2427
Blueprint $target
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PBaszak\UltraMapper\Mapper\Domain\Matcher\Contract;
6+
7+
use PBaszak\UltraMapper\Blueprint\Application\Model\Assets\PropertyBlueprint;
8+
use PBaszak\UltraMapper\Mapper\Application\Model\Context;
9+
use PBaszak\UltraMapper\Mapper\Domain\Model\Process;
10+
11+
interface PropertyMatchingStrategy
12+
{
13+
/**
14+
* Method checks if the strategy conditions are met.
15+
*
16+
* @return bool Success if the conditions are met.
17+
*/
18+
public function isStrategyConditionsMet(
19+
Context $context,
20+
Process $process,
21+
PropertyBlueprint $origin,
22+
PropertyBlueprint $source,
23+
PropertyBlueprint $target
24+
): bool;
25+
26+
/**
27+
* Method matches properties in the way defined by the strategy.
28+
*
29+
* @return void
30+
*/
31+
public function matchProperties(
32+
Context $context,
33+
Process $process,
34+
PropertyBlueprint $origin,
35+
PropertyBlueprint $source,
36+
PropertyBlueprint $target
37+
): void;
38+
}

src/Mapper/Domain/Exception/PropertyNotMatchedException.php src/Mapper/Domain/Matcher/Exception/PropertyNotMatchedException.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
declare(strict_types=1);
44

5-
namespace PBaszak\UltraMapper\Mapper\Domain\Exception;
5+
namespace PBaszak\UltraMapper\Mapper\Domain\Matcher\Exception;
66

77
use PBaszak\UltraMapper\Shared\Application\Exception\UltraMapperException;
88

0 commit comments

Comments
 (0)