Git Product home page Git Product logo

php-json-schema-model-generator's People

Contributors

dktapps avatar konafets avatar ramon-b avatar raphaelhanneken avatar wol-soft avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

php-json-schema-model-generator's Issues

Serialization Bug: Including Null Properties in JSON Output instead of Excluding Them

Describe the bug:
The serialization of models using the toArray and toJSON functions is including null properties instead of excluding them from the JSON string. These additional fields will cause an error when trying to instantiate the model with the saved JSON string.

Expected behavior:
I understand that using the object's properties is not the best approach. It is necessary to use only the information contained in the RawModelDataInput field, where the object's state is stored.

Schema:

"juros": {
	"$id": "#juros",
	"type": "object",
	"required": [
		"id"
	],
	"properties": {
		"id": {
			"type": ["integer", "string"],
			"description": "ID ou Sigla do tipo de indicador utilizado."
		},
		"dataInicioJuros": {
			"type": "string",
			"format": "datetime"
			"description": "Data de início de fluência dos juros."
		},
		"dataFinalJuros": {
			"type": "string",
			"format": "datetime"
			"description": "Data de término de fluência dos juros."
		},
		"jurosProRata": {
			"type": "boolean",
			"description": "Indica que o cálculo de juros considerará frações de períodos"
		},
		"jurosCompostos": {
			"type": "boolean",
			"description": "Indica que o cálculo de juros será da modalidade de juros compostos"
		}
	}
},

Version:
0.23.0

Additional context:
Considering the schema, I would like to create a model with the JSON string {"id": "JUROS_0"} and serialize it to the same output. However, the class will generate the following output JSON string: {"id": "JUROS_0", "dataInicioJuros": null, "dataFimJuros": null, "jurosProRata": null, "jurosCompostos": null}.

Add validateOption to FilterInterface

To validate the provided options of a filter during the build step the function

validate(array $options): void

should be added to the FilterInterface (or a new interface to reduce overhead for filters not using the validation). This method can be used to validate the options array and throw an exception, if for example a required option is missing.

Access additional properties

Problem

When a schema applies validation rules to additional properties the only way to access the values of the additional properties is to use the method getRawModelDataInput.

  • This method delivers all properties of the model, so there is no way to access only the additional properties
  • This method delivers the raw values which were applied to the model. This may be a problem in various situations:
    • The additional properties contain objects and processing the additional properties results in object instantiations. There is no way to access the objects
    • The additional properties are modified by filters. The filtered values can't be accessed
  • additional properties don't occur in serialized models

Possible solution

Access values on the model

If a schema defines constraints for additionalProperties add a method getAdditionalProperties to the model. This method returns an array indexed by the provided property key containing the processed values. If the properties provide type information (eg. an object structure which was generated) the return type of the method should be type hinted with the corresponding type to provide auto completion when using the method.

Additionally a method getAdditionalProperty will be added which accepts a property key. If an additional property with the requested key exists the property will be returned, null otherwise. The method is also type hinted.

Access the models via serialization

If a model with additional properties is serialized (requires serialization enabled) the returned array/JSON will contain all additional properties. If transforming filters are applied to the additional properties the corresponding serializer will be called for each additional property.

Modify values on the model

A method setAdditionalProperty will be added (if immutability is disabled) which accepts a property key and a property value (type hinted as well). If an additional property with the provided key already exists the existing property will be overwritten. When setting a new value the validation rules of the additionalProperties definition are applied to the provided value as well as propertyNames rules are applied to the provided property key.

Additionally a method removeAdditionalProperty will be added which accepts a property key and removes the additional property with the requested key if the property exists.

If new additional properties are added or existing properties are removed make sure the minProperties and the maxProperties validation rules aren't violated.

Add an option to default arrays to an empty array

Currently arrays which aren't required default to null. This requires additional null checks in PHP code where an empty array fits much better. Consequently an option to default not provided array properties to an empty array may be useful.

