Skip to content

Commit

Permalink
Merge branch 'master' into AddOptionToDefaultArraysToEmptyArray
Browse files Browse the repository at this point in the history
  • Loading branch information
wol-soft authored Feb 10, 2021
2 parents dc64343 + 014b1d8 commit 5c57857
Show file tree
Hide file tree
Showing 30 changed files with 613 additions and 100 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
}
],
"require": {
"wol-soft/php-json-schema-model-generator-production": "^0.15",
"wol-soft/php-json-schema-model-generator-production": "^0.16.0",
"wol-soft/php-micro-template": "^1.3.2",

"php": ">=7.2",
Expand Down
117 changes: 116 additions & 1 deletion docs/source/combinedSchemas/if.rst
Original file line number Diff line number Diff line change
@@ -1,4 +1,119 @@
If
==

Currently not fully supported
The keywords `if`, `then` and `else` can be used to conditionally combine multiple subschemas. Conditional compositions can be used on property level and on object level.

.. code-block:: json
{
"$id": "example",
"type": "object",
"properties": {
"example": {
"type": "number",
"if": {
"multipleOf": 5
},
"then": {
"minimum": 100
},
"else": {
"maximum": 100
}
}
}
}
Valid values are eg. 100, 105, 99. Invalid values are eg. 50, 101 or any non numeric values.

Generated interface:

.. code-block:: php
public function setExample(float $example): self;
public function getExample(): ?float;
Possible exception (in this case 50 was provided so the if condition succeeds but the then branch failed):

.. code-block:: none
Invalid value for example declined by conditional composition constraint
- Condition: Valid
- Conditional branch failed:
* Value for example must not be smaller than 100
Another example exception with 101 as value for the property:

.. code-block:: none
Invalid value for example declined by conditional composition constraint
- Condition: Failed
* Value for example must be a multiple of 5
- Conditional branch failed:
* Value for example must not be larger than 100
The thrown exception will be a *PHPModelGenerator\\Exception\\ComposedValue\\ConditionalException* which provides the following methods to get further error details:

.. code-block:: php
// get the exception which triggered the condition to fail
// if error collection is enabled an ErrorRegistryException will be returned
public function getIfException(): ?Exception
// get the exception which triggered the conditional branch to fail
// if error collection is enabled an ErrorRegistryException will be returned
public function getThenException(): ?Exception
public function getElseException(): ?Exception
// get the name of the property which failed
public function getPropertyName(): string
// get the value provided to the property
public function getProvidedValue()
An object level composition will result in an object which contains all properties contained in the three possible blocks of the condition.

.. code-block:: json
{
"$id": "customer",
"type": "object",
"properties": {
"country": {
"enum": ["United States of America", "Canada"]
}
},
"if": {
"type": "object",
"properties": {
"country": {
"const": "United States of America"
}
}
},
"then": {
"type": "object",
"properties": {
"postal_code": {
"pattern": "[0-9]{5}(-[0-9]{4})?"
}
}
},
"else": {
"type": "object",
"properties": {
"postal_code": {
"pattern": "[A-Z][0-9][A-Z] [0-9][A-Z][0-9]"
}
}
}
}
Generated interface:

.. code-block:: php
public function setCountry(string $country): self;
public function getCountry(): ?string;
public function setPostalCode(string $country): self;
public function getPostalCode(): ?string;
2 changes: 1 addition & 1 deletion docs/source/complexTypes/enum.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ An enum can also be defined without a specific type.
}
}
Generated interface (no typehints are generated as it's an untyped enum):
Generated interface (no typehints are generated as it's a mixed untyped enum. If all values in the untyped enum are of the same type [eg. only strings] the generated interface will contain type hinting):

.. code-block:: php
Expand Down
12 changes: 9 additions & 3 deletions docs/source/generator/postProcessor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ AdditionalPropertiesAccessorPostProcessor
The **AdditionalPropertiesAccessorPostProcessor** adds methods to your model to work with `additional properties <../complexTypes/object.html#additional-properties>`__ on your objects. By default the post processor only adds methods to objects from a schema which defines constraints for additional properties. If the first constructor parameter *$addForModelsWithoutAdditionalPropertiesDefinition* is set to true the methods will also be added to objects generated from a schema which doesn't define additional properties constraints. If the *additionalProperties* keyword in a schema is set to false the methods will never be added.

.. note::

If the `deny additional properties setting <../gettingStarted.html#deny-additional-properties>`__ is set to true the setting *$addForModelsWithoutAdditionalPropertiesDefinition* is ignored as all objects which don't define additional properties are restricted to the defined properties

Added methods
~~~~~~~~~~~~~

Expand Down Expand Up @@ -144,7 +148,7 @@ By default additional properties are not included in serialized models. If the *
Custom Post Processors
----------------------

You can implement custom post processors to accomplish your tasks. Each post processor must implement the **PHPModelGenerator\\SchemaProcessor\\PostProcessor\\PostProcessorInterface**. If you have implemented a post processor add the post processor to your `ModelGenerator` and the post processor will be executed for each class.
You can implement custom post processors to accomplish your tasks. Each post processor must extend the class **PHPModelGenerator\\SchemaProcessor\\PostProcessor\\PostProcessor**. If you have implemented a post processor add the post processor to your `ModelGenerator` and the post processor will be executed for each class.

A custom post processor which adds a custom trait to the generated model (eg. a trait adding methods for an active record pattern implementation) may look like:

Expand All @@ -153,9 +157,9 @@ A custom post processor which adds a custom trait to the generated model (eg. a
namespace MyApp\Model\Generator\PostProcessor;
use MyApp\Model\ActiveRecordTrait;
use PHPModelGenerator\SchemaProcessor\PostProcessor\PostProcessorInterface;
use PHPModelGenerator\SchemaProcessor\PostProcessor\PostProcessor;
class ActiveRecordPostProcessor implements PostProcessorInterface
class ActiveRecordPostProcessor extends PostProcessor
{
public function process(Schema $schema, GeneratorConfiguration $generatorConfiguration): void
{
Expand Down Expand Up @@ -184,3 +188,5 @@ What can you do inside your custom post processor?
If a setter for a property is called with the same value which is already stored internally (consequently no update of the property is required), the setters will return directly and as a result of that the setter hooks will not be executed.

This behaviour also applies also to properties changed via the *populate* method added by the `PopulatePostProcessor <#populatepostprocessor>`__ and the *setAdditionalProperty* method added by the `AdditionalPropertiesAccessorPostProcessor <#additionalpropertiesaccessorpostprocessor>`__

To execute code before/after the processing of the schemas override the methods **preProcess** and **postProcess** inside your custom post processor.
16 changes: 16 additions & 0 deletions docs/source/gettingStarted.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,22 @@ By default optional properties which contain an `array <complexTypes/array.html>
(new GeneratorConfiguration())
->setDefaultArraysToEmptyArray(true);
Deny additional properties
^^^^^^^^^^^^^^^^^^^^^^^^^^

By default each generated object accepts additional properties. For strict property checks which error if undefined properties are provided each object must contain the *additionalProperties* key set to *false*.

By setting the **denyAdditionalProperties** option each object which doesn't specify a value for *additionalProperties* is restricted to the defined properties.

.. code-block:: php
setDenyAdditionalProperties(bool $denyAdditionalProperties);
.. code-block:: php
(new GeneratorConfiguration())
->setDenyAdditionalProperties(true);
Collect errors vs. early return
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Expand Down
66 changes: 64 additions & 2 deletions docs/source/types/string.rst
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ The thrown exception will be a *PHPModelGenerator\\Exception\\String\\MinLengthE
Pattern validation
------------------

To add a pattern validation to the property use `pattern` keyword.
To add a pattern validation to the property use the `pattern` keyword.

.. warning::

Expand Down Expand Up @@ -115,4 +115,66 @@ The thrown exception will be a *PHPModelGenerator\\Exception\\String\\PatternExc
Format
------

String formats are currently not supported.
To add a format validation to the property use the `format` keyword.

.. code-block:: json
{
"$id": "example",
"type": "object",
"properties": {
"example": {
"type": "string",
"format": "myFormat"
}
}
}
Possible exceptions:

* Value for property must match the format __FORMAT__

The thrown exception will be a *PHPModelGenerator\\Exception\\String\\FormatException* which provides the following methods to get further error details:

.. code-block:: php
// get the expected format
public function getExpectedFormat(): string
// get the name of the property which failed
public function getPropertyName(): string
// get the value provided to the property
public function getProvidedValue()
Builtin formats
^^^^^^^^^^^^^^^

Currently no builtin formats are available.

Custom formats
^^^^^^^^^^^^^^

You can implement custom format validators and use them in your schema files. You must add your custom format to the generator configuration to make them available.

.. code-block:: php
$generator = new Generator(
(new GeneratorConfiguration())
->addFormat(new MyCustomFormat())
);
Your format validator must implement the interface **PHPModelGenerator\\Format\\FormatValidatorInterface**.

If your custom format is representable by a regular expression you can bypass implementing an own class and simply add a **FormatValidatorFromRegEx** (for example a string which must contain only numbers):

.. code-block:: php
$generator = new Generator(
(new GeneratorConfiguration())
->addFormat(new FormatValidatorFromRegEx('/^\d*$/'))
);
.. hint::

Pull requests for common usable format validators are always welcome.
A new format validator must be added in the *GeneratorConfiguration* method *initFormatValidator*.
If the format validator requires a class implementation and can't be added via the *FormatValidatorFromRegEx* the class must be added to the *wol-soft/php-json-schema-model-generator-production* repository.
Loading

0 comments on commit 5c57857

Please sign in to comment.