Skip to content

Commit be74d7d

Browse files
committed
Add schema hooks to add code to specific locations inside the generated models
1 parent 892f4a5 commit be74d7d

10 files changed

+180
-2
lines changed

src/Model/RenderJob.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
use PHPModelGenerator\Exception\FileSystemException;
1010
use PHPModelGenerator\Exception\RenderException;
1111
use PHPModelGenerator\Exception\ValidationException;
12+
use PHPModelGenerator\SchemaProcessor\Hook\SchemaHookResolver;
1213
use PHPModelGenerator\SchemaProcessor\PostProcessor\PostProcessorInterface;
1314
use PHPModelGenerator\Utils\RenderHelper;
1415

@@ -144,6 +145,7 @@ protected function renderClass(GeneratorConfiguration $generatorConfiguration):
144145
'use' => 'use ' . join(";\nuse ", array_unique($use)) . ';',
145146
'class' => $this->className,
146147
'schema' => $this->schema,
148+
'schemaHookResolver' => new SchemaHookResolver($this->schema),
147149
'generatorConfiguration' => $generatorConfiguration,
148150
'viewHelper' => new RenderHelper($generatorConfiguration),
149151
// one hack a day keeps the problems away. Make true literal available for the templating. Easy fix

src/Model/Schema.php

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use PHPModelGenerator\Model\Validator\PropertyValidatorInterface;
1313
use PHPModelGenerator\Model\Validator\SchemaDependencyValidator;
1414
use PHPModelGenerator\PropertyProcessor\Decorator\SchemaNamespaceTransferDecorator;
15+
use PHPModelGenerator\SchemaProcessor\Hook\SchemaHookInterface;
1516

1617
/**
1718
* Class Schema
@@ -40,10 +41,12 @@ class Schema
4041
* before adding properties to the model
4142
*/
4243
protected $baseValidators = [];
43-
/** @var array */
44+
/** @var string[] */
4445
protected $usedClasses = [];
4546
/** @var SchemaNamespaceTransferDecorator[] */
4647
protected $namespaceTransferDecorators = [];
48+
/** @var SchemaHookInterface[] */
49+
protected $schemaHooks = [];
4750