uuid string type support

Hi,
Do you know if it's possible to support additional format type as UUID ?

I got this error when I try to use it :

PHP Fatal error: Uncaught PHPModelGenerator\Exception\SchemaException: Unsupported format uuid for property UUID in file openApi.json in vendor/wol-soft/php-json-schema-model-generator/src/PropertyProcessor/Property/StringProcessor.php:136

My schema is
"properties": { "UUID": { "type": "string", "minLength": 1, "format": "uuid", }
best regards,
Alban

Property validation of mutable objects which use composition after instantiation

Problem

Objects which inherit properties from compositions validate correctly during object instantiation. If the object is generated with setters the setters don't perform validations according to the composition rules.

Expected behaviour

  • Simple validations on properties inherited from compositions (eg. string length checks) are performed when calling a setter
  • If the model, as a result of the changed internal state, violates the composition rule (eg. an allOf composition is violated as the string property now doesn't match the length constraint and thus at least one of the composition elements fails) an exception will be thrown.

Stable version

Is this package in a stable state and if not is there any plans to get it to a stable point?

I know this isn't technically tagged as stable (v0.x) but unsure if it;s just how this package has been tagged as I can't see any mention of it being in development

Multiple levels of compositions lead to lost IDs

Describe the bug
If multiple levels of compositions are used (each composition with an ID) the generated merged properties will be named generic instead of utilizing the provided ID as described in https://php-json-schema-model-generator.readthedocs.io/en/latest/combinedSchemas/mergedProperty.html

Expected behavior
The classes for the merged properties shall utilize the $id field of the most outer composition level to provide a predictable name over multiple generation processes.

Schema
Schema.zip

Version:
0.19.0

Add an option to set additionalProperties to false by default

By default a JSON schema enforces the user to define "additionalProperties": false for each object which should accept only the defined properties. To generate strict models an option should be available to default additionalProperties to false. If the additionalProperties keyword is defined for an object the option is ignored.

Access to undeclared property `_propertyValidationState` on simple templates

Describe the bug
I initially found this and various other bugs using PHPStan:
image

The vast majority of these issues are the same thing, but only this one looks actively harmful as far as I can tell (most of the others are just unused use and dead code which could be prevented from generating with the right efforts).

Bear in mind that this is just PHPStan level 1, and higher levels might find more problems.

Expected behavior
The generated code shouldn't be trying to access an undeclared property. This happens in both mutable and immutable models.

Schema

{
	"$schema": "http://json-schema.org/draft-04/schema#",
	"type": "object",
	"additionalProperties": false,
	"properties": {
		"mode": {
			"enum": [
				"blacklist",
				"whitelist",
				"allow",
				"disallow"
			],
			"default": "disallow",
			"description": "The listed plugins will either be allowed or disallowed based on this setting"
		},
		"plugins": {
			"anyOf": [
				{
					"type": "array",
					"items": {
						"type": "string"
					}
				},
				{
					"type": "null"
				}
			],
			"default": [],
			"description": "List of plugins to allow or disallow"
		}
	}
}

My generator config can be seen here: https://github.com/pmmp/DataModels/blob/3f398d966d5180d68e33c8f4054ab592094ea54c/generate-schemas.php

Version:
0.21.5

Don't create a merged property if the composition is on object level

Problem

Currently for each allOf, anyOf or oneOf composition which contains nested objects a merged property is created to represent the complete composition.

The merged property is required if the composition is used on property level (compare docs).

If the composition is used on object level the merged property is identical to the main model generated. Consequently the merged property can be skipped.

Class example:

{
  "type": "object",
  "allOf": [
    {
        "$ref": "....."
    },
    {
        "$ref": "....."
    }
  ]
}

Expected result

An object like the example above should produce three classes

  • two to validate the references independently of each other
  • main model.

Current behaviour

Four classes are generated.

  • two to validate the references independently of each other
  • merged property
  • main model.

Path to EasyCodingStandard binary is wrong

Describe the bug
The model generator provides a pretty-print option which uses EasyCodingStandard (ECS) in the background.

Expected behavior
The generated models are pretty-printed after generation.

Actual behavior
sh: 1: /home/username/project/vendor/wol-soft/php-json-schema-model-generator/src/../vendor/bin/ecs: not found

Schema
Not related to a schema.

Config

    $config = new GeneratorConfiguration();
    $config
        ->setNamespacePrefix('ACME\Common\Models')
        ->setImmutable(false)
        ->setPrettyPrint(true)
        ->setSerialization(true);

    $generator = new ModelGenerator($config);
    $generator
        ->generateModelDirectory(__DIR__ . '/src/ACME/Common/Models')
        ->generateModels(
            new RecursiveDirectoryProvider(__DIR__ . '/resources'),
            __DIR__ . '/src/ACME/Common/Models'
        );

Version:
0.20.0

Additional context

  • In src/ModelGenerator.php ECS is called like this: shell_exec(__DIR__ . "/../vendor/bin/ecs check $destination --config " . __DIR__ . "/cs.yml --fix $out").
  • However, resolving this directory will end up in src/vendor/bin/ecs.
  • It should be called like this: shell_exec(__DIR__ . "/../../../../vendor/bin/ecs check $destination --config " . __DIR__ . "/cs.yml --fix $out");

Make code output stable across multiple runs

Is your feature request related to a problem? Please describe.
Currently, this library relies on uniqid() quite a lot to ensure uniqueness in generated code. This is quite annoying when the generated code is in a git repository, because schema code changes every time my build script runs even if the schema itself was untouched.

Describe the solution you'd like
For class names, I've had some success with a custom class name generator that suffixes with md5(json_encode(propertySchema)) instead of uniqid(). However, there's some additional places that I can't touch without modifying the library itself:

  • ArrayItemValidator generates variable names using uniqid(). I'm not actually very clear why this is needed at all, since validators are anyway split up into separate methods per property.
  • AbstractPropertyProcessor uses uniqid() to generate class names for rendering dependencies. Again, I'm not very clear why this is needed - isn't ClassNameGenerator enough to take care of this?

Additional context
image

Inconsistency of generated code when using different methods to declare nullable structures

Describe the bug

The following diff:

diff --git a/schema/PluginListYml.json b/schema/PluginListYml.json
index 4500662..7d5fdea 100644
--- a/schema/PluginListYml.json
+++ b/schema/PluginListYml.json
@@ -14,17 +14,13 @@
                        "description": "The listed plugins will either be allowed or disallowed based on this setting"
                },
                "plugins": {
-                       "anyOf": [
-                               {
-                                       "type": "array",
-                                       "items": {
-                                               "type": "string"
-                                       }
-                               },
-                               {
-                                       "type": "null"
-                               }
+                       "type": [
+                               "array",
+                               "null"
                        ],
+                       "items": {
+                               "type": "string"
+                       },
                        "default": [],
                        "description": "List of plugins to allow or disallow"
                }

produces the following change:
pmmp/DataModels@46eab45

You can see that there's much less generated code for some reason, but what bothers me more is that the ?array native types disappeared from both getters and setters.

Expected behavior
The code should be the same in both cases, since they are semantically equivalent to the best of my understanding.

However, more importantly, the native types should not be missing after the change: the calculated types are exactly the same.

Schema
https://github.com/pmmp/DataModels/blob/46eab454f5e3c2498f3a84e8065ed9702f27a58f/schema/PluginListYml.json

https://github.com/pmmp/DataModels/blob/46eab454f5e3c2498f3a84e8065ed9702f27a58f/generate-schemas.php

Version:
0.12.7.

Integer property with default 0 is incorrectly nullable

Describe the bug
A property with a default value is not typically nullable, but if its default is 0, it's marked as nullable anyway.

Expected behavior
Integer properties with 0 as the default value shouldn't be nullable.

Schema

				"global-limit": {
					"type": "integer",
					"minimum": 0,
					"description": "Global soft memory limit (MB). When reached, low-memory triggers will fire to try and free memory.",
					"default": 1
				},

Version:
Which version of the library do you use?
dev-master as of about 1h ago.

Additional context
My bet is that there's some weak comparison == somewhere that's responsible for this bug.

Incorrect native parameter type on nullable setters in mutable models

Describe the bug
Nullable field setters don't correctly account for null when generating typehints.
image

Again, found by PHPStan.

Expected behavior
setDisableBlockTicking() should accept null.

Schema

{
	"$schema": "http://json-schema.org/draft-04/schema#",
	"type": "object",
	"additionalProperties": false,
	"properties": {
		"disable-block-ticking": {
			"oneOf": [
				{
					"type": "array",
					"items": {
						"type": "integer"
					}
				},
				{
					"type": "null"
				}
			],
			"description": "IDs of blocks to disallow ticking.",
			"default": null
		}
	},
	"required": [
		"chunk-ticking"
	]
}

Config: https://github.com/pmmp/DataModels/blob/3f398d966d5180d68e33c8f4054ab592094ea54c/generate-schemas.php

Version:
0.21.5.

Optional property return type with a default value is nullable

Only applies if the option implicitNull is not enabled. If no default value is provided the property must be nullable (value is null if no value is provided). If implicitNull is enabled the return type must also be nullable as optional properties with this option accept null.

{
    "type": "object",
    "properties": {
        "test": {
            "type": "boolean",
            "default": false
    }
}

Expected interface:

public function getTest(): bool;

Generated interface:

public function getTest(): ?bool;

Crash on `"type": ["object"]` on object properties

Describe the bug
The below schema causes the following error on code generation:

Fatal error: Uncaught Error: Call to a member function getClassPath() on null in C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\Property
Processor\Property\ObjectProcessor.php:51
Stack trace:
#0 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\Property\MultiTypeProcessor.php(165): PHPModelGenerator\PropertyProc
essor\Property\ObjectProcessor->process('aliases', Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema))
#1 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\Property\MultiTypeProcessor.php(84): PHPModelGenerator\PropertyProce
ssor\Property\MultiTypeProcessor->processSubProperties('aliases', Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema), Object(PHPModelGenerator\Model\Property\Property))
#2 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\PropertyFactory.php(72): PHPModelGenerator\PropertyProcessor\Propert
y\MultiTypeProcessor->process('aliases', Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema))
#3 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\Property\BaseProcessor.php(279): PHPModelGenerator\PropertyProcessor
\PropertyFactory->create(Object(PHPModelGenerator\PropertyProcessor\PropertyMetaDataCollection), Object(PHPModelGenerator\SchemaProcessor\SchemaProcessor), Object(PHPModelGenerator\Model\Schema), 'aliases', Obj
ect(PHPModelGenerator\Model\SchemaDefinition\JsonSchema))
#4 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\Property\BaseProcessor.php(75): PHPModelGenerator\PropertyProcessor\
Property\BaseProcessor->addPropertiesToSchema(Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema))
#5 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\PropertyFactory.php(72): PHPModelGenerator\PropertyProcessor\Propert
y\BaseProcessor->process('Crash', Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema))
#6 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\SchemaProcessor\SchemaProcessor.php(191): PHPModelGenerator\PropertyProcessor\Property
Factory->create(Object(PHPModelGenerator\PropertyProcessor\PropertyMetaDataCollection), Object(PHPModelGenerator\SchemaProcessor\SchemaProcessor), Object(PHPModelGenerator\Model\Schema), 'Crash', Object(PHPMode
lGenerator\Model\SchemaDefinition\JsonSchema))
#7 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\SchemaProcessor\SchemaProcessor.php(137): PHPModelGenerator\SchemaProcessor\SchemaProc
essor->generateModel('', 'Crash', Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema), Object(PHPModelGenerator\Model\SchemaDefinition\SchemaDefinitionDictionary), true)
#8 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\SchemaProcessor\SchemaProcessor.php(104): PHPModelGenerator\SchemaProcessor\SchemaProc
essor->processSchema(Object(PHPModelGenerator\Model\SchemaDefinition\JsonSchema), '', 'Crash', Object(PHPModelGenerator\Model\SchemaDefinition\SchemaDefinitionDictionary), true)
#9 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\ModelGenerator.php(125): PHPModelGenerator\SchemaProcessor\SchemaProcessor->process(Ob
ject(PHPModelGenerator\Model\SchemaDefinition\JsonSchema))
#10 C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\generate-schemas.php(74): PHPModelGenerator\ModelGenerator->generateModels(Object(PHPModelGenerator\SchemaProvider\RecursiveDirectoryProv
ider), 'C:\\Users\\dylan-...')
#11 {main}
  thrown in C:\Users\dylan-work\Documents\projects\pocketmine-mp\deps\DataModels\vendor\wol-soft\php-json-schema-model-generator\src\PropertyProcessor\Property\ObjectProcessor.php on line 51

