Skip to content

Commit 9f1d46a

Browse files
authored
Merge pull request #19 from wol-soft/SchemaHooks
Schema Hooks
2 parents 892f4a5 + 9747966 commit 9f1d46a

18 files changed

+567
-7
lines changed

docs/source/generator/postProcessor.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,8 @@ Now let's have a look at the behaviour of the generated model:
7979

8080
If the **PopulatePostProcessor** is added to your model generator the populate method will be added to the model independently of the `immutable setting <../gettingStarted.html#immutable-classes>`__.
8181

82+
The **PopulatePostProcessor** will also resolve all hooks which are applied to setters. Added code will be executed for all properties changed by a populate call.
83+
8284
AdditionalPropertiesAccessorPostProcessor
8385
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
8486

@@ -163,3 +165,15 @@ A custom post processor which adds a custom trait to the generated model (eg. a
163165
.. hint::
164166

165167
For examples how to implement a custom post processor have a look at the built in post processors located at **src/SchemaProcessor/PostProcessor/**
168+
169+
What can you do inside your custom post processor?
170+
171+
* Add additional traits and interfaces to your models
172+
* Add additional methods and properties to your models
173+
* Hook via SchemaHooks into the generated source code and add your snippets at defined places inside the model:
174+
175+
* Implement the **ConstructorBeforeValidationHookInterface** to add code to the beginning of your constructor
176+
* Implement the **ConstructorAfterValidationHookInterface** to add code to the end of your constructor
177+
* Implement the **GetterHookInterface** to add code to your getter methods
178+
* Implement the **SetterBeforeValidationHookInterface** to add code to the beginning of your setter methods
179+
* Implement the **SetterAfterValidationHookInterface** to add code to the end of your setter methods

docs/source/gettingStarted.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ Immutable classes
147147
148148
setImmutable(bool $immutable);
149149
150-
If set to true the generated model classes will be delivered without setter methods for the object properties. By default the classes are generated without setter methods.
150+
If set to true the generated model classes will be delivered without setter methods for the object properties. By default the classes are generated without setter methods. Each setter will validate the provided value and throw either a specific exception or a collection exception depending on the `error collection configuration <#collect-errors-vs-early-return>`__. If all validations pass the internal value will be updated as well as the value which will be returned when `getRawModelDataInput` is called.
151151

152152
.. code-block:: php
153153

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+
}

0 commit comments

Comments
 (0)