4851
/** @var SchemaDefinitionDictionary */
4952
protected $schemaDefinitionDictionary;
@@ -200,7 +203,7 @@ public function addNamespaceTransferDecorator(SchemaNamespaceTransferDecorator $
200203
/**
201204
* @param Schema[] $visitedSchema
202205
*
203-
* @return array
206+
* @return string[]
204207
*/
205208
public function getUsedClasses(array $visitedSchema = []): array
206209
{
@@ -244,6 +247,7 @@ public function getTraits(): array
244247

245248
/**
246249
* @param string $trait
250+
*
247251
* @return Schema
248252
*/
249253
public function addTrait(string $trait): self
@@ -264,6 +268,7 @@ public function getInterfaces(): array
264268

265269
/**
266270
* @param string $interface
271+
*
267272
* @return Schema
268273
*/
269274
public function addInterface(string $interface): self
@@ -273,4 +278,26 @@ public function addInterface(string $interface): self
273278

274279
return $this;
275280
}
281+
282+
/**
283+
* Add an additional schema hook
284+
*
285+
* @param SchemaHookInterface $schemaHook
286+
*
287+
* @return $this
288+
*/
289+
public function addSchemaHook(SchemaHookInterface $schemaHook): self
290+
{
291+
$this->schemaHooks[] = $schemaHook;
292+
293+
return $this;
294+
}
295+
296+
/**
297+
* @return SchemaHookInterface[]
298+
*/
299+
public function getSchemaHooks(): array
300+
{
301+
return $this->schemaHooks;
302+
}
276303
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
interface ConstructorAfterValidationHookInterface extends SchemaHookInterface
8+
{
9+
public function getCode(): string;
10+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
interface ConstructorBeforeValidationHookInterface extends SchemaHookInterface
8+
{
9+
public function getCode(): string;
10+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
use PHPModelGenerator\Model\Property\PropertyInterface;
8+
9+
interface GetterHookInterface extends SchemaHookInterface
10+
{
11+
public function getCode(PropertyInterface $property): string;
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
interface SchemaHookInterface
8+
{
9+
}
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
use PHPModelGenerator\Model\Property\PropertyInterface;
8+
use PHPModelGenerator\Model\Schema;
9+
10+
class SchemaHookResolver
11+
{
12+
/** @var Schema */
13+
private $schema;
14+
15+
public function __construct(Schema $schema)
16+
{
17+
$this->schema = $schema;
18+
}
19+
20+
public function resolveConstructorBeforeValidationHook(): string
21+
{
22+
return $this->resolveHook(ConstructorBeforeValidationHookInterface::class);
23+
}
24+
25+
public function resolveConstructorAfterValidationHook(): string
26+
{
27+
return $this->resolveHook(ConstructorAfterValidationHookInterface::class);
28+
}
29+
30+
public function resolveGetterHook(PropertyInterface $property): string
31+
{
32+
return $this->resolveHookWithProperty(GetterHookInterface::class, $property);
33+
}
34+
35+
public function resolveSetterBeforeValidationHook(PropertyInterface $property): string
36+
{
37+
return $this->resolveHookWithProperty(SetterBeforeValidationHookInterface::class, $property);
38+
}
39+
40+
public function resolveSetterAfterValidationHook(PropertyInterface $property): string
41+
{
42+
return $this->resolveHookWithProperty(SetterAfterValidationHookInterface::class, $property);
43+
}
44+
45+
private function getHooks(string $filterHook): array
46+
{
47+
return array_filter(
48+
$this->schema->getSchemaHooks(),
49+
function (SchemaHookInterface $hook) use ($filterHook): bool {
50+
return is_a($hook, $filterHook);
51+
}
52+
);
53+
}
54+
55+
private function resolveHook(string $filterHook): string
56+
{
57+
return join(
58+
"\n\n",
59+
array_map(function ($hook): string {
60+
return $hook->getCode();
61+
}, $this->getHooks($filterHook))
62+
);
63+
}
64+
65+
private function resolveHookWithProperty(string $filterHook, PropertyInterface $property): string
66+
{
67+
return join(
68+
"\n\n",
69+
array_map(function ($hook) use ($property): string {
70+
return $hook->getCode($property);
71+
}, $this->getHooks($filterHook))
72+
);
73+
}
74+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
use PHPModelGenerator\Model\Property\PropertyInterface;
8+
9+
interface SetterAfterValidationHookInterface extends SchemaHookInterface
10+
{
11+
public function getCode(PropertyInterface $property): string;
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace PHPModelGenerator\SchemaProcessor\Hook;
6+
7+
use PHPModelGenerator\Model\Property\PropertyInterface;
8+
9+
interface SetterBeforeValidationHookInterface extends SchemaHookInterface
10+
{
11+
public function getCode(PropertyInterface $property): string;
12+
}

src/Templates/Model.phptpl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ class {{ class }} {% if schema.getInterfaces() %}implements {{ viewHelper.joinCl
4545
$this->errorRegistry = new {{ viewHelper.getSimpleClassName(generatorConfiguration.getErrorRegistryClass()) }}();
4646
{% endif %}
4747

48+
{{ schemaHookResolver.resolveConstructorBeforeValidationHook() }}
49+
4850
{% if schema.getBaseValidators() %}
4951
$this->executeBaseValidators($modelData);
5052
{% endif %}
@@ -60,6 +62,8 @@ class {{ class }} {% if schema.getInterfaces() %}implements {{ viewHelper.joinCl
6062
{% endif %}
6163

6264
$this->rawModelDataInput = $modelData;
65+
66+
{{ schemaHookResolver.resolveConstructorAfterValidationHook() }}
6367
}
6468

6569
{% if schema.getBaseValidators() %}
@@ -97,6 +101,8 @@ class {{ class }} {% if schema.getInterfaces() %}implements {{ viewHelper.joinCl
97101
public function get{{ viewHelper.ucfirst(property.getAttribute()) }}()
98102
{% if property.getType(true) %}: {% if viewHelper.isPropertyNullable(property) %}?{% endif %}{{ property.getType(true) }}{% endif %}
99103
{
104+
{{ schemaHookResolver.resolveGetterHook(property) }}
105+
100106
return $this->{{ property.getAttribute() }};
101107
}
102108

@@ -113,6 +119,8 @@ class {{ class }} {% if schema.getInterfaces() %}implements {{ viewHelper.joinCl
113119
public function set{{ viewHelper.ucfirst(property.getAttribute()) }}(
114120
{% if property.getType() %}{% if viewHelper.isPropertyNullable(property, true) %}?{% endif %}{{ property.getType() }} {% endif %}${{ property.getAttribute() }}
115121
): self {
122+
{{ schemaHookResolver.resolveSetterBeforeValidationHook(property) }}
123+
116124
$value = $modelData['{{ property.getName() }}'] = ${{ property.getAttribute() }};
117125

118126
{% if generatorConfiguration.collectErrors() %}
@@ -129,6 +137,8 @@ class {{ class }} {% if schema.getInterfaces() %}implements {{ viewHelper.joinCl
129137

130138
$this->{{ property.getAttribute() }} = $value;
131139

140+
{{ schemaHookResolver.resolveSetterAfterValidationHook(property) }}
141+
132142
return $this;
133143
}
134144
{% endif %}

0 commit comments

Comments
 (0)