Expected behavior
The model should be generated exactly as if I'd used type: object.

Schema

{
	"$schema": "http://json-schema.org/draft-04/schema#",
	"type": "object",
	"properties": {
		"aliases": {
			"type": ["object"]
		}
	}
}

Generator config: https://github.com/pmmp/DataModels/blob/d91723d5cccb8879532430ba4aff80949c440034/generate-schemas.php

Version:
0.21.5

Additional context
I was trying to use type arrays to create explicitly nullable object fields.

Missing properties when multiple properties use the same ref

Describe the bug
When using a schema that has two keys that both reference the same definition in their values, only the first gets generated.

Expected behavior
Both properties exist in the generated PHP.
In the generated Test.php a search for the word personA returns 40 results, but a search for the word personB only returns 1.

Schema

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "$id": "Test",

  "definitions": {
    "person": {
      "type": "object",
      "properties": {
        "id": { "type": "string" }
      },
      "required": ["id"],
      "additionalProperties": false
    }
  },

  "type": "object",
  "properties": {
    "personA": { "$ref": "#/definitions/person" },
    "personB": { "$ref": "#/definitions/person" }
  },
  "required": ["personA", "personB"],
  "additionalProperties": false
}

With GeneratorConfiguration:

$generator = new ModelGenerator((new GeneratorConfiguration())
    ->setNamespacePrefix('Demo')
    ->setSerialization(true)
    ->setImmutable(false)
);

