From 8b96324544211e96d663203b8a69c21e5edadb88 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Wed, 24 Nov 2021 18:08:35 +0100 Subject: [PATCH] feat(schema-generator): attributes + load file --- schema-generator/configuration.md | 217 ++++++++++++++++------------ schema-generator/getting-started.md | 22 ++- schema-generator/index.md | 13 +- 3 files changed, 148 insertions(+), 104 deletions(-) diff --git a/schema-generator/configuration.md b/schema-generator/configuration.md index 5aa27d5a3af..1fdcf942249 100644 --- a/schema-generator/configuration.md +++ b/schema-generator/configuration.md @@ -87,10 +87,10 @@ types: Organization: properties: contactPoint: { range: Person, relationTableName: organization_contactPoint } - member: { range: Person, cardinality: (1..*) } ## Will be default value : organization_person + member: { range: Person, cardinality: (1..*) } # Will be the default value: organization_person ``` -## Forcing (or Disabling) a Class Parent +## Forcing (or Enabling) a Class Parent Override the guessed class hierarchy of a given type with this option. @@ -102,7 +102,7 @@ types: parent: Thing # Force the parent to be Thing instead of CreativeWork > MediaObject properties: ~ Drug: - parent: false # No parent + parent: ~ # Enable the class hierarchy for this type ``` ## Forcing a Class to be Abstract @@ -133,6 +133,25 @@ types: route_name: get_person_collection ``` +## Define Security + +API Platform security directives can be added to a generated file, at the class level: + +```yaml +types: + Person: + security: "is_granted('ROLE_USER')" +``` + +Or at a property level: + +```yaml +types: + Person: + properties: + email: { security: "is_granted('ROLE_ADMIN')" } +``` + ## Forcing a Nullable Property Force a property to be (or to not be) `nullable`. @@ -147,7 +166,7 @@ Example: name: { nullable: false } ``` -The `@Assert\NotNull` constraint is automatically added. +The `#[Assert\NotNull]` constraint is automatically added. ```php " ## Disabling Generators and Creating Custom Ones -By default, all generators except `DunglasJsonLdApi` (API Platform v1) and `SerializerGroups` are enabled. -You can specify the list of generators to use with the `annotationGenerators` option. +By default, all generators except `DoctrineMongoDBAttributeGenerator` are enabled. +You can specify the list of generators to use with the `annotationGenerators` and `attributeGenerators` option. Example (enabling only the PHPDoc generator): ```yaml annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator +attributeGenerators: [] ``` -You can write your generators by implementing the `AnnotationGeneratorInterface`. -The `AbstractAnnotationGenerator` provides helper methods +You can write your own generators by implementing the `AnnotationGeneratorInterface` or `AttributeGeneratorInterface`. +The `AbstractAnnotationGenerator` or `AbstractAttributeGenerator` provides helper methods useful when creating your own generators. -Enabling a custom generator and the PHPDoc generator: +Enabling a custom attribute generator and the PHPDoc generator: ```yaml annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator +attributeGenerators - Acme\Generators\MyGenerator ``` @@ -407,7 +421,7 @@ This behavior can be disabled with the following setting: ```yaml id: - generate: false + generate: false ``` ## Generating UUIDs @@ -416,17 +430,17 @@ It's also possible to let the DBMS generate [UUIDs](https://en.wikipedia.org/wik ```yaml id: - generationStrategy: uuid + generationStrategy: uuid ``` -## User submitted UUIDs +## User-submitted UUIDs To manually set a UUID instead of letting the DBMS generate it, use the following config: ```yaml id: - generationStrategy: uuid - writable: true + generationStrategy: uuid + writable: true ``` ## Generating Custom IDs @@ -436,13 +450,13 @@ generated, but the DBMS will not generate anything. The ID must be set manually. ```yaml id: - generationStrategy: none + generationStrategy: none ``` ## Disabling Usage of Doctrine Collections By default, the generator uses classes provided by the [Doctrine Collections](https://github.com/doctrine/collections) library -to store collections of entities. This is useful (and required) when using Doctrine ORM or Doctrine ODM. +to store collections of entities. This is useful (and required) when using Doctrine ORM or Doctrine MongoDB ODM. This behavior can be disabled (to fallback to standard arrays) with the following setting: ```yaml @@ -461,31 +475,28 @@ Example: fieldVisibility: "protected" ``` -## Generating `@Assert\Type` Annotations +## Generating `Assert\Type` Attributes -It's possible to automatically generate Symfony validator's `@Assert\Type` annotations using the following config: +It's possible to automatically generate Symfony validator's `#[Assert\Type]` attributes using the following config: ```yaml validator: - assertType: true + assertType: true ``` -## Forcing Doctrine Inheritance Mapping Annotation +## Forcing Doctrine Inheritance Mapping Attribute -The standard behavior of the generator is to use the `@MappedSuperclass` Doctrine annotation for classes with children and -`@Entity` for classes with no child. +The standard behavior of the generator is to use the `#[MappedSuperclass]` Doctrine attribute for classes with children and +`#[Entity]` for classes with no child. -The inheritance annotation can be forced for a given type in the following way: +The inheritance attribute can be forced in the following way: ```yaml -types: - Product: - doctrine: - inheritanceMapping: "@MappedSuperclass" +doctrine: + inheritanceAttributes: + CustomInheritanceAttribute: [] ``` -*This setting is only relevant when using the Doctrine ORM generator.* - ## Interfaces and Doctrine Resolve Target Entity Listener [`ResolveTargetEntityListener`](https://www.doctrine-project.org/projects/doctrine-orm/en/current/cookbook/resolve-target-entity-listener.html) @@ -495,28 +506,38 @@ mappings. If you set the option `useInterface` to true, the generator will generate an interface corresponding to each generated entity and will use them in relation mappings. -To let PHP Schema generate the XML mapping file usable with Symfony, add the following to your config file: +To let the schema generator generate the XML mapping file usable with Symfony, add the following to your config file: ```yaml doctrine: resolveTargetEntityConfigPath: path/to/doctrine.xml ``` +### Doctrine Resolve Target Entity Config Type + +By default the mapping file is in XML. If you want to have a yaml file, add the following: + +```yaml +doctrine: + resolveTargetEntityConfigPath: path/to/doctrine.yaml + resolveTargetEntityConfigType: yaml +``` + ## Custom Schemas -The generator can use your own schema definitions. They must be written in RDFa and follow the format of the [Schema.org's -definition](https://schema.org/docs/schema_org_rdfa.html). This is useful to document your [Schema.org extensions](https://schema.org/docs/extension.html) and use them +The generator can use your own schema definitions. They must be written in RDF/XML and follow the format of the [Schema.org's +definition](https://schema.org/version/latest/schemaorg-current-https.rdf). This is useful to document your [Schema.org extensions](https://schema.org/docs/extension.html) and use them to generate the PHP data model of your application. Example: ```yaml vocabularies: - - https://raw.githubusercontent.com/schemaorg/schemaorg/master/data/schema.rdfa # Experimental version of Schema.org - - http://example.com/data/myschema.rfa # Additional types + - https://github.com/schemaorg/schemaorg/raw/main/data/releases/13.0/schemaorg-current-https.rdf + - http://example.com/data/myschema.rdf # Additional types ``` -You can also use any other vocabulary. Check the [Linked Open Vocabularies](https://lov.okfn.org/dataset/lov/) to find one fitting your needs. +You can also use any other vocabulary. Check the [Linked Open Vocabularies](https://lov.linkeddata.es/dataset/lov/) to find one fitting your needs. For instance, to generate a data model from the [Video Game Ontology](http://purl.org/net/VideoGameOntology), use the following config file: @@ -568,19 +589,19 @@ config: - # RDF vocabulary to use - uri: 'https://schema.org/version/latest/schemaorg-current-http.rdf' # Example: 'https://schema.org/version/latest/schemaorg-current-http.rdf' + uri: 'https://schema.org/version/latest/schemaorg-current-https.rdf' # Example: 'https://schema.org/version/latest/schemaorg-current-https.rdf' # RDF vocabulary format format: null # Example: rdfxml # Namespace of the vocabulary to import - vocabularyNamespace: 'http://schema.org/' # Example: 'http://www.w3.org/ns/activitystreams#' + vocabularyNamespace: 'https://schema.org/' # Example: 'http://www.w3.org/ns/activitystreams#' # OWL relation files containing cardinality information in the GoodRelations format - relations: # Example: 'https://purl.org/goodrelations/v1.owl' + relations: # Example: 'https://archive.org/services/purl/goodrelations/v1.owl' # Default: - - https://purl.org/goodrelations/v1.owl + - https://archive.org/services/purl/goodrelations/v1.owl # Debug mode debug: false @@ -607,7 +628,7 @@ config: checkIsGoodRelations: false # A license or any text to use as header of generated files - header: false # Example: '// (c) Kévin Dunglas ' + header: null # Example: '// (c) Kévin Dunglas ' # PHP namespaces namespaces: @@ -630,11 +651,14 @@ config: # Use Doctrine's ArrayCollection instead of standard arrays useCollection: true - # The Resolve Target Entity Listener config file pass + # The Resolve Target Entity Listener config file path resolveTargetEntityConfigPath: null - # Doctrine inheritance annotations (if set, no other annotations are generated) - inheritanceAnnotations: [] + # The Resolve Target Entity Listener config file type + resolveTargetEntityConfigType: XML # One of "XML"; "yaml" + + # Doctrine inheritance attributes (if set, no other attributes are generated) + inheritanceAttributes: [] # Symfony Validator Component validator: @@ -689,8 +713,8 @@ config: interface: null doctrine: - # Doctrine annotations (if set, no other annotations are generated) - annotations: [] + # Doctrine attributes (if set, no other attributes are generated) + attributes: [] # The parent class, set to false for a top level class parent: false @@ -701,6 +725,9 @@ config: # Operations for the class operations: [] + # Security directive for the class + security: null + # Import all existing properties allProperties: false @@ -720,8 +747,11 @@ config: relationTableName: null # Example: organization_member cardinality: unknown # One of "(0..1)"; "(0..*)"; "(1..1)"; "(1..*)"; "(*..0)"; "(*..1)"; "(*..*)"; "unknown" - # The doctrine column annotation content - ormColumn: null # Example: 'type="decimal", precision=5, scale=1, options={"comment" = "my comment"}' + # The doctrine column attribute content + ormColumn: [] # Example: '{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}' + + # Security directive for the property + security: null # Symfony Serialization Groups groups: [] @@ -753,12 +783,17 @@ config: # Annotation generators to use annotationGenerators: - # Defaults: + # Default: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\SerializerGroupsAnnotationGenerator + + # Attribute generators to use + attributeGenerators: + + # Defaults: + - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator # Directories for custom generator twig templates generatorTemplates: [] diff --git a/schema-generator/getting-started.md b/schema-generator/getting-started.md index bfa7ae30125..cc2692ca205 100644 --- a/schema-generator/getting-started.md +++ b/schema-generator/getting-started.md @@ -26,8 +26,8 @@ Then, write a simple YAML config file similar to the following. Here we will generate a data model for an address book with the following data: -* a [`Person`](http://schema.org/Person) which inherits from [`Thing`](http://schema.org/Thing) -* a [`PostalAddress`](http://schema.org/PostalAddress) which inherits from [`ContactPoint`](http://schema.org/ContactPoint), which itself inherits from [`StructuredValue`](http://schema.org/StructuredValue), etc. +* a [`Person`](https://schema.org/Person) which inherits from [`Thing`](https://schema.org/Thing) +* a [`PostalAddress`](https://schema.org/PostalAddress) (without its class hierarchy) ```yaml # api/config/schema.yaml @@ -38,14 +38,14 @@ types: properties: name: ~ Person: + # Enable the generation of the class hierarchy (not enabled by default) + parent: ~ properties: familyName: ~ givenName: ~ additionalName: ~ address: ~ PostalAddress: - # Disable the generation of the class hierarchy for this type - parent: false properties: # Force the type of the addressCountry property to text addressCountry: { range: "Text" } @@ -59,14 +59,14 @@ types: Run the generator with this config file as parameter: ```console -vendor/bin/schema generate api/src/ api/config/schema.yaml +vendor/bin/schema generate api/src/ api/config/schema.yaml -vv ``` Using [the API Platform Distribution](../distribution/index.md): ```console docker-compose exec php \ - vendor/bin/schema generate src/ config/schema.yaml + vendor/bin/schema generate src/ config/schema.yaml -vv ``` The corresponding PHP classes will be automatically generated in the `src/` directory! @@ -85,9 +85,17 @@ A config file generating an enum class: ```yaml types: OfferItemCondition: # The generator will automatically guess that OfferItemCondition is subclass of Enum - properties: {} # Remove all properties of the parent class + properties: {} # Remove all properties of the parent class ``` +### Load Previously Generated Files + +If you launch the schema generator again, the previously generated files will be loaded. + +It will try to keep as much user-added changes as possible while adding the new changes from the configuration file. + +You can also choose to overwrite the file instead. + ### Going Further Browse [the configuration documentation](configuration.md) diff --git a/schema-generator/index.md b/schema-generator/index.md index b92ef44510f..33b582a8273 100644 --- a/schema-generator/index.md +++ b/schema-generator/index.md @@ -11,12 +11,12 @@ fully featured PHP data model including: hierarchy provided by the vocabulary will be translated to a PHP class hierarchy with parents as `abstract` classes. The generated code complies with [PSR](http://www.php-fig.org/) coding standards ; * Full, high-quality PHPDoc for classes, properties, constants and methods extracted from the vocabulary ; -* Doctrine ORM annotation mapping including database columns with type guessing, relations with cardinality guessing, class -inheritance (through the `@AbstractSuperclass` annotation) ; -* Data validation through [Symfony Validator](https://symfony.com/doc/current/book/validation.html) annotations including +* Doctrine ORM or MongoDB ODM attributes mapping including database columns / fields with type guessing, relations with cardinality guessing, class +inheritance (through the `#[MappedSuperclass]` attribute) ; +* Data validation through [Symfony Validator](https://symfony.com/doc/current/book/validation.html) attributes including data type validation, enum support (choices) and check for required properties ; -* API Platform Core annotations ; -* Interfaces and [Doctrine `ResolveTargetEntityListener`](https://doctrine-orm.readthedocs.org/en/latest/cookbook/resolve-target-entity-listener.html) +* API Platform attributes ; +* Interfaces and [Doctrine `ResolveTargetEntityListener`](https://www.doctrine-project.org/projects/doctrine-orm/en/current/cookbook/resolve-target-entity-listener.html) support ; * Custom PHP namespace support ; * List of values provided the vocabulary with [PHP Enum](https://github.com/myclabs/php-enum) classes. @@ -25,13 +25,14 @@ Bonus: * The code generator is fully configurable and extendable. All features can be deactivated (e.g., the Doctrine mapping generator) and a custom generator can be added (e.g., a Doctrine ODM mapping generator) ; +* The code generator can load previously generated files and add new changes while keeping the user-added ones. * The generated code can be used as is in a [Symfony](https://symfony.com) app (but it will work too in a raw PHP project or any other framework including [Laravel](https://laravel.com) and [Zend Framework](http://framework.zend.com/)). ## What Is Schema.org? Schema.org is a vocabulary representing common data structures and their relations. Schema.org can be exposed as [JSON-LD](https://en.wikipedia.org/wiki/JSON-LD), -[microdata](https://en.wikipedia.org/wiki/Microdata_(HTML)) and [RDFa](https://en.wikipedia.org/wiki/RDFa). +[microdata](https://en.wikipedia.org/wiki/Microdata_(HTML)) and [RDF](https://en.wikipedia.org/wiki/Resource_Description_Framework). Extracting semantical data exposed in the Schema.org vocabulary is supported by a growing number of companies including Google (Search, Gmail), Yahoo!, Bing and Yandex.