Skip to content

Commit 967ef71

Browse files
committed
Add setter hooks to PopulatePostProcessor
1 parent 704e3ae commit 967ef71

File tree

3 files changed

+126
-2
lines changed

3 files changed

+126
-2
lines changed

src/SchemaProcessor/PostProcessor/PopulatePostProcessor.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use PHPModelGenerator\Model\GeneratorConfiguration;
88
use PHPModelGenerator\Model\Schema;
9+
use PHPModelGenerator\SchemaProcessor\Hook\SchemaHookResolver;
910

1011
/**
1112
* Class PopulatePostProcessor
@@ -16,6 +17,14 @@ class PopulatePostProcessor implements PostProcessorInterface
1617
{
1718
public function process(Schema $schema, GeneratorConfiguration $generatorConfiguration): void
1819
{
19-
$schema->addMethod('populate', new RenderedMethod($schema, $generatorConfiguration, 'Populate.phptpl'));
20+
$schema->addMethod(
21+
'populate',
22+
new RenderedMethod(
23+
$schema,
24+
$generatorConfiguration,
25+
'Populate.phptpl',
26+
['schemaHookResolver' => new SchemaHookResolver($schema)]
27+
)
28+
);
2029
}
2130
}

src/SchemaProcessor/PostProcessor/Templates/Populate.phptpl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@ public function populate(array $modelData): self
2424

2525
{% foreach schema.getProperties() as property %}
2626
if (array_key_exists('{{ property.getName() }}', $modelData)) {
27+
{{ schemaHookResolver.resolveSetterBeforeValidationHook(property) }}
28+
2729
$rollbackValues['{{ property.getAttribute() }}'] = $this->{{ property.getAttribute() }};
2830
$this->process{{ viewHelper.ucfirst(property.getAttribute()) }}($modelData);
2931
}
@@ -49,5 +51,13 @@ public function populate(array $modelData): self
4951

5052
$this->rawModelDataInput = array_merge($this->rawModelDataInput, $modelData);
5153

54+
{% foreach schema.getProperties() as property %}
55+
{% if schemaHookResolver.resolveSetterAfterValidationHook(property) %}
56+
if (array_key_exists('{{ property.getName() }}', $modelData)) {
57+
{{ schemaHookResolver.resolveSetterAfterValidationHook(property) }}
58+
}
59+
{% endif %}
60+
{% endforeach %}
61+
5262
return $this;
5363
}

tests/PostProcessor/PopulatePostProcessorTest.php

Lines changed: 106 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,13 @@
1010
use PHPModelGenerator\Exception\Object\MaxPropertiesException;
1111
use PHPModelGenerator\Exception\String\PatternException;
1212
use PHPModelGenerator\Model\GeneratorConfiguration;
13+
use PHPModelGenerator\Model\Property\PropertyInterface;
14+
use PHPModelGenerator\Model\Schema;
1315
use PHPModelGenerator\ModelGenerator;
16+
use PHPModelGenerator\SchemaProcessor\Hook\SetterAfterValidationHookInterface;
17+
use PHPModelGenerator\SchemaProcessor\Hook\SetterBeforeValidationHookInterface;
1418
use PHPModelGenerator\SchemaProcessor\PostProcessor\PopulatePostProcessor;
19+
use PHPModelGenerator\SchemaProcessor\PostProcessor\PostProcessorInterface;
1520
use PHPModelGenerator\Tests\AbstractPHPModelGeneratorTest;
1621

1722
class PopulatePostProcessorTest extends AbstractPHPModelGeneratorTest
@@ -20,7 +25,7 @@ public function setUp(): void
2025
{
2126
parent::setUp();
2227

23-
$this->modifyModelGenerator = function (ModelGenerator $generator) {
28+
$this->modifyModelGenerator = function (ModelGenerator $generator): void {
2429
$generator->addPostProcessor(new PopulatePostProcessor());
2530
};
2631
}
@@ -145,4 +150,104 @@ public function invalidPopulateDataProvider(): array
145150
],
146151
];
147152
}
153+
154+
public function testSetterBeforeValidationHookInsidePopulateIsResolved(): void
155+
{
156+
$this->modifyModelGenerator = function (ModelGenerator $modelGenerator): void {
157+
$modelGenerator->addPostProcessor(new PopulatePostProcessor());
158+
$modelGenerator->addPostProcessor(new class () implements PostProcessorInterface {
159+
public function process(Schema $schema, GeneratorConfiguration $generatorConfiguration): void
160+
{
161+
$schema->addSchemaHook(new class () implements SetterBeforeValidationHookInterface {
162+
public function getCode(PropertyInterface $property): string
163+
{
164+
return $property->getName() === 'age'
165+
? 'throw new \Exception("SetterBeforeValidationHook");'
166+
: '';
167+
}
168+
});
169+
}
170+
});
171+
};
172+
173+
$className = $this->generateClassFromFile('BasicSchema.json');
174+
175+
$object = new $className(['name' => 'Albert', 'age' => 35]);
176+
$object->populate(['name' => 'Hannes']);
177+
178+
$this->expectException(Exception::class);
179+
$this->expectExceptionMessage("SetterBeforeValidationHook");
180+
181+
$object->populate(['age' => 40]);
182+
}
183+
184+
/**
185+
* @dataProvider setterAfterValidationHookDataProvider
186+
*
187+
* @param string|null $expectedException
188+
* @param string|null $expectedExceptionMessage
189+
* @param array $populateValues
190+
*/
191+
public function testSetterAfterValidationHookInsidePopulateIsResolved(
192+
?string $expectedException,
193+
?string $expectedExceptionMessage,
194+
array $populateValues
195+
): void
196+
{
197+
$this->modifyModelGenerator = function (ModelGenerator $modelGenerator): void {
198+
$modelGenerator->addPostProcessor(new PopulatePostProcessor());
199+
$modelGenerator->addPostProcessor(new class () implements PostProcessorInterface {
200+
public function process(Schema $schema, GeneratorConfiguration $generatorConfiguration): void
201+
{
202+
$schema->addSchemaHook(new class () implements SetterAfterValidationHookInterface {
203+
public function getCode(PropertyInterface $property): string
204+
{
205+
return $property->getName() === 'age'
206+
? 'throw new \Exception("SetterAfterValidationHook");'
207+
: '';
208+
}
209+
});
210+
}
211+
});
212+
};
213+
214+
$className = $this->generateClassFromFile('BasicSchema.json');
215+
216+
$object = new $className(['name' => 'Albert', 'age' => 35]);
217+
218+
if ($expectedException) {
219+
$this->expectException($expectedException);
220+
$this->expectExceptionMessage($expectedExceptionMessage);
221+
} else {
222+
$this->expectNotToPerformAssertions();
223+
}
224+
225+
$object->populate($populateValues);
226+
}
227+
228+
public function setterAfterValidationHookDataProvider(): array
229+
{
230+
return [
231+
'update not hooked value valid' => [
232+
null,
233+
null,
234+
['name' => 'Hannes'],
235+
],
236+
'update not hooked value invalid' => [
237+
InvalidTypeException::class,
238+
'Invalid type for name. Requires string, got boolean',
239+
['name' => false],
240+
],
241+
'update hooked value valid' => [
242+
Exception::class,
243+
'SetterAfterValidationHook',
244+
['age' => 40],
245+
],
246+
'update hooked value invalid' => [
247+
InvalidTypeException::class,
248+
'Invalid type for age. Requires int, got boolean',
249+
['age' => false],
250+
],
251+
];
252+
}
148253
}

0 commit comments

Comments
 (0)