Version:
0.19.0

Additional context
This is not my real schema, this is a minimal reproduction. The environment I did this in only has the following files:

  • composer.json
  • json-schema/test.json
  • codegen.php

const values lead to invalid code

Schema

{
  "$id": "Person",
  "type": "object",
  "properties": {
    "age": {
      "const": 42
    }
  }
}

Generated code

/** @var integer */
protected $age = NULL;

public function getAge(): integer
public function setAge(integer $age): self

...PropertyProxy::getProperty(): Return value must be of type ...PropertyInterface, null returned in

image

Note that the function return type was defined as non-null and, as you can see in the debugger, the specific key being looked up points to a null.

My suspicion (without digging deep into the code) is that the recursive declaration (line 530 of the schema) might be causing the null?

Describe the bug
Attempt to return null on a non-null return during generation.

Expected behavior
Generation should have succeeded.

Schema
https://raw.githubusercontent.com/JetBrains/web-types/master/schema/web-types.json

Version:
0.23 (generator) / 0.18 (interfaces)


Additionally, the patternProperties regex check in BaseProcessor line 171 is triggering a failure for pattern ^/(html|css|js)/[^/\n\r]+$, which to me looks fine, but maybe I'm missing the purpose of the check.

Simplify object notation for single-filter usage

Currently the library forces the user to define a list when using filter options even if only a single filter is applied:

