Skip to content

Commit fb3340e

Browse files
committed
ComposedValueProcessors
1 parent 941b1ec commit fb3340e

36 files changed

+722
-163
lines changed

src/Model/Property/Property.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,14 @@ public function getValidators(): array
9696
return $this->validator;
9797
}
9898

99+
/**
100+
* @inheritdoc
101+
*/
102+
public function filterValidators(callable $filter): void
103+
{
104+
$this->validator = array_filter($this->validator, $filter);
105+
}
106+
99107
/**
100108
* @inheritdoc
101109
*/

src/Model/Property/PropertyInterface.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,13 @@ public function addValidator(PropertyValidatorInterface $validator, int $priorit
5252
*/
5353
public function getValidators(): array;
5454

55+
/**
56+
* Filter the assigned validators
57+
*
58+
* @param callable $filter
59+
*/
60+
public function filterValidators(callable $filter): void;
61+
5562
/**
5663
* Retrieve all added validators ordered by priority
5764
*

src/Model/Property/PropertyProxy.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,14 @@ public function getValidators(): array
9090
return $this->getProperty()->getValidators();
9191
}
9292

93+
/**
94+
* @inheritdoc
95+
*/
96+
public function filterValidators(callable $filter): void
97+
{
98+
$this->getProperty()->filterValidators($filter);
99+
}
100+
93101
/**
94102
* @inheritdoc
95103
*/

src/Model/SchemaDefinition.php

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
use PHPModelGenerator\Model\Property\PropertyProxy;
1111
use PHPModelGenerator\PropertyProcessor\PropertyCollectionProcessor;
1212
use PHPModelGenerator\PropertyProcessor\PropertyFactory;
13+
use PHPModelGenerator\PropertyProcessor\PropertyProcessorFactory;
1314
use PHPModelGenerator\SchemaProcessor\SchemaProcessor;
1415

1516
/**
@@ -49,16 +50,20 @@ public function __construct(array $structure, SchemaProcessor $schemaProcessor,
4950
/**
5051
* Resolve a reference
5152
*
52-
* @param string $propertyName
53-
* @param array $path
53+
* @param string $propertyName
54+
* @param array $path
55+
* @param PropertyCollectionProcessor $propertyCollectionProcessor
5456
*
5557
* @return PropertyInterface
5658
*
5759
* @throws PHPModelGeneratorException
5860
* @throws SchemaException
5961
*/
60-
public function resolveReference(string $propertyName, array $path): PropertyInterface
61-
{
62+
public function resolveReference(
63+
string $propertyName,
64+
array $path,
65+
PropertyCollectionProcessor $propertyCollectionProcessor
66+
): PropertyInterface {
6267
$structure = $this->structure;
6368
while ($segment = array_shift($path)) {
6469
if (!isset($structure[$segment])) {
@@ -75,9 +80,9 @@ public function resolveReference(string $propertyName, array $path): PropertyInt
7580
// to the currently created property
7681
$this->resolvedPaths->offsetSet($key, true);
7782
try {
78-
$this->resolvedPaths->offsetSet($key, (new PropertyFactory())
83+
$this->resolvedPaths->offsetSet($key, (new PropertyFactory(new PropertyProcessorFactory()))
7984
->create(
80-
new PropertyCollectionProcessor(),
85+
$propertyCollectionProcessor,
8186
$this->schemaProcessor,
8287
$this->schema,
8388
$propertyName,
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
<?php
2+
3+
namespace PHPModelGenerator\Model\Validator;
4+
5+
use PHPModelGenerator\Exception\InvalidArgumentException;
6+
use PHPModelGenerator\Model\Property\PropertyInterface;
7+
8+
/**
9+
* Class RequiredPropertyValidator
10+
*
11+
* @package PHPModelGenerator\Model\Validator
12+
*/
13+
class RequiredPropertyValidator extends PropertyValidator
14+
{
15+
/**
16+
* RequiredPropertyValidator constructor.
17+
*
18+
* @param PropertyInterface $property
19+
*/
20+
public function __construct(PropertyInterface $property)
21+
{
22+
parent::__construct(
23+
"!isset(\$modelData['{$property->getName()}'])",
24+
InvalidArgumentException::class,
25+
"Missing required value for {$property->getName()}"
26+
);
27+
}
28+
}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<?php
2+
3+
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
4+
5+
use PHPModelGenerator\Exception\InvalidArgumentException;
6+
use PHPModelGenerator\Model\Property\PropertyInterface;
7+
use PHPModelGenerator\Model\Validator;
8+
use PHPModelGenerator\Model\Validator\PropertyTemplateValidator;
9+
use PHPModelGenerator\Model\Validator\RequiredPropertyValidator;
10+
use PHPModelGenerator\PropertyProcessor\Property\AbstractTypedValueProcessor;
11+
use PHPModelGenerator\PropertyProcessor\PropertyCollectionProcessor;
12+
use PHPModelGenerator\PropertyProcessor\PropertyFactory;
13+
use PHPModelGenerator\PropertyProcessor\PropertyProcessorFactory;
14+
use PHPModelGenerator\Utils\RenderHelper;
15+
16+
/**
17+
* Class AbstractComposedValueProcessor
18+
*
19+
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
20+
*/
21+
abstract class AbstractComposedValueProcessor extends AbstractTypedValueProcessor
22+
{
23+
/**
24+
* @inheritdoc
25+
*/
26+
protected function generateValidators(PropertyInterface $property, array $propertyData): void
27+
{
28+
$propertyFactory = new PropertyFactory(new PropertyProcessorFactory());
29+
30+
$properties = [];
31+
foreach ($propertyData['composition'] as $compositionElement) {
32+
$compositionProperty = $propertyFactory
33+
->create(
34+
new PropertyCollectionProcessor([$property->getName() => $property->isRequired()]),
35+
$this->schemaProcessor,
36+
$this->schema,
37+
$property->getName(),
38+
$compositionElement
39+
);
40+
41+
$compositionProperty->filterValidators(function (Validator $validator) {
42+
return !is_a($validator->getValidator(), RequiredPropertyValidator::class);
43+
});
44+
45+
$properties[] = $compositionProperty;
46+
}
47+
48+
$availableAmount = count($properties);
49+
50+
$property->addValidator(
51+
new PropertyTemplateValidator(
52+
InvalidArgumentException::class,
53+
"Invalid value for {$property->getName()} declined by composition constraint",
54+
DIRECTORY_SEPARATOR . 'Validator' . DIRECTORY_SEPARATOR . 'ComposedItem.phptpl',
55+
[
56+
'properties' => $properties,
57+
'viewHelper' => new RenderHelper(),
58+
'availableAmount' => $availableAmount,
59+
'composedValueValidation' => $this->getComposedValueValidation($availableAmount),
60+
]
61+
),
62+
100
63+
);
64+
}
65+
66+
/**
67+
* @param int $composedElements The amount of elements which are composed together
68+
*
69+
* @return string
70+
*/
71+
abstract function getComposedValueValidation(int $composedElements): string;
72+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
4+
5+
/**
6+
* Class AllofProcessor
7+
*
8+
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
9+
*/
10+
class AllOfProcessor extends AbstractComposedValueProcessor
11+
{
12+
/**
13+
* @inheritdoc
14+
*/
15+
function getComposedValueValidation(int $composedElements): string
16+
{
17+
return "\$succeededCompositionElements === $composedElements";
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
4+
5+
/**
6+
* Class AnyofProcessor
7+
*
8+
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
9+
*/
10+
class AnyOfProcessor extends AbstractComposedValueProcessor
11+
{
12+
/**
13+
* @inheritdoc
14+
*/
15+
function getComposedValueValidation(int $composedElements): string
16+
{
17+
return "\$succeededCompositionElements > 0";
18+
}
19+
}
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
3+
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
4+
5+
use PHPModelGenerator\Model\Property\PropertyInterface;
6+
7+
/**
8+
* Class NotProcessor
9+
*
10+
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
11+
*/
12+
class NotProcessor extends AbstractComposedValueProcessor
13+
{
14+
/**
15+
* @inheritdoc
16+
*/
17+
protected function generateValidators(PropertyInterface $property, array $propertyData): void
18+
{
19+
// as the not composition only takes one schema nest it one level deeper to use the ComposedValueProcessor
20+
$propertyData['composition'] = [$propertyData['composition']];
21+
// strict type checks for not constraint to avoid issues with null
22+
$property->setRequired(true);
23+
parent::generateValidators($property, $propertyData);
24+
}
25+
26+
/**
27+
* @inheritdoc
28+
*/
29+
function getComposedValueValidation(int $composedElements): string
30+
{
31+
return '$succeededCompositionElements === 0';
32+
}
33+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
namespace PHPModelGenerator\PropertyProcessor\ComposedValue;
4+
5+
/**
6+
* Class OneofProcessor
7+
*
8+
* @package PHPModelGenerator\PropertyProcessor\ComposedValue
9+
*/
10+
class OneOfProcessor extends AbstractComposedValueProcessor
11+
{
12+
/**
13+
* @inheritdoc
14+
*/
15+
function getComposedValueValidation(int $composedElements): string
16+
{
17+
return '$succeededCompositionElements === 1';
18+
}
19+
}

0 commit comments

Comments
 (0)