{
    "type": "object",
    "properties": {
        "created": {
            "type": "string",
            "filter": [
                {
                    "filter": "dateTime",
                    "denyEmptyValue": true
                }
            ]
        }
    }
}

Instead of the list allow the direct usage of an object to define a single filter with options:

{
    "type": "object",
    "properties": {
        "created": {
            "type": "string",
            "filter": {
                "filter": "dateTime",
                "denyEmptyValue": true
            }
        }
    }
}

The above currently crashes with a message unsupported filter denyEmptyValues which is not helpful.

Validation of nested composition causes fatal error

Describe the bug
Validation of nested composition causes a fatal error:

Call to undefined method Generated\CreateSession_CreateSession615efe9ce38a3::validateComposition_0() in Generated/CreateSession_CreateSession615efe9ce38a3.php(86)

#0 Generated/CreateSession_CreateSession615efe9ce38a3.php(62): Generated\CreateSession_CreateSession615efe9ce38a3->executeBaseValidators(Array)
#1 Generated/CreateSession.php(555): Generated\CreateSession_CreateSession615efe9ce38a3->__construct(Array)
#2 Generated/CreateSession.php(569): Generated\CreateSession->Generated\{closure}(Array)
#3 Generated/CreateSession.php(634): Generated\CreateSession->Generated\{closure}(Array)
#4 Generated/CreateSession.php(113): Generated\CreateSession->validateComposition_0(Array)
#5 Generated/CreateSession.php(79): Generated\CreateSession->executeBaseValidators(Array)
#6 CreateSessionAction.php(56): Generated\CreateSession->__construct(Array)

Expected behavior
A successful (or depending on the input unsuccessful) validation, without an unexpected exception.

Schema

{
    "$id": "CreateSession",
    "type": "object",
    "allOf": [
        {
            "type": "object",
            "properties": {
                "timeout": {
                    "type": "integer",
                    "example": 120,
                    "minimum": 1,
                    "description": "The sessions lifetime in minutes",
                    "filter": [
                        {
                            "filter": "timeInterval",
                            "intervalUnit": "minutes"
                        }
                    ]
                },
                "expires": {
                    "type": "string",
                    "example": "2021-10-21T13:52:00+02:00",
                    "description": "An expiry date formatted according to ISO-8106",
                    "filter": [
                        {
                            "filter": "dateTime",
                            "outputFormat": "ATOM"
                        }
                    ]
                }
            }
        },
        {
            "oneOf": [
                {
                    "required": [
                        "timeout"
                    ]
                },
                {
                    "required": [
                        "expires"
                    ]
                }
            ]
        }
    ]
}

Version:
0.21.0

Creation of dynamic property for composed item validators on properties

Describe the bug
Composed item validators on properties use the _propertyValidationState property inside the validator which is used for base validators to determine whether a property change must trigger a re-evaluation of the base validator. As the _propertyValidationState property is only added to the model when a composed item base validator is found the property might not be present and the access will trigger a deprecation warning in PHP >= 8.2.

Expected behavior
Don't use the _propertyValidationState outside of base validators.

Schema

{
  "$schema": "https://json-schema.org/draft/2019-09/schema",
  "type": "object",
  "definitions": {
    "number": {
      "type": "integer",
      "minimum": 0,
      "maximum": 1000
    },
    "values": {
      "type": "array",
      "items": {
        "allOf": [
          { "$ref": "#/definitions/number" },
          { "minimum": 1 }
        ]
      },
      "minItems": 1
    },
    "pet": {
      "oneOf": [
        { "$ref": "#/definitions/pets/dog" },
        { "$ref": "#/definitions/pets/spider" }
      ]
    },
    "pets": {
      "dog": {
        "type": "object",
        "properties": {
          "age": {
            "$ref": "#/definitions/number"
          },
          "name": {
            "type": "string"
          }
        }
      },
      "spider": {
        "type": "object",
        "properties": {
          "age": {
            "$ref": "#/definitions/number"
          },
          "weight": {
            "type": "number"
          }
        }
      }
    }
  },
  "properties": {
    "values": {
      "$ref": "#/definitions/values"
    },
    "pet": {
      "$ref": "#/definitions/pet"
    }
  },
  "additionalProperties": false
}

Version:
0.23.4

Inherited properties are partially nullable

Describe the bug
When using compositions the properties of the compositions are transferred to the main object. Independently of the implicitNull setting and the required state of the properties which are transferred from a composition the function signatures for getters and the DocBlocks for the properties are nullable.

With implicitNull setters of required properties become also nullable (although the validation performs correct checks and it will consequently fail if null is provided). Should be solved via the function signature.

Schema

{
  "$id": "Person",
  "allOf": [
    {
      "type": "object",
      "properties": {
        "age": {
          "type": "integer",
          "description": "The age of the person",
          "example": 42
        }
      }
    },
    {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the person",
          "example": "Lawrence"
        }
      },
      "required": [
        "name"
      ]
    }
  ]
}

implicitNull disabled

generated interface

        /** @var int|null The age of the person */
        protected $age = NULL;
        /** @var string|null The name of the person */
        protected $name = NULL;

        public function getAge(): ?int
        public function setAge(int $age): self
        public function getName(): ?string
        public function setName(string $name): self

expected interface

        /** @var int|null The age of the person */
        protected $age = NULL;
        /** @var string The name of the person */
        protected $name;

        public function getAge(): ?int
        public function setAge(int $age): self
        public function getName(): string
        public function setName(string $name): self

implicitNull enabled

generated interface

        /** @var int|null The age of the person */
        protected $age = NULL;
        /** @var string|null The name of the person */
        protected $name = NULL;

        public function getAge(): ?int
        public function setAge(?int $age): self
        public function getName(): ?string
        public function setName(?string $name): self

expected interface

        /** @var int|null The age of the person */
        protected $age = NULL;
        /** @var string The name of the person */
        protected $name;

        public function getAge(): ?int
        public function setAge(?int $age): self
        public function getName(): string
        public function setName(string $name): self

Version:
all versions

No nested schema for composed property

Describe the bug
With this schema I get this error I don't understand: No nested schema for composed property Address in file Adress.json found

Expected behavior
I don't see anything wrong with this schema so I'd expect it to generate the appropriate class.

Schema

{
    "$schema": "http://json-schema.org/draft-04/schema#",
    "oneOf": [
        { "type": "string" },
        {
            "type": "object",
            "properties": {
                "address": { "type": "string" },
                "specialDelivery": { "type": "string" },
                "zipCode": { "type": "string" },
                "city": { "type": "string" }
            },
            "additionalProperties": false
        }
    ]
}

No custom GeneratorConfiguration.

Version:
0.22.0

Error when generating classes with FedEx OpenAPI schema

Describe the bug
When I use this library to try to generate PHP classes from FedEx's OpenAPI schema for their new RESTful API, I get this error:

PHP Fatal error: Uncaught PHPModelGenerator\Exception\SchemaException: No nested schema for composed property RequestePackageLineItemDimensions in file /[...]/utils/../schemas/rate.json

(Note: that should be RequestedPackageLineItemDimensions, but the first 'd' is missing in the reference and the definition, so it shouldn't matter.)

This is mentioned in issue 57, but the solution there was to alter the schema. Since the goal is to be as hands-off as possible, I'd much prefer to simply download the schemas and run this function on them. I don't want to have to modify every schema we need (ship, rate, address validation, and more) each time we have to update to a new API release. I've installed a java-based tool that converts schemas into PHP, and it didn't encounter this problem when using this schema, so I know it's possible. I also validated the schema with two online validators, and both indicated that the JSON is valid for OpenAPI.

Expected behavior

Given that this is a valid OpenAPI 3 schema from a major company, I expect it to be processed into PHP classes properly.

Schema

https://developer.fedex.com/api/en-us/catalog/rate/v1/docs.html > click "download JSON schema". I'd link to it directly here, but the page uses some JS to actually serve the JSON file.

Here's the function I'm using to try to generate the classes:

function generate() {
	$generator = new ModelGenerator(
		(new GeneratorConfiguration())
		->setNamespacePrefix('models\fedex')
		->setSerialization(true)
		->setCollectErrors(false)
		->setImmutable(false)
	);
	$schemaPath = dirname(__FILE__) . '/../schemas/rate.json';
	$resultDirectory = dirname(__FILE__) . '/../models/fedex';
	$generator
		->generateModelDirectory($resultDirectory)
		->generateModels(new OpenAPIv3Provider($schemaPath), $resultDirectory);
}

Version:

0.23.3

Additional context

I don't think I have anything to add. I'm experienced with PHP, but very new to OpenAPI and class generation. If more information is required, please ask.

Support number property key

Unfortunately some of the data we had to describe in our Json Schema are objects with number as keys like so:

"Markets": {
  "type": "object",
  "additionalProperties": false,
  "properties": {
    "2201": {
      "type": "string"
    },
    "2202": {
      "type": "string"
    },
    "2203": {
      "type": "string"
    },
    "2204": {
      "type": "string"
    },
  }
}

Could it be possible to support this?

Filter for a property inside a Composition inside an array is not executed

Describe the bug
Independent of a provided value or a default value the value for created is not transformed resulting in a fatal error when calling the generated getCreated:

Uncaught TypeError: ...::getCreated(): Return value must be of type ?DateTime, string returned

The issue also affects non-transforming filters like trim.

Expected behavior

The transformed filter should be executed and consequently a DateTime object should be returned.

Schema

{
  "type": "object",
  "properties": {
    "songs": {
      "type": "array",
      "items":{
        "allOf": [
          {
            "type": "object",
            "properties": {
              "title": {
                "type": "string"
              }
            },
            "required": [
              "title"
            ]
          },
          {
            "type": "object",
            "properties": {
              "created": {
                "type": "string",
                "filter": "dateTime",
                "default": "now"
              }
            }
          }
        ]
      }
    }
  }
}

Version:
0.23.2

Incorrectly escaped backslashes in regex in generated code

Describe the bug

    },
    "main": {
      "description": "The fully-qualified name of the main class that extends PluginBase",
      "pattern": "([A-Za-z_]\\w+\\\\)*([A-Za-z_]\\w+)",
      "type": "string"
    },

This schema causes the following code to be generated:

                    if (is_string($value) && !preg_match('/([A-Za-z_]\w+\\)*([A-Za-z_]\w+)/', $value)) {
                        $this->_errorRegistry->addError(new \PHPModelGenerator\Exception\String\PatternException($value ?? null, ...array (
  0 => 'main',
  1 => '([A-Za-z_]\\w+\\\\)*([A-Za-z_]\\w+)',
)));
                    }
                

                return $value;
            }

This pattern is meant to allow backslashes, hence the 4 \\\\ (to match the literal backslash character).

You can see that the backslash given to preg_match() is incorrectly escaped: there are only 2 backslashes in the resulting string, which is interpreted by PHP as a single backslash even in a single-quoted string.

Expected behavior
The backslash pattern above should be correctly escaped.

Schema
plugin-schema.json.txt

Version:
0.21.0

Constructor with explicit argument

I'd like to be able to detect missing/badly typed properties with static analysis.
So the __construct(array $rawModelDataInput = []) is not ideal in that regards since dev will see their error at runtime.

Would it be possible, maybe via a config option, to generate constructor of the form __construct(string $propA, int $propB)?

With php 8.1 we would also be able to use named arguments to avoid unreadable constructors.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.