From bffaf8393ab6e1795cedc60279c04b9f3254eee3 Mon Sep 17 00:00:00 2001 From: Labrut Date: Wed, 22 Apr 2015 09:43:53 +0200 Subject: [PATCH 001/258] Update and rename DunglasJsonLdApiAnnotationGenerator.php to DunglasApiAnnotationGenerator.php --- ...ionGenerator.php => DunglasApiAnnotationGenerator.php} | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) rename src/SchemaOrgModel/AnnotationGenerator/{DunglasJsonLdApiAnnotationGenerator.php => DunglasApiAnnotationGenerator.php} (79%) diff --git a/src/SchemaOrgModel/AnnotationGenerator/DunglasJsonLdApiAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php similarity index 79% rename from src/SchemaOrgModel/AnnotationGenerator/DunglasJsonLdApiAnnotationGenerator.php rename to src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php index 64c216ea..69c5b2d5 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DunglasJsonLdApiAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -12,13 +12,13 @@ use SchemaOrgModel\TypesGenerator; /** - * Generates Iri annotations provided by DunglasJsonLdApiBundle. + * Generates Iri annotations provided by DunglasApiBundle. * * @author Kévin Dunglas * - * @link https://github.com/dunglas/DunglasJsonLdApiBundle + * @link https://github.com/dunglas/DunglasApiBundle */ -class DunglasJsonLdApiAnnotationGenerator extends AbstractAnnotationGenerator +class DunglasApiAnnotationGenerator extends AbstractAnnotationGenerator { /** * {@inheritdoc} @@ -48,6 +48,6 @@ public function generateUses($className) $subClassOf = $resource->get('rdfs:subClassOf'); $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; - return $typeIsEnum ? [] : ['Dunglas\JsonLdApiBundle\Annotation\Iri']; + return $typeIsEnum ? [] : ['Dunglas\ApiBundle\Annotation\Iri']; } } From 4944d6465cfa9b7515dfbb3efcfcdccaa0d8157c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 15 May 2015 19:29:44 +0200 Subject: [PATCH 002/258] Fix doc and test about DunglasApiBundle. Update dependencies. --- composer.json | 4 +- composer.lock | 789 +++++++++++++++++--------- doc/getting-started.md | 6 +- src/SchemaOrgModel/TypesGenerator.php | 6 +- tests/config/address-book.yml | 2 +- 5 files changed, 533 insertions(+), 274 deletions(-) diff --git a/composer.json b/composer.json index c6d1fa8b..1c662ab0 100644 --- a/composer.json +++ b/composer.json @@ -31,8 +31,8 @@ "require-dev": { "doctrine/orm": "~2.2", "symfony/validator": "~2.6", - "symfony/serializer": "~2.7@dev", - "dunglas/json-ld-api-bundle": "dev-master" + "symfony/serializer": "~2.7@beta", + "dunglas/api-bundle": "dev-master" }, "suggest": { "myclabs/php-enum": "For enumerations", diff --git a/composer.lock b/composer.lock index 66cdb188..0a068498 100644 --- a/composer.lock +++ b/composer.lock @@ -1,10 +1,10 @@ { "_readme": [ "This file locks the dependencies of your project to a known state", - "Read more about it at http://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "370daf89e5091cc3d21a846596f7dd85", + "hash": "dbb82a4d5c2b8ce56c643771b1c22506", "packages": [ { "name": "easyrdf/easyrdf", @@ -70,22 +70,23 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.6", + "version": "v1.8", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "81a46f8a0f92f1ba64587b384a275d0766cf2c70" + "reference": "93c723fe0c50ed54292006e7249a4c1173cf5847" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/81a46f8a0f92f1ba64587b384a275d0766cf2c70", - "reference": "81a46f8a0f92f1ba64587b384a275d0766cf2c70", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/93c723fe0c50ed54292006e7249a4c1173cf5847", + "reference": "93c723fe0c50ed54292006e7249a4c1173cf5847", "shasum": "" }, "require": { + "ext-tokenizer": "*", "php": ">=5.3.6", "sebastian/diff": "~1.1", - "symfony/console": "~2.1", + "symfony/console": "~2.3", "symfony/event-dispatcher": "~2.1", "symfony/filesystem": "~2.1", "symfony/finder": "~2.1", @@ -118,8 +119,8 @@ "email": "fabien@symfony.com" } ], - "description": "A script to automatically fix Symfony Coding Standard", - "time": "2015-03-26 21:09:59" + "description": "A tool to automatically fix PHP code style", + "time": "2015-05-04 17:06:20" }, { "name": "nickcernis/html-to-markdown", @@ -259,17 +260,17 @@ }, { "name": "symfony/config", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Config", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "d91be01336605db8da21b79bc771e46a7276d1bc" + "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/d91be01336605db8da21b79bc771e46a7276d1bc", - "reference": "d91be01336605db8da21b79bc771e46a7276d1bc", + "url": "https://api.github.com/repos/symfony/Config/zipball/b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25", + "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25", "shasum": "" }, "require": { @@ -295,32 +296,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Config Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/console", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Console", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667" + "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/5b91dc4ed5eb08553f57f6df04c4730a73992667", - "reference": "5b91dc4ed5eb08553f57f6df04c4730a73992667", + "url": "https://api.github.com/repos/symfony/Console/zipball/ebc5679854aa24ed7d65062e9e3ab0b18a917272", + "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272", "shasum": "" }, "require": { @@ -353,32 +354,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Console Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/event-dispatcher", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/EventDispatcher", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284" + "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/70f7c8478739ad21e3deef0d977b38c77f1fb284", - "reference": "70f7c8478739ad21e3deef0d977b38c77f1fb284", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02", + "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02", "shasum": "" }, "require": { @@ -412,32 +413,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony EventDispatcher Component", - "homepage": "http://symfony.com/", - "time": "2015-03-13 17:37:22" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/filesystem", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Filesystem", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "4983964b3693e4f13449cb3800c64a9112c301b4" + "reference": "f73904bd2dae525c42ea1f0340c7c98480ecacde" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/4983964b3693e4f13449cb3800c64a9112c301b4", - "reference": "4983964b3693e4f13449cb3800c64a9112c301b4", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/f73904bd2dae525c42ea1f0340c7c98480ecacde", + "reference": "f73904bd2dae525c42ea1f0340c7c98480ecacde", "shasum": "" }, "require": { @@ -462,32 +463,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Filesystem Component", - "homepage": "http://symfony.com/", - "time": "2015-03-22 16:55:57" + "homepage": "https://symfony.com/", + "time": "2015-05-08 00:09:07" }, { "name": "symfony/finder", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Finder", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "5dbe2e73a580618f5b4880fda93406eed25de251" + "reference": "704c64c8b12c8882640d5c0330a8414b1e06dc99" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/5dbe2e73a580618f5b4880fda93406eed25de251", - "reference": "5dbe2e73a580618f5b4880fda93406eed25de251", + "url": "https://api.github.com/repos/symfony/Finder/zipball/704c64c8b12c8882640d5c0330a8414b1e06dc99", + "reference": "704c64c8b12c8882640d5c0330a8414b1e06dc99", "shasum": "" }, "require": { @@ -512,32 +513,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Finder Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/process", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Process", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552" + "reference": "9f3c4baaf840ed849e1b1f7bfd5ae246e8509562" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/a8bebaec1a9dc6cde53e0250e32917579b0be552", - "reference": "a8bebaec1a9dc6cde53e0250e32917579b0be552", + "url": "https://api.github.com/repos/symfony/Process/zipball/9f3c4baaf840ed849e1b1f7bfd5ae246e8509562", + "reference": "9f3c4baaf840ed849e1b1f7bfd5ae246e8509562", "shasum": "" }, "require": { @@ -562,32 +563,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Process Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/stopwatch", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Stopwatch", "source": { "type": "git", "url": "https://github.com/symfony/Stopwatch.git", - "reference": "5f196e84b5640424a166d2ce9cca161ce1e9d912" + "reference": "b470f87c69837cb71115f1fa720388bb19b63635" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/5f196e84b5640424a166d2ce9cca161ce1e9d912", - "reference": "5f196e84b5640424a166d2ce9cca161ce1e9d912", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/b470f87c69837cb71115f1fa720388bb19b63635", + "reference": "b470f87c69837cb71115f1fa720388bb19b63635", "shasum": "" }, "require": { @@ -612,32 +613,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Stopwatch Component", - "homepage": "http://symfony.com/", - "time": "2015-03-22 16:55:57" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/yaml", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Yaml", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "174f009ed36379a801109955fc5a71a49fe62dd4" + "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/174f009ed36379a801109955fc5a71a49fe62dd4", - "reference": "174f009ed36379a801109955fc5a71a49fe62dd4", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/f157ab074e453ecd4c0fa775f721f6e67a99d9e2", + "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2", "shasum": "" }, "require": { @@ -662,35 +663,35 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Yaml Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "twig/twig", - "version": "v1.18.0", + "version": "v1.18.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "4cf7464348e7f9893a93f7096a90b73722be99cf" + "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/4cf7464348e7f9893a93f7096a90b73722be99cf", - "reference": "4cf7464348e7f9893a93f7096a90b73722be99cf", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9f70492f44398e276d1b81c1b43adfe6751c7b7f", + "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f", "shasum": "" }, "require": { - "php": ">=5.2.4" + "php": ">=5.2.7" }, "type": "library", "extra": { @@ -730,22 +731,22 @@ "keywords": [ "templating" ], - "time": "2015-01-25 17:32:08" + "time": "2015-04-19 08:30:27" } ], "packages-dev": [ { "name": "doctrine/annotations", - "version": "v1.2.3", + "version": "v1.2.4", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "eeda578cbe24a170331a1cfdf78be723412df7a4" + "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/eeda578cbe24a170331a1cfdf78be723412df7a4", - "reference": "eeda578cbe24a170331a1cfdf78be723412df7a4", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/b5202eb9e83f8db52e0e58867e0a46e63be8332e", + "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e", "shasum": "" }, "require": { @@ -800,20 +801,20 @@ "docblock", "parser" ], - "time": "2014-12-20 20:49:38" + "time": "2014-12-23 22:40:37" }, { "name": "doctrine/cache", - "version": "v1.4.0", + "version": "v1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "2346085d2b027b233ae1d5de59b07440b9f288c8" + "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/2346085d2b027b233ae1d5de59b07440b9f288c8", - "reference": "2346085d2b027b233ae1d5de59b07440b9f288c8", + "url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03", + "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03", "shasum": "" }, "require": { @@ -824,13 +825,13 @@ }, "require-dev": { "phpunit/phpunit": ">=3.7", - "predis/predis": "~0.8", + "predis/predis": "~1.0", "satooshi/php-coveralls": "~0.6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.5.x-dev" } }, "autoload": { @@ -870,25 +871,28 @@ "cache", "caching" ], - "time": "2015-01-15 20:38:55" + "time": "2015-04-15 00:11:59" }, { "name": "doctrine/collections", - "version": "v1.2", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "b99c5c46c87126201899afe88ec490a25eedd6a2" + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/b99c5c46c87126201899afe88ec490a25eedd6a2", - "reference": "b99c5c46c87126201899afe88ec490a25eedd6a2", + "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", + "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", "shasum": "" }, "require": { "php": ">=5.3.2" }, + "require-dev": { + "phpunit/phpunit": "~4.0" + }, "type": "library", "extra": { "branch-alias": { @@ -905,17 +909,6 @@ "MIT" ], "authors": [ - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com", - "homepage": "http://www.jwage.com/", - "role": "Creator" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com", - "homepage": "http://www.instaclick.com/" - }, { "name": "Roman Borschel", "email": "roman@code-factory.org" @@ -924,11 +917,17 @@ "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Jonathan Wage", + "email": "jonwage@gmail.com" + }, { "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com", - "homepage": "https://github.com/schmittjoh", - "role": "Developer of wrapped JMSSerializerBundle" + "email": "schmittjoh@gmail.com" } ], "description": "Collections Abstraction library", @@ -938,7 +937,7 @@ "collections", "iterator" ], - "time": "2014-02-03 23:07:43" + "time": "2015-04-14 22:21:58" }, { "name": "doctrine/common", @@ -1498,17 +1497,17 @@ "time": "2015-04-02 20:40:18" }, { - "name": "dunglas/json-ld-api-bundle", + "name": "dunglas/api-bundle", "version": "dev-master", "source": { "type": "git", - "url": "https://github.com/dunglas/DunglasJsonLdApiBundle.git", - "reference": "b0ccbb3131c711539752d183ffc35803b5cb5584" + "url": "https://github.com/dunglas/DunglasApiBundle.git", + "reference": "7658b196dc4fe906012a6f4ca70352769ef00d81" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/DunglasJsonLdApiBundle/zipball/b0ccbb3131c711539752d183ffc35803b5cb5584", - "reference": "b0ccbb3131c711539752d183ffc35803b5cb5584", + "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/7658b196dc4fe906012a6f4ca70352769ef00d81", + "reference": "7658b196dc4fe906012a6f4ca70352769ef00d81", "shasum": "" }, "require": { @@ -1516,10 +1515,12 @@ "doctrine/inflector": "~1.0", "doctrine/orm": "~2.2,>=2.2.3", "dunglas/php-property-info": "~0.2", + "ocramius/proxy-manager": "~1.0", "php": ">=5.5", "phpdocumentor/reflection": "^1.0.7", "symfony/framework-bundle": "~2.6|~3.0", - "symfony/serializer": "~3.0|~2.7@dev", + "symfony/proxy-manager-bridge": "~2.3", + "symfony/serializer": "~3.0|~2.7@beta", "symfony/validator": "~2.5|~3.0" }, "require-dev": { @@ -1528,10 +1529,10 @@ "behat/mink-browserkit-driver": "~1.1", "behat/mink-extension": "~2.0", "behat/symfony2-extension": "~2.0", - "behatch/contexts": "~2.2", + "behatch/contexts": "~2.1", "friendsofsymfony/user-bundle": "dev-master", "phpspec/phpspec": "~2.0", - "symfony/symfony": "~2.7@dev" + "symfony/symfony": "~2.7@beta" }, "suggest": { "friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge." @@ -1544,7 +1545,7 @@ }, "autoload": { "psr-4": { - "Dunglas\\JsonLdApiBundle\\": "" + "Dunglas\\ApiBundle\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1567,7 +1568,7 @@ "json", "rest" ], - "time": "2015-04-06 11:35:01" + "time": "2015-05-14 21:45:06" }, { "name": "dunglas/php-property-info", @@ -1719,6 +1720,69 @@ ], "time": "2014-07-23 18:24:17" }, + { + "name": "ocramius/proxy-manager", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/Ocramius/ProxyManager.git", + "reference": "a80a39fac4fbd771aea7d3871929933a3a1bbf3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/a80a39fac4fbd771aea7d3871929933a3a1bbf3e", + "reference": "a80a39fac4fbd771aea7d3871929933a3a1bbf3e", + "shasum": "" + }, + "require": { + "php": ">=5.3.3", + "zendframework/zend-code": ">2.2.5,<3.0" + }, + "require-dev": { + "ext-phar": "*", + "phpunit/phpunit": "~4.0", + "squizlabs/php_codesniffer": "1.5.*" + }, + "suggest": { + "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects", + "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)", + "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)", + "zendframework/zend-stdlib": "To use the hydrator proxy", + "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "ProxyManager\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies", + "homepage": "https://github.com/Ocramius/ProxyManager", + "keywords": [ + "aop", + "lazy loading", + "proxy", + "proxy pattern", + "service proxies" + ], + "time": "2014-12-12 10:59:05" + }, { "name": "phpdocumentor/reflection", "version": "1.0.7", @@ -1824,17 +1888,17 @@ }, { "name": "symfony/debug", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Debug", "source": { "type": "git", "url": "https://github.com/symfony/Debug.git", - "reference": "d49a46a20a8f0544aedac54466750ad787d3d3e3" + "reference": "ad4511a8fddce7ec163b513ba39a30ea4f32c9e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/d49a46a20a8f0544aedac54466750ad787d3d3e3", - "reference": "d49a46a20a8f0544aedac54466750ad787d3d3e3", + "url": "https://api.github.com/repos/symfony/Debug/zipball/ad4511a8fddce7ec163b513ba39a30ea4f32c9e7", + "reference": "ad4511a8fddce7ec163b513ba39a30ea4f32c9e7", "shasum": "" }, "require": { @@ -1870,32 +1934,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Debug Component", - "homepage": "http://symfony.com/", - "time": "2015-03-22 16:55:57" + "homepage": "https://symfony.com/", + "time": "2015-05-08 13:17:44" }, { "name": "symfony/dependency-injection", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/DependencyInjection", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "8e9007012226b4bd41f8afed855c452cf5edc3a6" + "reference": "b575c160af001d3525ee733085bcc4ec7c8e1b51" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/8e9007012226b4bd41f8afed855c452cf5edc3a6", - "reference": "8e9007012226b4bd41f8afed855c452cf5edc3a6", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b575c160af001d3525ee733085bcc4ec7c8e1b51", + "reference": "b575c160af001d3525ee733085bcc4ec7c8e1b51", "shasum": "" }, "require": { @@ -1931,32 +1995,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony DependencyInjection Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/doctrine-bridge", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Bridge/Doctrine", "source": { "type": "git", "url": "https://github.com/symfony/DoctrineBridge.git", - "reference": "6233098ffcafffeeb83225be8b8b0a496af8b16e" + "reference": "7ed45d2895343311ee1ed63ef9c57cec346181c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/6233098ffcafffeeb83225be8b8b0a496af8b16e", - "reference": "6233098ffcafffeeb83225be8b8b0a496af8b16e", + "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/7ed45d2895343311ee1ed63ef9c57cec346181c0", + "reference": "7ed45d2895343311ee1ed63ef9c57cec346181c0", "shasum": "" }, "require": { @@ -2001,32 +2065,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Doctrine Bridge", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/framework-bundle", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Bundle/FrameworkBundle", "source": { "type": "git", "url": "https://github.com/symfony/FrameworkBundle.git", - "reference": "34f0ea802a125ff1d28ed3923886127df31c8ee6" + "reference": "25217a4c326b4837c259629ef3f3087863b42b2c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/34f0ea802a125ff1d28ed3923886127df31c8ee6", - "reference": "34f0ea802a125ff1d28ed3923886127df31c8ee6", + "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/25217a4c326b4837c259629ef3f3087863b42b2c", + "reference": "25217a4c326b4837c259629ef3f3087863b42b2c", "shasum": "" }, "require": { @@ -2085,32 +2149,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony FrameworkBundle", - "homepage": "http://symfony.com/", - "time": "2015-03-27 10:19:51" + "homepage": "https://symfony.com/", + "time": "2015-05-04 14:53:25" }, { "name": "symfony/http-foundation", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/HttpFoundation", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9" + "reference": "8a0d00980ef9f6b47ddbf24bdfbf70fead760816" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/8a6337233f08f7520de97f4ffd6f00e947d892f9", - "reference": "8a6337233f08f7520de97f4ffd6f00e947d892f9", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/8a0d00980ef9f6b47ddbf24bdfbf70fead760816", + "reference": "8a0d00980ef9f6b47ddbf24bdfbf70fead760816", "shasum": "" }, "require": { @@ -2139,32 +2203,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony HttpFoundation Component", - "homepage": "http://symfony.com/", - "time": "2015-04-01 16:50:12" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/http-kernel", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/HttpKernel", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "3829cacfe21eaf3f73604a62d79183d1f6e792c4" + "reference": "2010194de0a57731af9404c7f97fd300db98b7a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/3829cacfe21eaf3f73604a62d79183d1f6e792c4", - "reference": "3829cacfe21eaf3f73604a62d79183d1f6e792c4", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/2010194de0a57731af9404c7f97fd300db98b7a3", + "reference": "2010194de0a57731af9404c7f97fd300db98b7a3", "shasum": "" }, "require": { @@ -2218,31 +2282,84 @@ ], "authors": [ { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony HttpKernel Component", + "homepage": "https://symfony.com/", + "time": "2015-05-11 01:58:49" + }, + { + "name": "symfony/proxy-manager-bridge", + "version": "v2.6.7", + "target-dir": "Symfony/Bridge/ProxyManager", + "source": { + "type": "git", + "url": "https://github.com/symfony/ProxyManagerBridge.git", + "reference": "9744a8ee680be6d50794f48cb376680a37a6bfb8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/ProxyManagerBridge/zipball/9744a8ee680be6d50794f48cb376680a37a6bfb8", + "reference": "9744a8ee680be6d50794f48cb376680a37a6bfb8", + "shasum": "" + }, + "require": { + "ocramius/proxy-manager": "~0.4|~1.0", + "php": ">=5.3.3", + "symfony/dependency-injection": "~2.3" + }, + "require-dev": { + "symfony/config": "~2.3", + "symfony/phpunit-bridge": "~2.7" + }, + "type": "symfony-bridge", + "extra": { + "branch-alias": { + "dev-master": "2.6-dev" + } + }, + "autoload": { + "psr-0": { + "Symfony\\Bridge\\ProxyManager\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony HttpKernel Component", - "homepage": "http://symfony.com/", - "time": "2015-04-01 16:55:26" + "description": "Symfony ProxyManager Bridge", + "homepage": "https://symfony.com/", + "time": "2015-05-06 14:13:47" }, { "name": "symfony/routing", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Routing", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "4e173a645b63ff60a124f3741b4f15feebd908fa" + "reference": "1455ec537940f7428ea6aa9411f3c4bca69413a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/4e173a645b63ff60a124f3741b4f15feebd908fa", - "reference": "4e173a645b63ff60a124f3741b4f15feebd908fa", + "url": "https://api.github.com/repos/symfony/Routing/zipball/1455ec537940f7428ea6aa9411f3c4bca69413a0", + "reference": "1455ec537940f7428ea6aa9411f3c4bca69413a0", "shasum": "" }, "require": { @@ -2280,38 +2397,38 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Routing Component", - "homepage": "http://symfony.com/", + "homepage": "https://symfony.com/", "keywords": [ "router", "routing", "uri", "url" ], - "time": "2015-03-30 15:54:10" + "time": "2015-05-02 15:18:45" }, { "name": "symfony/security", - "version": "v2.3.27", + "version": "v2.3.28", "target-dir": "Symfony/Component/Security", "source": { "type": "git", "url": "https://github.com/symfony/Security.git", - "reference": "25e914f2b63d4021af1fb0e510ac0843f1bdb3ee" + "reference": "4bc570e4ecad43b827f5c8852a4a4616ede89e4e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Security/zipball/25e914f2b63d4021af1fb0e510ac0843f1bdb3ee", - "reference": "25e914f2b63d4021af1fb0e510ac0843f1bdb3ee", + "url": "https://api.github.com/repos/symfony/Security/zipball/4bc570e4ecad43b827f5c8852a4a4616ede89e4e", + "reference": "4bc570e4ecad43b827f5c8852a4a4616ede89e4e", "shasum": "" }, "require": { @@ -2356,22 +2473,22 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Security Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:33:35" + "homepage": "https://symfony.com/", + "time": "2015-05-07 14:20:47" }, { "name": "symfony/security-core", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Security/Core", "source": { "type": "git", @@ -2435,7 +2552,7 @@ }, { "name": "symfony/security-csrf", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Security/Csrf", "source": { "type": "git", @@ -2490,17 +2607,16 @@ }, { "name": "symfony/serializer", - "version": "2.7.x-dev", - "target-dir": "Symfony/Component/Serializer", + "version": "v2.7.0-BETA2", "source": { "type": "git", "url": "https://github.com/symfony/Serializer.git", - "reference": "d8295ddc10069a4e146e2503f4fc31053ff86be3" + "reference": "122c2b000130e3ae0fe5029bcc111bb6b3ffaad6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Serializer/zipball/d8295ddc10069a4e146e2503f4fc31053ff86be3", - "reference": "d8295ddc10069a4e146e2503f4fc31053ff86be3", + "url": "https://api.github.com/repos/symfony/Serializer/zipball/122c2b000130e3ae0fe5029bcc111bb6b3ffaad6", + "reference": "122c2b000130e3ae0fe5029bcc111bb6b3ffaad6", "shasum": "" }, "require": { @@ -2509,10 +2625,10 @@ "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "symfony/config": "~2.2|~3.0.0", - "symfony/phpunit-bridge": "~2.7|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "~2.0|~3.0.0" + "symfony/config": "~2.2", + "symfony/phpunit-bridge": "~2.7", + "symfony/property-access": "~2.3", + "symfony/yaml": "~2.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", @@ -2528,7 +2644,7 @@ } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Serializer\\": "" } }, @@ -2537,32 +2653,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Serializer Component", - "homepage": "http://symfony.com/", - "time": "2015-03-22 16:57:18" + "homepage": "https://symfony.com/", + "time": "2015-05-04 07:31:19" }, { "name": "symfony/templating", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Templating", "source": { "type": "git", "url": "https://github.com/symfony/Templating.git", - "reference": "bc4879a794c1fa51fd7bd4bbc5bea33b7071b776" + "reference": "e5c1620f7480883e1de7ad104af100d25c49cd59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Templating/zipball/bc4879a794c1fa51fd7bd4bbc5bea33b7071b776", - "reference": "bc4879a794c1fa51fd7bd4bbc5bea33b7071b776", + "url": "https://api.github.com/repos/symfony/Templating/zipball/e5c1620f7480883e1de7ad104af100d25c49cd59", + "reference": "e5c1620f7480883e1de7ad104af100d25c49cd59", "shasum": "" }, "require": { @@ -2591,32 +2707,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Templating Component", - "homepage": "http://symfony.com/", - "time": "2015-03-13 17:37:22" + "homepage": "https://symfony.com/", + "time": "2015-05-02 15:18:45" }, { "name": "symfony/translation", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Translation", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af" + "reference": "398e0eedcb89243ad34a10d079a4b6ea4c0b61ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/bd939f05cdaca128f4ddbae1b447d6f0203b60af", - "reference": "bd939f05cdaca128f4ddbae1b447d6f0203b60af", + "url": "https://api.github.com/repos/symfony/Translation/zipball/398e0eedcb89243ad34a10d079a4b6ea4c0b61ff", + "reference": "398e0eedcb89243ad34a10d079a4b6ea4c0b61ff", "shasum": "" }, "require": { @@ -2650,32 +2766,32 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Translation Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-05 16:51:00" }, { "name": "symfony/validator", - "version": "v2.6.6", + "version": "v2.6.7", "target-dir": "Symfony/Component/Validator", "source": { "type": "git", "url": "https://github.com/symfony/Validator.git", - "reference": "85d9b42fe71bf88e7a1e5dec2094605dc9fbff28" + "reference": "6bb1b474d25cb80617d8da6cb14c955ba914e495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/85d9b42fe71bf88e7a1e5dec2094605dc9fbff28", - "reference": "85d9b42fe71bf88e7a1e5dec2094605dc9fbff28", + "url": "https://api.github.com/repos/symfony/Validator/zipball/6bb1b474d25cb80617d8da6cb14c955ba914e495", + "reference": "6bb1b474d25cb80617d8da6cb14c955ba914e495", "shasum": "" }, "require": { @@ -2722,25 +2838,168 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Validator Component", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-05-05 01:29:27" + }, + { + "name": "zendframework/zend-code", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/Component_ZendCode.git", + "reference": "cfd5951ff4348e4430850560416c7ddb755f95d3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/Component_ZendCode/zipball/cfd5951ff4348e4430850560416c7ddb755f95d3", + "reference": "cfd5951ff4348e4430850560416c7ddb755f95d3", + "shasum": "" + }, + "require": { + "php": ">=5.3.23", + "zendframework/zend-eventmanager": "self.version" + }, + "require-dev": { + "doctrine/common": ">=2.1", + "zendframework/zend-stdlib": "self.version" + }, + "suggest": { + "doctrine/common": "Doctrine\\Common >=2.1 for annotation features", + "zendframework/zend-stdlib": "Zend\\Stdlib component" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev", + "dev-develop": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Code\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "provides facilities to generate arbitrary code using an object oriented interface", + "homepage": "https://github.com/zendframework/zf2", + "keywords": [ + "code", + "zf2" + ], + "time": "2015-04-01 17:59:08" + }, + { + "name": "zendframework/zend-eventmanager", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/Component_ZendEventManager.git", + "reference": "38df5b567d4ff4d22144745c503ba0502d0d5695" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/Component_ZendEventManager/zipball/38df5b567d4ff4d22144745c503ba0502d0d5695", + "reference": "38df5b567d4ff4d22144745c503ba0502d0d5695", + "shasum": "" + }, + "require": { + "php": ">=5.3.23", + "zendframework/zend-stdlib": "self.version" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev", + "dev-develop": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\EventManager\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zf2", + "keywords": [ + "eventmanager", + "zf2" + ], + "time": "2015-04-01 18:05:26" + }, + { + "name": "zendframework/zend-stdlib", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/zendframework/Component_ZendStdlib.git", + "reference": "eab586f4c18af3fa63c977611939f1f4a3cf1030" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zendframework/Component_ZendStdlib/zipball/eab586f4c18af3fa63c977611939f1f4a3cf1030", + "reference": "eab586f4c18af3fa63c977611939f1f4a3cf1030", + "shasum": "" + }, + "require": { + "php": ">=5.3.23" + }, + "require-dev": { + "zendframework/zend-eventmanager": "self.version", + "zendframework/zend-filter": "self.version", + "zendframework/zend-serializer": "self.version", + "zendframework/zend-servicemanager": "self.version" + }, + "suggest": { + "zendframework/zend-eventmanager": "To support aggregate hydrator usage", + "zendframework/zend-filter": "To support naming strategy hydrator usage", + "zendframework/zend-serializer": "Zend\\Serializer component", + "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.3-dev", + "dev-develop": "2.4-dev" + } + }, + "autoload": { + "psr-4": { + "Zend\\Stdlib\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "homepage": "https://github.com/zendframework/zf2", + "keywords": [ + "stdlib", + "zf2" + ], + "time": "2015-04-01 18:09:29" } ], "aliases": [], "minimum-stability": "stable", "stability-flags": { - "symfony/serializer": 20, - "dunglas/json-ld-api-bundle": 20 + "symfony/serializer": 10, + "dunglas/api-bundle": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/doc/getting-started.md b/doc/getting-started.md index 3a45a83f..14c168bc 100644 --- a/doc/getting-started.md +++ b/doc/getting-started.md @@ -717,9 +717,9 @@ class OfferItemCondition extends Enum ``` -### Enabling DunglasJsonLdApi support +### Enabling DunglasApi support -PHP Schema supports [IRI annotations provided by DunglasJsonLdApiBundle](https://github.com/dunglas/DunglasJsonLdApiBundle#using-external-json-ld-vocabularies). +PHP Schema supports [IRI annotations provided by DunglasApiBundle](https://github.com/dunglas/DunglasApiBundle#using-external-json-ld-vocabularies). This is useful if you plan to use your generated data model to power a REST API. To enable this generator along with others, add the following lines to your PHP Schema configuration file: @@ -729,7 +729,7 @@ annotationGenerators: - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator - SchemaOrgModel\AnnotationGenerator\ConstraintAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\DunglasJsonLdApiAnnotationGenerator + - SchemaOrgModel\AnnotationGenerator\DunglasApiAnnotationGenerator ``` ### Going further diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index fcc8a892..7814e0b8 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -720,9 +720,9 @@ private function fixCs(array $files) ->setAllFixers($fixer->getFixers()) ->setConfig($config) ->setOptions(array( - 'level' => 'symfony', - 'fixers' => null, - 'progress' => false, + 'level' => 'symfony', + 'fixers' => null, + 'progress' => false, )) ->resolve() ; diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index 327b327d..c866ece4 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -6,7 +6,7 @@ annotationGenerators: - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator - SchemaOrgModel\AnnotationGenerator\ConstraintAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\DunglasJsonLdApiAnnotationGenerator + - SchemaOrgModel\AnnotationGenerator\DunglasApiAnnotationGenerator # The list of types and properties we want to use types: # Parent class of Person From 1e321df41215b704999a81295a4e75c4e0b69f3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 12 Jun 2015 12:18:32 +0200 Subject: [PATCH 003/258] API Platform branding --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index dae3e3d3..6b13e72a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # PHP Schema.org Model Scaffolding -The [PHP Schema](http://php-schema.dunglas.com/) command line tool instantly generates a PHP data model from the [Schema.org](http://schema.org) +The [PHP Schema](http://php-schema.dunglas.com/) command line tool part of [the API Platform framework](http://api-platform.com) that instantly generates a PHP data model from the [Schema.org](http://schema.org) vocabulary. Browse Schema.org, choose the types and properties you need, run our code generator and you're done! You get a fully featured PHP data model including: * A set of PHP entities with properties, constants (enum values), getters, setters, adders and removers. The class From 2253d10008220f99f684dbd44c01def9edcbd23f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 8 Jul 2015 16:18:55 +0200 Subject: [PATCH 004/258] Update dependencies --- composer.lock | 657 +++++++++++++++++++++++++++----------------------- 1 file changed, 355 insertions(+), 302 deletions(-) diff --git a/composer.lock b/composer.lock index 0a068498..e8ba14e3 100644 --- a/composer.lock +++ b/composer.lock @@ -70,16 +70,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.8", + "version": "v1.9", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "93c723fe0c50ed54292006e7249a4c1173cf5847" + "reference": "ef528b9d3f1dd66197baabf8f77c8402c62bb9fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/93c723fe0c50ed54292006e7249a4c1173cf5847", - "reference": "93c723fe0c50ed54292006e7249a4c1173cf5847", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/ef528b9d3f1dd66197baabf8f77c8402c62bb9fc", + "reference": "ef528b9d3f1dd66197baabf8f77c8402c62bb9fc", "shasum": "" }, "require": { @@ -120,20 +120,20 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-05-04 17:06:20" + "time": "2015-06-13 09:30:19" }, { "name": "nickcernis/html-to-markdown", - "version": "2.2.1", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/nickcernis/html-to-markdown.git", - "reference": "7263d2ce65011b050fa7ecda0cbe09b23e84271d" + "reference": "08491df8e9475b219659400edf68416d8044a9db" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nickcernis/html-to-markdown/zipball/7263d2ce65011b050fa7ecda0cbe09b23e84271d", - "reference": "7263d2ce65011b050fa7ecda0cbe09b23e84271d", + "url": "https://api.github.com/repos/nickcernis/html-to-markdown/zipball/08491df8e9475b219659400edf68416d8044a9db", + "reference": "08491df8e9475b219659400edf68416d8044a9db", "shasum": "" }, "require": { @@ -166,7 +166,7 @@ "html", "markdown" ], - "time": "2015-02-22 12:59:02" + "time": "2015-05-29 13:27:02" }, { "name": "psr/log", @@ -260,21 +260,20 @@ }, { "name": "symfony/config", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Config", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25" + "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25", - "reference": "b6fddb4aa2daaa2b06f0040071ac131b4a1ecf25", + "url": "https://api.github.com/repos/symfony/Config/zipball/58ded81f1f582a87c528ef3dae9a859f78b5f374", + "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=5.3.9", "symfony/filesystem": "~2.3" }, "require-dev": { @@ -283,11 +282,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Config\\": "" } }, @@ -307,25 +306,24 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-11 14:06:56" }, { "name": "symfony/console", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Console", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272" + "reference": "564398bc1f33faf92fc2ec86859983d30eb81806" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/ebc5679854aa24ed7d65062e9e3ab0b18a917272", - "reference": "ebc5679854aa24ed7d65062e9e3ab0b18a917272", + "url": "https://api.github.com/repos/symfony/Console/zipball/564398bc1f33faf92fc2ec86859983d30eb81806", + "reference": "564398bc1f33faf92fc2ec86859983d30eb81806", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "psr/log": "~1.0", @@ -341,11 +339,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Console\\": "" } }, @@ -365,25 +363,24 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-10 15:30:22" }, { "name": "symfony/event-dispatcher", - "version": "v2.6.7", - "target-dir": "Symfony/Component/EventDispatcher", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02" + "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/672593bc4b0043a0acf91903bb75a1c82d8f2e02", - "reference": "672593bc4b0043a0acf91903bb75a1c82d8f2e02", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/be3c5ff8d503c46768aeb78ce6333051aa6f26d9", + "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "psr/log": "~1.0", @@ -400,11 +397,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" } }, @@ -424,25 +421,24 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-08 09:37:21" }, { "name": "symfony/filesystem", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Filesystem", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "f73904bd2dae525c42ea1f0340c7c98480ecacde" + "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/f73904bd2dae525c42ea1f0340c7c98480ecacde", - "reference": "f73904bd2dae525c42ea1f0340c7c98480ecacde", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a0d43eb3e17d4f4c6990289805a488a0482a07f3", + "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "symfony/phpunit-bridge": "~2.7" @@ -450,11 +446,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Filesystem\\": "" } }, @@ -474,25 +470,24 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com/", - "time": "2015-05-08 00:09:07" + "time": "2015-06-08 09:37:21" }, { "name": "symfony/finder", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Finder", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "704c64c8b12c8882640d5c0330a8414b1e06dc99" + "reference": "c13a40d638aeede1e8400f8c956c7f9246c05f75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/704c64c8b12c8882640d5c0330a8414b1e06dc99", - "reference": "704c64c8b12c8882640d5c0330a8414b1e06dc99", + "url": "https://api.github.com/repos/symfony/Finder/zipball/c13a40d638aeede1e8400f8c956c7f9246c05f75", + "reference": "c13a40d638aeede1e8400f8c956c7f9246c05f75", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "symfony/phpunit-bridge": "~2.7" @@ -500,11 +495,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Finder\\": "" } }, @@ -524,25 +519,24 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-04 20:11:48" }, { "name": "symfony/process", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Process", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "9f3c4baaf840ed849e1b1f7bfd5ae246e8509562" + "reference": "552d8efdc80980cbcca50b28d626ac8e36e3cdd1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/9f3c4baaf840ed849e1b1f7bfd5ae246e8509562", - "reference": "9f3c4baaf840ed849e1b1f7bfd5ae246e8509562", + "url": "https://api.github.com/repos/symfony/Process/zipball/552d8efdc80980cbcca50b28d626ac8e36e3cdd1", + "reference": "552d8efdc80980cbcca50b28d626ac8e36e3cdd1", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "symfony/phpunit-bridge": "~2.7" @@ -550,11 +544,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Process\\": "" } }, @@ -574,25 +568,24 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-08 09:37:21" }, { "name": "symfony/stopwatch", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Stopwatch", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Stopwatch.git", - "reference": "b470f87c69837cb71115f1fa720388bb19b63635" + "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/b470f87c69837cb71115f1fa720388bb19b63635", - "reference": "b470f87c69837cb71115f1fa720388bb19b63635", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", + "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "symfony/phpunit-bridge": "~2.7" @@ -600,11 +593,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Stopwatch\\": "" } }, @@ -624,25 +617,24 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-04 20:11:48" }, { "name": "symfony/yaml", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Yaml", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2" + "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/f157ab074e453ecd4c0fa775f721f6e67a99d9e2", - "reference": "f157ab074e453ecd4c0fa775f721f6e67a99d9e2", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/9808e75c609a14f6db02f70fccf4ca4aab53c160", + "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "symfony/phpunit-bridge": "~2.7" @@ -650,11 +642,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Yaml\\": "" } }, @@ -674,20 +666,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-10 15:30:22" }, { "name": "twig/twig", - "version": "v1.18.1", + "version": "v1.18.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f" + "reference": "e8e6575abf6102af53ec283f7f14b89e304fa602" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/9f70492f44398e276d1b81c1b43adfe6751c7b7f", - "reference": "9f70492f44398e276d1b81c1b43adfe6751c7b7f", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/e8e6575abf6102af53ec283f7f14b89e304fa602", + "reference": "e8e6575abf6102af53ec283f7f14b89e304fa602", "shasum": "" }, "require": { @@ -731,22 +723,22 @@ "keywords": [ "templating" ], - "time": "2015-04-19 08:30:27" + "time": "2015-06-06 23:31:24" } ], "packages-dev": [ { "name": "doctrine/annotations", - "version": "v1.2.4", + "version": "v1.2.6", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e" + "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/b5202eb9e83f8db52e0e58867e0a46e63be8332e", - "reference": "b5202eb9e83f8db52e0e58867e0a46e63be8332e", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f4a91702ca3cd2e568c3736aa031ed00c3752af4", + "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4", "shasum": "" }, "require": { @@ -801,7 +793,7 @@ "docblock", "parser" ], - "time": "2014-12-23 22:40:37" + "time": "2015-06-17 12:21:22" }, { "name": "doctrine/cache", @@ -1085,16 +1077,16 @@ }, { "name": "doctrine/doctrine-bundle", - "version": "v1.4.0", + "version": "v1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "1986ff3a945b584c6505d07eae92d77e41131078" + "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/1986ff3a945b584c6505d07eae92d77e41131078", - "reference": "1986ff3a945b584c6505d07eae92d77e41131078", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0b9e27037c4fdbad515ee5ec89842e9091a6480f", + "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f", "shasum": "" }, "require": { @@ -1102,6 +1094,7 @@ "doctrine/doctrine-cache-bundle": "~1.0", "jdorn/sql-formatter": "~1.1", "php": ">=5.3.2", + "symfony/console": "~2.3", "symfony/doctrine-bridge": "~2.2", "symfony/framework-bundle": "~2.3" }, @@ -1120,7 +1113,7 @@ "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "1.4.x-dev" + "dev-master": "1.5.x-dev" } }, "autoload": { @@ -1158,7 +1151,7 @@ "orm", "persistence" ], - "time": "2015-02-28 11:04:45" + "time": "2015-05-28 12:27:15" }, { "name": "doctrine/doctrine-cache-bundle", @@ -1313,16 +1306,16 @@ }, { "name": "doctrine/instantiator", - "version": "1.0.4", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119" + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f976e5de371104877ebc89bd8fecb0019ed9c119", - "reference": "f976e5de371104877ebc89bd8fecb0019ed9c119", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", + "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", "shasum": "" }, "require": { @@ -1333,7 +1326,7 @@ "ext-pdo": "*", "ext-phar": "*", "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "2.0.*@ALPHA" + "squizlabs/php_codesniffer": "~2.0" }, "type": "library", "extra": { @@ -1342,8 +1335,8 @@ } }, "autoload": { - "psr-0": { - "Doctrine\\Instantiator\\": "src" + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1363,7 +1356,7 @@ "constructor", "instantiate" ], - "time": "2014-10-13 12:58:55" + "time": "2015-06-14 21:17:01" }, { "name": "doctrine/lexer", @@ -1502,12 +1495,12 @@ "source": { "type": "git", "url": "https://github.com/dunglas/DunglasApiBundle.git", - "reference": "7658b196dc4fe906012a6f4ca70352769ef00d81" + "reference": "b1f39f756f220148b58b9b39a892f0c8abe569b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/7658b196dc4fe906012a6f4ca70352769ef00d81", - "reference": "7658b196dc4fe906012a6f4ca70352769ef00d81", + "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/b1f39f756f220148b58b9b39a892f0c8abe569b2", + "reference": "b1f39f756f220148b58b9b39a892f0c8abe569b2", "shasum": "" }, "require": { @@ -1520,7 +1513,7 @@ "phpdocumentor/reflection": "^1.0.7", "symfony/framework-bundle": "~2.6|~3.0", "symfony/proxy-manager-bridge": "~2.3", - "symfony/serializer": "~3.0|~2.7@beta", + "symfony/serializer": "~2.7|~3.0", "symfony/validator": "~2.5|~3.0" }, "require-dev": { @@ -1529,10 +1522,10 @@ "behat/mink-browserkit-driver": "~1.1", "behat/mink-extension": "~2.0", "behat/symfony2-extension": "~2.0", - "behatch/contexts": "~2.1", - "friendsofsymfony/user-bundle": "dev-master", - "phpspec/phpspec": "~2.0", - "symfony/symfony": "~2.7@beta" + "behatch/contexts": "dev-master#eef7ab39ca896796bf3ba25a0fa5a95f15276eb7", + "friendsofsymfony/user-bundle": "~1.3", + "phpunit/phpunit": "~4.6", + "symfony/finder": "~2.3" }, "suggest": { "friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge." @@ -1568,7 +1561,7 @@ "json", "rest" ], - "time": "2015-05-14 21:45:06" + "time": "2015-07-08 09:05:56" }, { "name": "dunglas/php-property-info", @@ -1886,23 +1879,75 @@ ], "time": "2015-02-03 12:10:50" }, + { + "name": "symfony/asset", + "version": "v2.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/asset.git", + "reference": "11f8e32ff4a854297f8a5ea3497e78f9d57d3b22" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/asset/zipball/11f8e32ff4a854297f8a5ea3497e78f9d57d3b22", + "reference": "11f8e32ff4a854297f8a5ea3497e78f9d57d3b22", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "symfony/http-foundation": "~2.4", + "symfony/phpunit-bridge": "~2.7" + }, + "suggest": { + "symfony/http-foundation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.7-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Component\\Asset\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Asset Component", + "homepage": "https://symfony.com/", + "time": "2015-05-01 14:16:41" + }, { "name": "symfony/debug", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Debug", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Debug.git", - "reference": "ad4511a8fddce7ec163b513ba39a30ea4f32c9e7" + "reference": "075070230c5bbc65abde8241191655bbce0716e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/ad4511a8fddce7ec163b513ba39a30ea4f32c9e7", - "reference": "ad4511a8fddce7ec163b513ba39a30ea4f32c9e7", + "url": "https://api.github.com/repos/symfony/Debug/zipball/075070230c5bbc65abde8241191655bbce0716e2", + "reference": "075070230c5bbc65abde8241191655bbce0716e2", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=5.3.9", "psr/log": "~1.0" }, "conflict": { @@ -1921,11 +1966,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Debug\\": "" } }, @@ -1945,25 +1990,24 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com/", - "time": "2015-05-08 13:17:44" + "time": "2015-06-08 09:37:21" }, { "name": "symfony/dependency-injection", - "version": "v2.6.7", - "target-dir": "Symfony/Component/DependencyInjection", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "b575c160af001d3525ee733085bcc4ec7c8e1b51" + "reference": "1a409e52a38ec891de0a7a61a191d1c62080b69d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/b575c160af001d3525ee733085bcc4ec7c8e1b51", - "reference": "b575c160af001d3525ee733085bcc4ec7c8e1b51", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/1a409e52a38ec891de0a7a61a191d1c62080b69d", + "reference": "1a409e52a38ec891de0a7a61a191d1c62080b69d", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "conflict": { "symfony/expression-language": "<2.6" @@ -1982,11 +2026,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\DependencyInjection\\": "" } }, @@ -2006,26 +2050,25 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-11 19:13:11" }, { "name": "symfony/doctrine-bridge", - "version": "v2.6.7", - "target-dir": "Symfony/Bridge/Doctrine", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/DoctrineBridge.git", - "reference": "7ed45d2895343311ee1ed63ef9c57cec346181c0" + "reference": "50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/7ed45d2895343311ee1ed63ef9c57cec346181c0", - "reference": "7ed45d2895343311ee1ed63ef9c57cec346181c0", + "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a", + "reference": "50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a", "shasum": "" }, "require": { "doctrine/common": "~2.3", - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "doctrine/data-fixtures": "1.0.*", @@ -2033,7 +2076,7 @@ "doctrine/orm": "~2.2,>=2.2.3", "symfony/dependency-injection": "~2.2", "symfony/expression-language": "~2.2", - "symfony/form": "~2.3,>=2.3.8", + "symfony/form": "~2.7,>=2.7.1", "symfony/http-kernel": "~2.2", "symfony/phpunit-bridge": "~2.7", "symfony/property-access": "~2.3", @@ -2052,11 +2095,11 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Bridge\\Doctrine\\": "" } }, @@ -2076,48 +2119,48 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-10 18:57:31" }, { "name": "symfony/framework-bundle", - "version": "v2.6.7", - "target-dir": "Symfony/Bundle/FrameworkBundle", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/FrameworkBundle.git", - "reference": "25217a4c326b4837c259629ef3f3087863b42b2c" + "reference": "dee055c00ac76bb079439aac4ec04897f00e1d43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/25217a4c326b4837c259629ef3f3087863b42b2c", - "reference": "25217a4c326b4837c259629ef3f3087863b42b2c", + "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/dee055c00ac76bb079439aac4ec04897f00e1d43", + "reference": "dee055c00ac76bb079439aac4ec04897f00e1d43", "shasum": "" }, "require": { "doctrine/annotations": "~1.0", - "php": ">=5.3.3", + "php": ">=5.3.9", + "symfony/asset": "~2.7", "symfony/config": "~2.4", "symfony/dependency-injection": "~2.6,>=2.6.2", "symfony/event-dispatcher": "~2.5", "symfony/filesystem": "~2.3", "symfony/http-foundation": "~2.4.9|~2.5,>=2.5.4", - "symfony/http-kernel": "~2.6", - "symfony/routing": "~2.3.26|~2.6,>=2.6.5", + "symfony/http-kernel": "~2.7", + "symfony/routing": "~2.6,>2.6.4", "symfony/security-core": "~2.6", "symfony/security-csrf": "~2.6", "symfony/stopwatch": "~2.3", "symfony/templating": "~2.1", - "symfony/translation": "~2.6" + "symfony/translation": "~2.7" }, "require-dev": { "symfony/browser-kit": "~2.4", "symfony/class-loader": "~2.1", - "symfony/console": "~2.5,>=2.5.2", + "symfony/console": "~2.7", "symfony/css-selector": "~2.0,>=2.0.5", "symfony/dom-crawler": "~2.0,>=2.0.5", "symfony/expression-language": "~2.6", "symfony/finder": "~2.0,>=2.0.5", - "symfony/form": "~2.6", + "symfony/form": "~2.7", "symfony/intl": "~2.3", "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.0,>=2.0.5", @@ -2131,16 +2174,16 @@ "symfony/finder": "For using the translation loader and cache warmer", "symfony/form": "For using forms", "symfony/validator": "For using validation", - "symfony/yaml": "For using the debug:config and yaml:lint commands" + "symfony/yaml": "For using the debug:config and lint:yaml commands" }, "type": "symfony-bundle", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Bundle\\FrameworkBundle\\": "" } }, @@ -2160,25 +2203,24 @@ ], "description": "Symfony FrameworkBundle", "homepage": "https://symfony.com/", - "time": "2015-05-04 14:53:25" + "time": "2015-06-11 17:26:34" }, { "name": "symfony/http-foundation", - "version": "v2.6.7", - "target-dir": "Symfony/Component/HttpFoundation", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "8a0d00980ef9f6b47ddbf24bdfbf70fead760816" + "reference": "4f363c426b0ced57e3d14460022feb63937980ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/8a0d00980ef9f6b47ddbf24bdfbf70fead760816", - "reference": "8a0d00980ef9f6b47ddbf24bdfbf70fead760816", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/4f363c426b0ced57e3d14460022feb63937980ff", + "reference": "4f363c426b0ced57e3d14460022feb63937980ff", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "symfony/expression-language": "~2.4", @@ -2187,15 +2229,15 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\HttpFoundation\\": "" }, "classmap": [ - "Symfony/Component/HttpFoundation/Resources/stubs" + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2214,34 +2256,36 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-10 15:30:22" }, { "name": "symfony/http-kernel", - "version": "v2.6.7", - "target-dir": "Symfony/Component/HttpKernel", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "2010194de0a57731af9404c7f97fd300db98b7a3" + "reference": "208101c7a11e31933183bd2a380486e528c74302" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/2010194de0a57731af9404c7f97fd300db98b7a3", - "reference": "2010194de0a57731af9404c7f97fd300db98b7a3", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/208101c7a11e31933183bd2a380486e528c74302", + "reference": "208101c7a11e31933183bd2a380486e528c74302", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=5.3.9", "psr/log": "~1.0", "symfony/debug": "~2.6,>=2.6.2", "symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2", "symfony/http-foundation": "~2.5,>=2.5.4" }, + "conflict": { + "symfony/config": "<2.7" + }, "require-dev": { "symfony/browser-kit": "~2.3", "symfony/class-loader": "~2.1", - "symfony/config": "~2.0,>=2.0.5", + "symfony/config": "~2.7", "symfony/console": "~2.3", "symfony/css-selector": "~2.0,>=2.0.5", "symfony/dependency-injection": "~2.2", @@ -2268,11 +2312,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\HttpKernel\\": "" } }, @@ -2292,26 +2336,25 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com/", - "time": "2015-05-11 01:58:49" + "time": "2015-06-11 21:15:28" }, { "name": "symfony/proxy-manager-bridge", - "version": "v2.6.7", - "target-dir": "Symfony/Bridge/ProxyManager", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/ProxyManagerBridge.git", - "reference": "9744a8ee680be6d50794f48cb376680a37a6bfb8" + "reference": "d82b82d47e8d93db9dac4ed186d7f521265ed93e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/ProxyManagerBridge/zipball/9744a8ee680be6d50794f48cb376680a37a6bfb8", - "reference": "9744a8ee680be6d50794f48cb376680a37a6bfb8", + "url": "https://api.github.com/repos/symfony/ProxyManagerBridge/zipball/d82b82d47e8d93db9dac4ed186d7f521265ed93e", + "reference": "d82b82d47e8d93db9dac4ed186d7f521265ed93e", "shasum": "" }, "require": { "ocramius/proxy-manager": "~0.4|~1.0", - "php": ">=5.3.3", + "php": ">=5.3.9", "symfony/dependency-injection": "~2.3" }, "require-dev": { @@ -2321,11 +2364,11 @@ "type": "symfony-bridge", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Bridge\\ProxyManager\\": "" } }, @@ -2345,31 +2388,33 @@ ], "description": "Symfony ProxyManager Bridge", "homepage": "https://symfony.com/", - "time": "2015-05-06 14:13:47" + "time": "2015-05-11 02:35:29" }, { "name": "symfony/routing", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Routing", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "1455ec537940f7428ea6aa9411f3c4bca69413a0" + "reference": "5581be29185b8fb802398904555f70da62f6d50d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/1455ec537940f7428ea6aa9411f3c4bca69413a0", - "reference": "1455ec537940f7428ea6aa9411f3c4bca69413a0", + "url": "https://api.github.com/repos/symfony/Routing/zipball/5581be29185b8fb802398904555f70da62f6d50d", + "reference": "5581be29185b8fb802398904555f70da62f6d50d", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/common": "~2.2", "psr/log": "~1.0", - "symfony/config": "~2.2", + "symfony/config": "~2.7", "symfony/expression-language": "~2.4", "symfony/http-foundation": "~2.3", "symfony/phpunit-bridge": "~2.7", @@ -2384,11 +2429,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Routing\\": "" } }, @@ -2414,21 +2459,21 @@ "uri", "url" ], - "time": "2015-05-02 15:18:45" + "time": "2015-06-11 17:20:40" }, { "name": "symfony/security", - "version": "v2.3.28", + "version": "v2.3.30", "target-dir": "Symfony/Component/Security", "source": { "type": "git", "url": "https://github.com/symfony/Security.git", - "reference": "4bc570e4ecad43b827f5c8852a4a4616ede89e4e" + "reference": "b3d032613d74a7d5d7babeee28d9ac8f870ff36c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Security/zipball/4bc570e4ecad43b827f5c8852a4a4616ede89e4e", - "reference": "4bc570e4ecad43b827f5c8852a4a4616ede89e4e", + "url": "https://api.github.com/repos/symfony/Security/zipball/b3d032613d74a7d5d7babeee28d9ac8f870ff36c", + "reference": "b3d032613d74a7d5d7babeee28d9ac8f870ff36c", "shasum": "" }, "require": { @@ -2484,25 +2529,24 @@ ], "description": "Symfony Security Component", "homepage": "https://symfony.com/", - "time": "2015-05-07 14:20:47" + "time": "2015-05-21 04:29:49" }, { "name": "symfony/security-core", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Security/Core", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "d25c17db741f58c0f615e52006a47f6fb23cd9b3" + "reference": "08cd68cea42ad73476d3900e675662db363c8fba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/d25c17db741f58c0f615e52006a47f6fb23cd9b3", - "reference": "d25c17db741f58c0f615e52006a47f6fb23cd9b3", + "url": "https://api.github.com/repos/symfony/security-core/zipball/08cd68cea42ad73476d3900e675662db363c8fba", + "reference": "08cd68cea42ad73476d3900e675662db363c8fba", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "ircmaxell/password-compat": "1.0.*", @@ -2524,11 +2568,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Security\\Core\\": "" } }, @@ -2537,36 +2581,35 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Security Component - Core Library", - "homepage": "http://symfony.com/", - "time": "2015-03-30 15:54:10" + "homepage": "https://symfony.com/", + "time": "2015-06-08 09:37:21" }, { "name": "symfony/security-csrf", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Security/Csrf", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "7cc85bffcb0f3a68cd8be8d2c91da0cc962f152a" + "reference": "e438b3e7de930e2147e397830126d2f0d32a0088" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/7cc85bffcb0f3a68cd8be8d2c91da0cc962f152a", - "reference": "7cc85bffcb0f3a68cd8be8d2c91da0cc962f152a", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/e438b3e7de930e2147e397830126d2f0d32a0088", + "reference": "e438b3e7de930e2147e397830126d2f0d32a0088", "shasum": "" }, "require": { - "php": ">=5.3.3", + "php": ">=5.3.9", "symfony/security-core": "~2.4" }, "require-dev": { @@ -2579,11 +2622,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Security\\Csrf\\": "" } }, @@ -2592,31 +2635,31 @@ "MIT" ], "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, { "name": "Fabien Potencier", "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Security Component - CSRF Library", - "homepage": "http://symfony.com/", - "time": "2015-02-24 11:52:21" + "homepage": "https://symfony.com/", + "time": "2015-05-13 11:34:46" }, { "name": "symfony/serializer", - "version": "v2.7.0-BETA2", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Serializer.git", - "reference": "122c2b000130e3ae0fe5029bcc111bb6b3ffaad6" + "reference": "edf2820c4948389e3f168a0160151806cefd6ac3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Serializer/zipball/122c2b000130e3ae0fe5029bcc111bb6b3ffaad6", - "reference": "122c2b000130e3ae0fe5029bcc111bb6b3ffaad6", + "url": "https://api.github.com/repos/symfony/Serializer/zipball/edf2820c4948389e3f168a0160151806cefd6ac3", + "reference": "edf2820c4948389e3f168a0160151806cefd6ac3", "shasum": "" }, "require": { @@ -2664,25 +2707,24 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com/", - "time": "2015-05-04 07:31:19" + "time": "2015-06-08 09:37:21" }, { "name": "symfony/templating", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Templating", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Templating.git", - "reference": "e5c1620f7480883e1de7ad104af100d25c49cd59" + "reference": "3a2ed707230bae834ee24248a1a2a76f14eb3649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Templating/zipball/e5c1620f7480883e1de7ad104af100d25c49cd59", - "reference": "e5c1620f7480883e1de7ad104af100d25c49cd59", + "url": "https://api.github.com/repos/symfony/Templating/zipball/3a2ed707230bae834ee24248a1a2a76f14eb3649", + "reference": "3a2ed707230bae834ee24248a1a2a76f14eb3649", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" }, "require-dev": { "psr/log": "~1.0", @@ -2694,11 +2736,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Templating\\": "" } }, @@ -2718,29 +2760,31 @@ ], "description": "Symfony Templating Component", "homepage": "https://symfony.com/", - "time": "2015-05-02 15:18:45" + "time": "2015-06-08 09:37:21" }, { "name": "symfony/translation", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Translation", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "398e0eedcb89243ad34a10d079a4b6ea4c0b61ff" + "reference": "8349a2b0d11bd0311df9e8914408080912983a0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/398e0eedcb89243ad34a10d079a4b6ea4c0b61ff", - "reference": "398e0eedcb89243ad34a10d079a4b6ea4c0b61ff", + "url": "https://api.github.com/repos/symfony/Translation/zipball/8349a2b0d11bd0311df9e8914408080912983a0b", + "reference": "8349a2b0d11bd0311df9e8914408080912983a0b", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.3,>=2.3.12", + "symfony/config": "~2.7", "symfony/intl": "~2.3", "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.2" @@ -2753,11 +2797,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Translation\\": "" } }, @@ -2777,31 +2821,29 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com/", - "time": "2015-05-05 16:51:00" + "time": "2015-06-11 17:26:34" }, { "name": "symfony/validator", - "version": "v2.6.7", - "target-dir": "Symfony/Component/Validator", + "version": "v2.7.1", "source": { "type": "git", "url": "https://github.com/symfony/Validator.git", - "reference": "6bb1b474d25cb80617d8da6cb14c955ba914e495" + "reference": "3c58b1ef26ab2114f8f84d1808937b9b76bad8f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/6bb1b474d25cb80617d8da6cb14c955ba914e495", - "reference": "6bb1b474d25cb80617d8da6cb14c955ba914e495", + "url": "https://api.github.com/repos/symfony/Validator/zipball/3c58b1ef26ab2114f8f84d1808937b9b76bad8f5", + "reference": "3c58b1ef26ab2114f8f84d1808937b9b76bad8f5", "shasum": "" }, "require": { - "php": ">=5.3.3", - "symfony/translation": "~2.0,>=2.0.5" + "php": ">=5.3.9", + "symfony/translation": "~2.4" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "doctrine/common": "~2.3", "egulias/email-validator": "~1.2,>=1.2.1", "symfony/config": "~2.2", "symfony/expression-language": "~2.4", @@ -2825,11 +2867,11 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "psr-0": { + "psr-4": { "Symfony\\Component\\Validator\\": "" } }, @@ -2849,29 +2891,32 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", - "time": "2015-05-05 01:29:27" + "time": "2015-06-08 09:37:21" }, { "name": "zendframework/zend-code", - "version": "2.4.0", + "version": "2.5.1", "source": { "type": "git", - "url": "https://github.com/zendframework/Component_ZendCode.git", - "reference": "cfd5951ff4348e4430850560416c7ddb755f95d3" + "url": "https://github.com/zendframework/zend-code.git", + "reference": "5d998f261ec2a55171c71da57a11622745680153" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendCode/zipball/cfd5951ff4348e4430850560416c7ddb755f95d3", - "reference": "cfd5951ff4348e4430850560416c7ddb755f95d3", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/5d998f261ec2a55171c71da57a11622745680153", + "reference": "5d998f261ec2a55171c71da57a11622745680153", "shasum": "" }, "require": { "php": ">=5.3.23", - "zendframework/zend-eventmanager": "self.version" + "zendframework/zend-eventmanager": "~2.5" }, "require-dev": { "doctrine/common": ">=2.1", - "zendframework/zend-stdlib": "self.version" + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-stdlib": "~2.5", + "zendframework/zend-version": "~2.5" }, "suggest": { "doctrine/common": "Doctrine\\Common >=2.1 for annotation features", @@ -2880,13 +2925,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev", - "dev-develop": "2.4-dev" + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" } }, "autoload": { "psr-4": { - "Zend\\Code\\": "" + "Zend\\Code\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2894,76 +2939,84 @@ "BSD-3-Clause" ], "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zf2", + "homepage": "https://github.com/zendframework/zend-code", "keywords": [ "code", "zf2" ], - "time": "2015-04-01 17:59:08" + "time": "2015-06-03 15:31:59" }, { "name": "zendframework/zend-eventmanager", - "version": "2.4.0", + "version": "2.5.1", "source": { "type": "git", - "url": "https://github.com/zendframework/Component_ZendEventManager.git", - "reference": "38df5b567d4ff4d22144745c503ba0502d0d5695" + "url": "https://github.com/zendframework/zend-eventmanager.git", + "reference": "d94a16039144936f107f906896349900fd634443" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendEventManager/zipball/38df5b567d4ff4d22144745c503ba0502d0d5695", - "reference": "38df5b567d4ff4d22144745c503ba0502d0d5695", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d94a16039144936f107f906896349900fd634443", + "reference": "d94a16039144936f107f906896349900fd634443", "shasum": "" }, "require": { "php": ">=5.3.23", - "zendframework/zend-stdlib": "self.version" + "zendframework/zend-stdlib": "~2.5" + }, + "require-dev": { + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev", - "dev-develop": "2.4-dev" + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" } }, "autoload": { "psr-4": { - "Zend\\EventManager\\": "" + "Zend\\EventManager\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zf2", + "homepage": "https://github.com/zendframework/zend-eventmanager", "keywords": [ "eventmanager", "zf2" ], - "time": "2015-04-01 18:05:26" + "time": "2015-06-03 15:32:01" }, { "name": "zendframework/zend-stdlib", - "version": "2.4.0", + "version": "2.5.1", "source": { "type": "git", - "url": "https://github.com/zendframework/Component_ZendStdlib.git", - "reference": "eab586f4c18af3fa63c977611939f1f4a3cf1030" + "url": "https://github.com/zendframework/zend-stdlib.git", + "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/Component_ZendStdlib/zipball/eab586f4c18af3fa63c977611939f1f4a3cf1030", - "reference": "eab586f4c18af3fa63c977611939f1f4a3cf1030", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cc8e90a60dd5d44b9730b77d07b97550091da1ae", + "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae", "shasum": "" }, "require": { "php": ">=5.3.23" }, "require-dev": { - "zendframework/zend-eventmanager": "self.version", - "zendframework/zend-filter": "self.version", - "zendframework/zend-serializer": "self.version", - "zendframework/zend-servicemanager": "self.version" + "fabpot/php-cs-fixer": "1.7.*", + "phpunit/phpunit": "~4.0", + "zendframework/zend-config": "~2.5", + "zendframework/zend-eventmanager": "~2.5", + "zendframework/zend-filter": "~2.5", + "zendframework/zend-inputfilter": "~2.5", + "zendframework/zend-serializer": "~2.5", + "zendframework/zend-servicemanager": "~2.5" }, "suggest": { "zendframework/zend-eventmanager": "To support aggregate hydrator usage", @@ -2974,25 +3027,25 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev", - "dev-develop": "2.4-dev" + "dev-master": "2.5-dev", + "dev-develop": "2.6-dev" } }, "autoload": { "psr-4": { - "Zend\\Stdlib\\": "" + "Zend\\Stdlib\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], - "homepage": "https://github.com/zendframework/zf2", + "homepage": "https://github.com/zendframework/zend-stdlib", "keywords": [ "stdlib", "zf2" ], - "time": "2015-04-01 18:09:29" + "time": "2015-06-03 15:32:03" } ], "aliases": [], From a86f1ac1be6e58685dd3f37087910062ed23449a Mon Sep 17 00:00:00 2001 From: Lee Siong Chan Date: Thu, 9 Jul 2015 12:28:01 +0800 Subject: [PATCH 005/258] Read external rdfa data --- doc/configuration.md | 43 ++++++++++++++++++- .../DunglasApiAnnotationGenerator.php | 5 ++- src/SchemaOrgModel/TypesGenerator.php | 5 ++- tests/config/custom.yml | 9 ++++ tests/data/custom.rdfa | 33 ++++++++++++++ tests/run-tests.sh | 3 +- 6 files changed, 93 insertions(+), 5 deletions(-) create mode 100644 tests/config/custom.yml create mode 100644 tests/data/custom.rdfa diff --git a/doc/configuration.md b/doc/configuration.md index 10ba9cac..4ae906e3 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -203,10 +203,49 @@ Example: ```yaml rdfa: - https://raw.githubusercontent.com/rvguha/schemaorg/master/data/schema.rdfa # Experimental version of Schema.org - - http://example.com/data/myschema.rfa # Additional types + - http://example.com/data/myschema.rdfa # Additional types +types: + http://example.com/Language: + properties: + http://example.com/Locale: ~ ``` -*Support for other namespaces than `http://schema.org` is planned for future versions but not currently available.* +myschema.rdfa +```html + + + + Custom RDFa + + + + + + +
+ Language + Natural languages such as Spanish, Tamil, Hindi, English, etc. and programming languages such as Scheme and Lisp. +
+ +
+ Locale + User's language, country and any special variant preferences that the user wants to see in their user interface (in 2-letter <a href='https://en.wikipedia.org/wiki/ISO_639-1'>ISO 639-1</a> format). + Domain: Language + Range: Text +
+ + + +``` ## Checking GoodRelation compatibility diff --git a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php index 69c5b2d5..b52a2a0c 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -35,7 +35,10 @@ public function generateClassAnnotations($className) */ public function generateFieldAnnotations($className, $fieldName) { - return 'id' === $fieldName ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; + $resource = $this->classes[$className]['resource']; + $resourceUrl = parse_url(http://github.com/$resource-%3EgetUri()); + + return 'id' === $fieldName ? [] : [sprintf('@Iri("%s://%s/%s")', $resourceUrl['scheme'], $resourceUrl['host'], $fieldName)]; } /** diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index 7814e0b8..cd5a416a 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -135,6 +135,9 @@ public function generate($config) if (isset($resources[self::SCHEMA_ORG_NAMESPACE.$key])) { $resource = $graph->resource(self::SCHEMA_ORG_NAMESPACE.$key, 'rdfs:Class'); break; + } else if (isset($resources[$key])) { + $resource = $graph->resource($key, 'rdfs:Class'); + break; } } @@ -230,7 +233,7 @@ public function generate($config) $ranges[] = $typeConfig['properties'][$property->localName()]['range']; } else { foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { - if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { + if (!$typesDefined || $this->isDatatype($range->localName()) || (isset($config['types'][$range->localName()]) || isset($config['types'][$range->getUri()]))) { $ranges[] = $range->localName(); } } diff --git a/tests/config/custom.yml b/tests/config/custom.yml new file mode 100644 index 00000000..c8e074c3 --- /dev/null +++ b/tests/config/custom.yml @@ -0,0 +1,9 @@ +rdfa: + - tests/data/schema.rdfa + - tests/data/custom.rdfa +namespaces: + entity: "Custom\Entity" +types: + http://example.com/Language: + properties: + http://example.com/Locale: ~ diff --git a/tests/data/custom.rdfa b/tests/data/custom.rdfa new file mode 100644 index 00000000..631e7305 --- /dev/null +++ b/tests/data/custom.rdfa @@ -0,0 +1,33 @@ + + + + Custom RDFa + + + + + + +
+ Language + Natural languages such as Spanish, Tamil, Hindi, English, etc. and programming languages such as Scheme and Lisp. +
+ +
+ Locale + User's language, country and any special variant preferences that the user wants to see in their user interface (in 2-letter <a href='https://en.wikipedia.org/wiki/ISO_639-1'>ISO 639-1</a> format). + Domain: Language + Range: Text +
+ + + diff --git a/tests/run-tests.sh b/tests/run-tests.sh index c066d09d..7f89263c 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -6,9 +6,10 @@ bin/schema extract-cardinalities # Build models rm -Rf build/ -mkdir -p build/full/ build/ecommerce/ build/address-book/ +mkdir -p build/full/ build/ecommerce/ build/address-book/ build/custom/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml +bin/schema generate-types build/custom/ tests/config/custom.yml bin/schema generate-types build/full/ # Check code CS From 2f2b54abb677c9fde30deaca2ff1ddeca6428733 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 14 Jul 2015 18:14:22 +0200 Subject: [PATCH 006/258] Revert "Read external rdfa data" --- doc/configuration.md | 43 +------------------ .../DunglasApiAnnotationGenerator.php | 5 +-- src/SchemaOrgModel/TypesGenerator.php | 5 +-- tests/config/custom.yml | 9 ---- tests/data/custom.rdfa | 33 -------------- tests/run-tests.sh | 3 +- 6 files changed, 5 insertions(+), 93 deletions(-) delete mode 100644 tests/config/custom.yml delete mode 100644 tests/data/custom.rdfa diff --git a/doc/configuration.md b/doc/configuration.md index 4ae906e3..10ba9cac 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -203,49 +203,10 @@ Example: ```yaml rdfa: - https://raw.githubusercontent.com/rvguha/schemaorg/master/data/schema.rdfa # Experimental version of Schema.org - - http://example.com/data/myschema.rdfa # Additional types -types: - http://example.com/Language: - properties: - http://example.com/Locale: ~ + - http://example.com/data/myschema.rfa # Additional types ``` -myschema.rdfa -```html - - - - Custom RDFa - - - - - - -
- Language - Natural languages such as Spanish, Tamil, Hindi, English, etc. and programming languages such as Scheme and Lisp. -
- -
- Locale - User's language, country and any special variant preferences that the user wants to see in their user interface (in 2-letter <a href='https://en.wikipedia.org/wiki/ISO_639-1'>ISO 639-1</a> format). - Domain: Language - Range: Text -
- - - -``` +*Support for other namespaces than `http://schema.org` is planned for future versions but not currently available.* ## Checking GoodRelation compatibility diff --git a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php index b52a2a0c..69c5b2d5 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -35,10 +35,7 @@ public function generateClassAnnotations($className) */ public function generateFieldAnnotations($className, $fieldName) { - $resource = $this->classes[$className]['resource']; - $resourceUrl = parse_url(http://github.com/$resource-%3EgetUri()); - - return 'id' === $fieldName ? [] : [sprintf('@Iri("%s://%s/%s")', $resourceUrl['scheme'], $resourceUrl['host'], $fieldName)]; + return 'id' === $fieldName ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; } /** diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index cd5a416a..7814e0b8 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -135,9 +135,6 @@ public function generate($config) if (isset($resources[self::SCHEMA_ORG_NAMESPACE.$key])) { $resource = $graph->resource(self::SCHEMA_ORG_NAMESPACE.$key, 'rdfs:Class'); break; - } else if (isset($resources[$key])) { - $resource = $graph->resource($key, 'rdfs:Class'); - break; } } @@ -233,7 +230,7 @@ public function generate($config) $ranges[] = $typeConfig['properties'][$property->localName()]['range']; } else { foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { - if (!$typesDefined || $this->isDatatype($range->localName()) || (isset($config['types'][$range->localName()]) || isset($config['types'][$range->getUri()]))) { + if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { $ranges[] = $range->localName(); } } diff --git a/tests/config/custom.yml b/tests/config/custom.yml deleted file mode 100644 index c8e074c3..00000000 --- a/tests/config/custom.yml +++ /dev/null @@ -1,9 +0,0 @@ -rdfa: - - tests/data/schema.rdfa - - tests/data/custom.rdfa -namespaces: - entity: "Custom\Entity" -types: - http://example.com/Language: - properties: - http://example.com/Locale: ~ diff --git a/tests/data/custom.rdfa b/tests/data/custom.rdfa deleted file mode 100644 index 631e7305..00000000 --- a/tests/data/custom.rdfa +++ /dev/null @@ -1,33 +0,0 @@ - - - - Custom RDFa - - - - - - -
- Language - Natural languages such as Spanish, Tamil, Hindi, English, etc. and programming languages such as Scheme and Lisp. -
- -
- Locale - User's language, country and any special variant preferences that the user wants to see in their user interface (in 2-letter <a href='https://en.wikipedia.org/wiki/ISO_639-1'>ISO 639-1</a> format). - Domain: Language - Range: Text -
- - - diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 7f89263c..c066d09d 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -6,10 +6,9 @@ bin/schema extract-cardinalities # Build models rm -Rf build/ -mkdir -p build/full/ build/ecommerce/ build/address-book/ build/custom/ +mkdir -p build/full/ build/ecommerce/ build/address-book/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml -bin/schema generate-types build/custom/ tests/config/custom.yml bin/schema generate-types build/full/ # Check code CS From ba35ddf88f88f29055f2569be0b7a1daa4751376 Mon Sep 17 00:00:00 2001 From: Gert Date: Thu, 20 Aug 2015 14:18:55 +0200 Subject: [PATCH 007/258] 0...* cardinality is also an array --- src/SchemaOrgModel/TypesGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index 7814e0b8..c8bd463a 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -250,6 +250,7 @@ public function generate($config) } $isArray = in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_0_N, CardinalitiesExtractor::CARDINALITY_1_N, CardinalitiesExtractor::CARDINALITY_N_N, ]); From 67492ed23e9eb90d77f836d592617665dfa23dc2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hubert?= Date: Sun, 23 Aug 2015 16:41:44 +0200 Subject: [PATCH 008/258] handle relation table name customization --- doc/configuration.md | 16 ++++++++++++++++ .../DoctrineOrmAnnotationGenerator.php | 13 +++++++++++-- .../TypesGeneratorConfiguration.php | 1 + tests/config/address-book.yml | 6 ++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/configuration.md b/doc/configuration.md index 10ba9cac..8bd32f48 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -69,6 +69,22 @@ types: cardinality: "(0..1)" ``` +## Forcing a relation table name + +The relation table name between two entities is automatically guessed by Doctrine. The `relationTableName` option allows +to override the default value. + +This is useful when you need two entities to have more than one relation. + +Example: + +```yaml + Organization: + properties: + contactPoint: { range: Person, relationTableName: organization_contactPoint } + member: { range: Person, cardinality: (1..*) } ## Will be default value : organization_person +``` + ## Forcing (or disabling) a class parent Override the guessed class hierarchy of a given type with this option. diff --git a/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index d1961554..fbcf9765 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -50,6 +50,10 @@ public function generateFieldAnnotations($className, $fieldName) $this->classes[$className]; $field = $this->classes[$className]['fields'][$fieldName]; + $field['relationTableName'] = null; + if (!$field['isId'] && isset($this->config['types'][$className]['properties'][$fieldName])) { + $field['relationTableName'] = $this->config['types'][$className]['properties'][$fieldName]['relationTableName']; + } $annotations = []; if ($field['isEnum']) { @@ -140,16 +144,21 @@ public function generateFieldAnnotations($className, $fieldName) case CardinalitiesExtractor::CARDINALITY_0_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - $annotations[] = '@ORM\JoinTable(inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; + $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; + $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; break; case CardinalitiesExtractor::CARDINALITY_1_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - $annotations[] = '@ORM\JoinTable(inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; + $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; + $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; break; case CardinalitiesExtractor::CARDINALITY_N_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); + if ($field['relationTableName']) { + $annotations[] = sprintf('@ORM\JoinTable(name="%s")', $field['relationTableName']); + } break; } } diff --git a/src/SchemaOrgModel/TypesGeneratorConfiguration.php b/src/SchemaOrgModel/TypesGeneratorConfiguration.php index 4b440de3..d2aafa3b 100644 --- a/src/SchemaOrgModel/TypesGeneratorConfiguration.php +++ b/src/SchemaOrgModel/TypesGeneratorConfiguration.php @@ -97,6 +97,7 @@ public function getConfigTreeBuilder() ->addDefaultsIfNotSet() ->children() ->scalarNode('range')->defaultNull()->info('The property range')->example('Offer')->end() + ->scalarNode('relationTableName')->defaultNull()->info('The relation table name')->example('organization_member')->end() ->enumNode('cardinality')->defaultValue(CardinalitiesExtractor::CARDINALITY_UNKNOWN)->values([ CardinalitiesExtractor::CARDINALITY_0_1, CardinalitiesExtractor::CARDINALITY_0_N, diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index c866ece4..405d0ecd 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -25,6 +25,11 @@ types: email: ~ url: ~ jobTitle: ~ + # Default relation table name would be "person_organization" for all following fields, but we customize them + affiliation: ~ + brand: { relationTableName: "person_brand"} + memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} + worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} PostalAddress: # Disable the generation of the class hierarchy for this type parent: false @@ -36,3 +41,4 @@ types: postOfficeBoxNumber: ~ postalCode: ~ streetAddress: ~ + Organization: {} From 317d2364022eb04353ca4296322a364becdf9337 Mon Sep 17 00:00:00 2001 From: aureluster Date: Thu, 13 Aug 2015 20:36:46 +0200 Subject: [PATCH 009/258] Allow using parent properties in child classes Refactor #15 and add tests. --- composer.lock | 460 ++++++++++-------- .../PhpDocAnnotationGenerator.php | 2 +- src/SchemaOrgModel/TypesGenerator.php | 47 +- tests/config/address-book.yml | 13 +- tests/run-tests.sh | 1 - 5 files changed, 306 insertions(+), 217 deletions(-) diff --git a/composer.lock b/composer.lock index e8ba14e3..b5f2ee8c 100644 --- a/composer.lock +++ b/composer.lock @@ -70,16 +70,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.9", + "version": "v1.10", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "ef528b9d3f1dd66197baabf8f77c8402c62bb9fc" + "reference": "8e21b4fb32c4618a425817d9f0daf3d57a9808d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/ef528b9d3f1dd66197baabf8f77c8402c62bb9fc", - "reference": "ef528b9d3f1dd66197baabf8f77c8402c62bb9fc", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/8e21b4fb32c4618a425817d9f0daf3d57a9808d1", + "reference": "8e21b4fb32c4618a425817d9f0daf3d57a9808d1", "shasum": "" }, "require": { @@ -120,7 +120,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-06-13 09:30:19" + "time": "2015-07-27 20:56:10" }, { "name": "nickcernis/html-to-markdown", @@ -260,16 +260,16 @@ }, { "name": "symfony/config", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374" + "reference": "5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/58ded81f1f582a87c528ef3dae9a859f78b5f374", - "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374", + "url": "https://api.github.com/repos/symfony/Config/zipball/5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8", + "reference": "5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8", "shasum": "" }, "require": { @@ -306,20 +306,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 14:06:56" + "time": "2015-08-27 06:45:45" }, { "name": "symfony/console", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "564398bc1f33faf92fc2ec86859983d30eb81806" + "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/564398bc1f33faf92fc2ec86859983d30eb81806", - "reference": "564398bc1f33faf92fc2ec86859983d30eb81806", + "url": "https://api.github.com/repos/symfony/Console/zipball/9ff9032151186bd66ecee727d728f1319f52d1d8", + "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8", "shasum": "" }, "require": { @@ -363,20 +363,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com/", - "time": "2015-06-10 15:30:22" + "time": "2015-09-03 11:40:38" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9" + "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/be3c5ff8d503c46768aeb78ce6333051aa6f26d9", - "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/b58c916f1db03a611b72dd702564f30ad8fe83fa", + "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa", "shasum": "" }, "require": { @@ -421,20 +421,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/filesystem", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3" + "reference": "f079e9933799929584200b9a926f72f29e291654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a0d43eb3e17d4f4c6990289805a488a0482a07f3", - "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/f079e9933799929584200b9a926f72f29e291654", + "reference": "f079e9933799929584200b9a926f72f29e291654", "shasum": "" }, "require": { @@ -470,20 +470,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-27 07:03:44" }, { "name": "symfony/finder", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "c13a40d638aeede1e8400f8c956c7f9246c05f75" + "reference": "fff4b0c362640a0ab7355e2647b3d461608e9065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/c13a40d638aeede1e8400f8c956c7f9246c05f75", - "reference": "c13a40d638aeede1e8400f8c956c7f9246c05f75", + "url": "https://api.github.com/repos/symfony/Finder/zipball/fff4b0c362640a0ab7355e2647b3d461608e9065", + "reference": "fff4b0c362640a0ab7355e2647b3d461608e9065", "shasum": "" }, "require": { @@ -519,20 +519,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com/", - "time": "2015-06-04 20:11:48" + "time": "2015-08-26 17:56:37" }, { "name": "symfony/process", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "552d8efdc80980cbcca50b28d626ac8e36e3cdd1" + "reference": "f7b3f73f70a7f8f49a1c838dc3debbf054732d8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/552d8efdc80980cbcca50b28d626ac8e36e3cdd1", - "reference": "552d8efdc80980cbcca50b28d626ac8e36e3cdd1", + "url": "https://api.github.com/repos/symfony/Process/zipball/f7b3f73f70a7f8f49a1c838dc3debbf054732d8e", + "reference": "f7b3f73f70a7f8f49a1c838dc3debbf054732d8e", "shasum": "" }, "require": { @@ -568,20 +568,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-27 06:45:45" }, { "name": "symfony/stopwatch", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Stopwatch.git", - "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b" + "reference": "abc61bac76fb10ffa2c6373d7932bc35190dbf3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", - "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/abc61bac76fb10ffa2c6373d7932bc35190dbf3b", + "reference": "abc61bac76fb10ffa2c6373d7932bc35190dbf3b", "shasum": "" }, "require": { @@ -617,20 +617,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com/", - "time": "2015-06-04 20:11:48" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/yaml", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160" + "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/9808e75c609a14f6db02f70fccf4ca4aab53c160", - "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/2dc7b06c065df96cc686c66da2705e5e18aef661", + "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661", "shasum": "" }, "require": { @@ -666,29 +666,33 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com/", - "time": "2015-06-10 15:30:22" + "time": "2015-08-24 07:13:45" }, { "name": "twig/twig", - "version": "v1.18.2", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e8e6575abf6102af53ec283f7f14b89e304fa602" + "reference": "b7fc2469fa009897871fb95b68237286fc54a5ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e8e6575abf6102af53ec283f7f14b89e304fa602", - "reference": "e8e6575abf6102af53ec283f7f14b89e304fa602", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/b7fc2469fa009897871fb95b68237286fc54a5ad", + "reference": "b7fc2469fa009897871fb95b68237286fc54a5ad", "shasum": "" }, "require": { "php": ">=5.2.7" }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-master": "1.22-dev" } }, "autoload": { @@ -723,22 +727,22 @@ "keywords": [ "templating" ], - "time": "2015-06-06 23:31:24" + "time": "2015-09-15 06:50:16" } ], "packages-dev": [ { "name": "doctrine/annotations", - "version": "v1.2.6", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4" + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/f4a91702ca3cd2e568c3736aa031ed00c3752af4", - "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", "shasum": "" }, "require": { @@ -793,20 +797,20 @@ "docblock", "parser" ], - "time": "2015-06-17 12:21:22" + "time": "2015-08-31 12:32:49" }, { "name": "doctrine/cache", - "version": "v1.4.1", + "version": "v1.4.2", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03" + "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03", - "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03", + "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca", + "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca", "shasum": "" }, "require": { @@ -863,7 +867,7 @@ "cache", "caching" ], - "time": "2015-04-15 00:11:59" + "time": "2015-08-31 12:36:41" }, { "name": "doctrine/collections", @@ -933,16 +937,16 @@ }, { "name": "doctrine/common", - "version": "v2.5.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3" + "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/cd8daf2501e10c63dced7b8b9b905844316ae9d3", - "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3", + "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9", + "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9", "shasum": "" }, "require": { @@ -1002,20 +1006,20 @@ "persistence", "spl" ], - "time": "2015-04-02 19:55:44" + "time": "2015-08-31 13:00:22" }, { "name": "doctrine/dbal", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "628c2256b646ae2417d44e063bce8aec5199d48d" + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/628c2256b646ae2417d44e063bce8aec5199d48d", - "reference": "628c2256b646ae2417d44e063bce8aec5199d48d", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c", "shasum": "" }, "require": { @@ -1073,20 +1077,20 @@ "persistence", "queryobject" ], - "time": "2015-01-12 21:52:47" + "time": "2015-09-16 16:29:33" }, { "name": "doctrine/doctrine-bundle", - "version": "v1.5.0", + "version": "v1.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f" + "reference": "8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0b9e27037c4fdbad515ee5ec89842e9091a6480f", - "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01", + "reference": "8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01", "shasum": "" }, "require": { @@ -1094,16 +1098,16 @@ "doctrine/doctrine-cache-bundle": "~1.0", "jdorn/sql-formatter": "~1.1", "php": ">=5.3.2", - "symfony/console": "~2.3", - "symfony/doctrine-bridge": "~2.2", - "symfony/framework-bundle": "~2.3" + "symfony/console": "~2.3|~3.0", + "symfony/doctrine-bridge": "~2.2|~3.0", + "symfony/framework-bundle": "~2.3|~3.0" }, "require-dev": { "doctrine/orm": "~2.3", "phpunit/phpunit": "~4", "satooshi/php-coveralls": "~0.6.1", - "symfony/validator": "~2.2", - "symfony/yaml": "~2.2", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0", "twig/twig": "~1.10" }, "suggest": { @@ -1151,7 +1155,7 @@ "orm", "persistence" ], - "time": "2015-05-28 12:27:15" + "time": "2015-08-12 15:52:00" }, { "name": "doctrine/doctrine-cache-bundle", @@ -1414,16 +1418,16 @@ }, { "name": "doctrine/orm", - "version": "v2.5.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe" + "reference": "e6a83bedbe67579cb0bfb688e982e617943a2945" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe", - "reference": "aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/e6a83bedbe67579cb0bfb688e982e617943a2945", + "reference": "e6a83bedbe67579cb0bfb688e982e617943a2945", "shasum": "" }, "require": { @@ -1487,7 +1491,7 @@ "database", "orm" ], - "time": "2015-04-02 20:40:18" + "time": "2015-08-31 12:59:39" }, { "name": "dunglas/api-bundle", @@ -1495,12 +1499,12 @@ "source": { "type": "git", "url": "https://github.com/dunglas/DunglasApiBundle.git", - "reference": "b1f39f756f220148b58b9b39a892f0c8abe569b2" + "reference": "7882ec0c993e69f82cf66784f82c6b6df3ada6bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/b1f39f756f220148b58b9b39a892f0c8abe569b2", - "reference": "b1f39f756f220148b58b9b39a892f0c8abe569b2", + "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/7882ec0c993e69f82cf66784f82c6b6df3ada6bf", + "reference": "7882ec0c993e69f82cf66784f82c6b6df3ada6bf", "shasum": "" }, "require": { @@ -1513,8 +1517,9 @@ "phpdocumentor/reflection": "^1.0.7", "symfony/framework-bundle": "~2.6|~3.0", "symfony/proxy-manager-bridge": "~2.3", - "symfony/serializer": "~2.7|~3.0", - "symfony/validator": "~2.5|~3.0" + "symfony/serializer": "^2.7.2|~3.0", + "symfony/validator": "~2.5|~3.0", + "willdurand/negotiation": "~1.4" }, "require-dev": { "behat/behat": "~3.0", @@ -1522,10 +1527,11 @@ "behat/mink-browserkit-driver": "~1.1", "behat/mink-extension": "~2.0", "behat/symfony2-extension": "~2.0", - "behatch/contexts": "dev-master#eef7ab39ca896796bf3ba25a0fa5a95f15276eb7", + "behatch/contexts": "dev-master", "friendsofsymfony/user-bundle": "~1.3", "phpunit/phpunit": "~4.6", - "symfony/finder": "~2.3" + "symfony/finder": "~2.3", + "symfony/security": "~2.7.2|~3.0" }, "suggest": { "friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge." @@ -1561,7 +1567,7 @@ "json", "rest" ], - "time": "2015-07-08 09:05:56" + "time": "2015-09-17 07:26:14" }, { "name": "dunglas/php-property-info", @@ -1715,16 +1721,16 @@ }, { "name": "ocramius/proxy-manager", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/Ocramius/ProxyManager.git", - "reference": "a80a39fac4fbd771aea7d3871929933a3a1bbf3e" + "reference": "57e9272ec0e8deccf09421596e0e2252df440e11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/a80a39fac4fbd771aea7d3871929933a3a1bbf3e", - "reference": "a80a39fac4fbd771aea7d3871929933a3a1bbf3e", + "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/57e9272ec0e8deccf09421596e0e2252df440e11", + "reference": "57e9272ec0e8deccf09421596e0e2252df440e11", "shasum": "" }, "require": { @@ -1774,7 +1780,7 @@ "proxy pattern", "service proxies" ], - "time": "2014-12-12 10:59:05" + "time": "2015-08-09 04:28:19" }, { "name": "phpdocumentor/reflection", @@ -1881,16 +1887,16 @@ }, { "name": "symfony/asset", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "11f8e32ff4a854297f8a5ea3497e78f9d57d3b22" + "reference": "290cc813d01532de9a04884f32f300b67eb3b84d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/11f8e32ff4a854297f8a5ea3497e78f9d57d3b22", - "reference": "11f8e32ff4a854297f8a5ea3497e78f9d57d3b22", + "url": "https://api.github.com/repos/symfony/asset/zipball/290cc813d01532de9a04884f32f300b67eb3b84d", + "reference": "290cc813d01532de9a04884f32f300b67eb3b84d", "shasum": "" }, "require": { @@ -1930,20 +1936,20 @@ ], "description": "Symfony Asset Component", "homepage": "https://symfony.com/", - "time": "2015-05-01 14:16:41" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/debug", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Debug.git", - "reference": "075070230c5bbc65abde8241191655bbce0716e2" + "reference": "726bf9651d29f53243281d0b6418cfaa5e318281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/075070230c5bbc65abde8241191655bbce0716e2", - "reference": "075070230c5bbc65abde8241191655bbce0716e2", + "url": "https://api.github.com/repos/symfony/Debug/zipball/726bf9651d29f53243281d0b6418cfaa5e318281", + "reference": "726bf9651d29f53243281d0b6418cfaa5e318281", "shasum": "" }, "require": { @@ -1955,14 +1961,9 @@ }, "require-dev": { "symfony/class-loader": "~2.2", - "symfony/http-foundation": "~2.1", "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2", "symfony/phpunit-bridge": "~2.7" }, - "suggest": { - "symfony/http-foundation": "", - "symfony/http-kernel": "" - }, "type": "library", "extra": { "branch-alias": { @@ -1990,20 +1991,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-29 11:12:16" }, { "name": "symfony/dependency-injection", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "1a409e52a38ec891de0a7a61a191d1c62080b69d" + "reference": "c0a3a97b9450d77cd8eff81c5825efb3624c255b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/1a409e52a38ec891de0a7a61a191d1c62080b69d", - "reference": "1a409e52a38ec891de0a7a61a191d1c62080b69d", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/c0a3a97b9450d77cd8eff81c5825efb3624c255b", + "reference": "c0a3a97b9450d77cd8eff81c5825efb3624c255b", "shasum": "" }, "require": { @@ -2050,20 +2051,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 19:13:11" + "time": "2015-08-24 07:16:32" }, { "name": "symfony/doctrine-bridge", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/DoctrineBridge.git", - "reference": "50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a" + "reference": "a1c0ede6fe783f204455a3cfe867f8639afe371f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a", - "reference": "50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a", + "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/a1c0ede6fe783f204455a3cfe867f8639afe371f", + "reference": "a1c0ede6fe783f204455a3cfe867f8639afe371f", "shasum": "" }, "require": { @@ -2119,20 +2120,20 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com/", - "time": "2015-06-10 18:57:31" + "time": "2015-09-04 20:16:46" }, { "name": "symfony/framework-bundle", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/FrameworkBundle.git", - "reference": "dee055c00ac76bb079439aac4ec04897f00e1d43" + "reference": "5c2a5e8bf1f47a917714877eb17bb5b5add2796f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/dee055c00ac76bb079439aac4ec04897f00e1d43", - "reference": "dee055c00ac76bb079439aac4ec04897f00e1d43", + "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/5c2a5e8bf1f47a917714877eb17bb5b5add2796f", + "reference": "5c2a5e8bf1f47a917714877eb17bb5b5add2796f", "shasum": "" }, "require": { @@ -2160,7 +2161,7 @@ "symfony/dom-crawler": "~2.0,>=2.0.5", "symfony/expression-language": "~2.6", "symfony/finder": "~2.0,>=2.0.5", - "symfony/form": "~2.7", + "symfony/form": "~2.7,>=2.7.2", "symfony/intl": "~2.3", "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.0,>=2.0.5", @@ -2203,20 +2204,20 @@ ], "description": "Symfony FrameworkBundle", "homepage": "https://symfony.com/", - "time": "2015-06-11 17:26:34" + "time": "2015-09-03 11:40:38" }, { "name": "symfony/http-foundation", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "4f363c426b0ced57e3d14460022feb63937980ff" + "reference": "7253c2041652353e71560bbd300d6256d170ddaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/4f363c426b0ced57e3d14460022feb63937980ff", - "reference": "4f363c426b0ced57e3d14460022feb63937980ff", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/7253c2041652353e71560bbd300d6256d170ddaf", + "reference": "7253c2041652353e71560bbd300d6256d170ddaf", "shasum": "" }, "require": { @@ -2256,27 +2257,27 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com/", - "time": "2015-06-10 15:30:22" + "time": "2015-08-27 06:45:45" }, { "name": "symfony/http-kernel", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "208101c7a11e31933183bd2a380486e528c74302" + "reference": "fd9c7af92c9e3ade1327cc3af10b17731eebc4a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/208101c7a11e31933183bd2a380486e528c74302", - "reference": "208101c7a11e31933183bd2a380486e528c74302", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/fd9c7af92c9e3ade1327cc3af10b17731eebc4a7", + "reference": "fd9c7af92c9e3ade1327cc3af10b17731eebc4a7", "shasum": "" }, "require": { "php": ">=5.3.9", "psr/log": "~1.0", "symfony/debug": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2", + "symfony/event-dispatcher": "~2.6,>=2.6.7", "symfony/http-foundation": "~2.5,>=2.5.4" }, "conflict": { @@ -2336,11 +2337,11 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 21:15:28" + "time": "2015-09-08 14:26:39" }, { "name": "symfony/proxy-manager-bridge", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/ProxyManagerBridge.git", @@ -2392,16 +2393,16 @@ }, { "name": "symfony/routing", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "5581be29185b8fb802398904555f70da62f6d50d" + "reference": "20b1378cb6efffb77ea0608232f18c8f0dd25109" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/5581be29185b8fb802398904555f70da62f6d50d", - "reference": "5581be29185b8fb802398904555f70da62f6d50d", + "url": "https://api.github.com/repos/symfony/Routing/zipball/20b1378cb6efffb77ea0608232f18c8f0dd25109", + "reference": "20b1378cb6efffb77ea0608232f18c8f0dd25109", "shasum": "" }, "require": { @@ -2459,21 +2460,21 @@ "uri", "url" ], - "time": "2015-06-11 17:20:40" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/security", - "version": "v2.3.30", + "version": "v2.3.32", "target-dir": "Symfony/Component/Security", "source": { "type": "git", "url": "https://github.com/symfony/Security.git", - "reference": "b3d032613d74a7d5d7babeee28d9ac8f870ff36c" + "reference": "e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Security/zipball/b3d032613d74a7d5d7babeee28d9ac8f870ff36c", - "reference": "b3d032613d74a7d5d7babeee28d9ac8f870ff36c", + "url": "https://api.github.com/repos/symfony/Security/zipball/e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb", + "reference": "e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb", "shasum": "" }, "require": { @@ -2529,20 +2530,20 @@ ], "description": "Symfony Security Component", "homepage": "https://symfony.com/", - "time": "2015-05-21 04:29:49" + "time": "2015-08-07 07:22:48" }, { "name": "symfony/security-core", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "08cd68cea42ad73476d3900e675662db363c8fba" + "reference": "fba105731ce43dcb512ace74c82b72d042b6938c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/08cd68cea42ad73476d3900e675662db363c8fba", - "reference": "08cd68cea42ad73476d3900e675662db363c8fba", + "url": "https://api.github.com/repos/symfony/security-core/zipball/fba105731ce43dcb512ace74c82b72d042b6938c", + "reference": "fba105731ce43dcb512ace74c82b72d042b6938c", "shasum": "" }, "require": { @@ -2592,20 +2593,20 @@ ], "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-30 11:26:29" }, { "name": "symfony/security-csrf", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "e438b3e7de930e2147e397830126d2f0d32a0088" + "reference": "238d6aea56008bfeae16cb9703d52b123582288b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/e438b3e7de930e2147e397830126d2f0d32a0088", - "reference": "e438b3e7de930e2147e397830126d2f0d32a0088", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/238d6aea56008bfeae16cb9703d52b123582288b", + "reference": "238d6aea56008bfeae16cb9703d52b123582288b", "shasum": "" }, "require": { @@ -2646,20 +2647,20 @@ ], "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com/", - "time": "2015-05-13 11:34:46" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/serializer", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Serializer.git", - "reference": "edf2820c4948389e3f168a0160151806cefd6ac3" + "reference": "baf24f86a8656eea9c80988f332e51461bfcb67f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Serializer/zipball/edf2820c4948389e3f168a0160151806cefd6ac3", - "reference": "edf2820c4948389e3f168a0160151806cefd6ac3", + "url": "https://api.github.com/repos/symfony/Serializer/zipball/baf24f86a8656eea9c80988f332e51461bfcb67f", + "reference": "baf24f86a8656eea9c80988f332e51461bfcb67f", "shasum": "" }, "require": { @@ -2671,7 +2672,7 @@ "symfony/config": "~2.2", "symfony/phpunit-bridge": "~2.7", "symfony/property-access": "~2.3", - "symfony/yaml": "~2.0" + "symfony/yaml": "~2.0,>=2.0.5" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", @@ -2707,20 +2708,20 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-31 16:44:53" }, { "name": "symfony/templating", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Templating.git", - "reference": "3a2ed707230bae834ee24248a1a2a76f14eb3649" + "reference": "cb1b7421c53642bc515bc10caa81cc097775d6a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Templating/zipball/3a2ed707230bae834ee24248a1a2a76f14eb3649", - "reference": "3a2ed707230bae834ee24248a1a2a76f14eb3649", + "url": "https://api.github.com/repos/symfony/Templating/zipball/cb1b7421c53642bc515bc10caa81cc097775d6a1", + "reference": "cb1b7421c53642bc515bc10caa81cc097775d6a1", "shasum": "" }, "require": { @@ -2760,20 +2761,20 @@ ], "description": "Symfony Templating Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-30 11:26:29" }, { "name": "symfony/translation", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "8349a2b0d11bd0311df9e8914408080912983a0b" + "reference": "485877661835e188cd78345c6d4eef1290d17571" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/8349a2b0d11bd0311df9e8914408080912983a0b", - "reference": "8349a2b0d11bd0311df9e8914408080912983a0b", + "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571", + "reference": "485877661835e188cd78345c6d4eef1290d17571", "shasum": "" }, "require": { @@ -2785,7 +2786,7 @@ "require-dev": { "psr/log": "~1.0", "symfony/config": "~2.7", - "symfony/intl": "~2.3", + "symfony/intl": "~2.4", "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.2" }, @@ -2821,20 +2822,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 17:26:34" + "time": "2015-09-06 08:36:38" }, { "name": "symfony/validator", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Validator.git", - "reference": "3c58b1ef26ab2114f8f84d1808937b9b76bad8f5" + "reference": "356459a697e26274d44c608513c05c23dc1d8ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/3c58b1ef26ab2114f8f84d1808937b9b76bad8f5", - "reference": "3c58b1ef26ab2114f8f84d1808937b9b76bad8f5", + "url": "https://api.github.com/repos/symfony/Validator/zipball/356459a697e26274d44c608513c05c23dc1d8ea7", + "reference": "356459a697e26274d44c608513c05c23dc1d8ea7", "shasum": "" }, "require": { @@ -2848,7 +2849,7 @@ "symfony/config": "~2.2", "symfony/expression-language": "~2.4", "symfony/http-foundation": "~2.1", - "symfony/intl": "~2.3", + "symfony/intl": "~2.4", "symfony/phpunit-bridge": "~2.7", "symfony/property-access": "~2.3", "symfony/yaml": "~2.0,>=2.0.5" @@ -2891,24 +2892,73 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-09-06 08:36:38" + }, + { + "name": "willdurand/negotiation", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Negotiation.git", + "reference": "8a84c5956e765f432542fc52a8c6e9aff4508eb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/8a84c5956e765f432542fc52a8c6e9aff4508eb3", + "reference": "8a84c5956e765f432542fc52a8c6e9aff4508eb3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Negotiation\\": "src/Negotiation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William DURAND", + "email": "william.durand1@gmail.com" + } + ], + "description": "Content Negotiation tools for PHP provided as a standalone library.", + "homepage": "http://williamdurand.fr/Negotiation/", + "keywords": [ + "accept", + "content", + "format", + "header", + "negotiation" + ], + "time": "2015-07-28 13:10:50" }, { "name": "zendframework/zend-code", - "version": "2.5.1", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "5d998f261ec2a55171c71da57a11622745680153" + "reference": "a97ef49f82496fabc3b7379b37f6bbff925b58b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/5d998f261ec2a55171c71da57a11622745680153", - "reference": "5d998f261ec2a55171c71da57a11622745680153", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/a97ef49f82496fabc3b7379b37f6bbff925b58b8", + "reference": "a97ef49f82496fabc3b7379b37f6bbff925b58b8", "shasum": "" }, "require": { - "php": ">=5.3.23", + "php": ">=5.5", "zendframework/zend-eventmanager": "~2.5" }, "require-dev": { @@ -2944,24 +2994,24 @@ "code", "zf2" ], - "time": "2015-06-03 15:31:59" + "time": "2015-07-21 22:40:59" }, { "name": "zendframework/zend-eventmanager", - "version": "2.5.1", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "d94a16039144936f107f906896349900fd634443" + "reference": "135af03d07fd048c322259aab6611d2be290475c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d94a16039144936f107f906896349900fd634443", - "reference": "d94a16039144936f107f906896349900fd634443", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/135af03d07fd048c322259aab6611d2be290475c", + "reference": "135af03d07fd048c322259aab6611d2be290475c", "shasum": "" }, "require": { - "php": ">=5.3.23", + "php": ">=5.5", "zendframework/zend-stdlib": "~2.5" }, "require-dev": { @@ -2989,24 +3039,24 @@ "eventmanager", "zf2" ], - "time": "2015-06-03 15:32:01" + "time": "2015-07-16 19:00:49" }, { "name": "zendframework/zend-stdlib", - "version": "2.5.1", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae" + "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cc8e90a60dd5d44b9730b77d07b97550091da1ae", - "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/a35758803fc9051ec1aff43989e679b6b451b1b4", + "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": ">=5.5" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", @@ -3027,8 +3077,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" } }, "autoload": { @@ -3045,7 +3095,7 @@ "stdlib", "zf2" ], - "time": "2015-06-03 15:32:03" + "time": "2015-07-21 17:08:05" } ], "aliases": [], diff --git a/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php index 06b703e2..11931525 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -178,7 +178,7 @@ private function formatDoc($doc, $indent = false) if ($indent) { $count = count($doc); - for ($i = 1; $i < $count; $i++) { + for ($i = 1; $i < $count; ++$i) { $doc[$i] = self::INDENT.$doc[$i]; } } diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index c8bd463a..581dea70 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -235,7 +235,6 @@ public function generate($config) } } } - $numberOfRanges = count($ranges); if ($numberOfRanges === 0) { $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $property->localName(), $type->localName())); @@ -440,6 +439,42 @@ private function isEnum(\EasyRdf_Resource $type) return $subClassOf && $subClassOf->getUri() === self::SCHEMA_ORG_ENUMERATION; } + /** + * Gets the parent classes of the current one and add them to $parentClasses array. + * + * @param \EasyRdf_Resource $resource + * @param string[] $parentClasses + * + * @return array + */ + private function getParentClasses(\EasyRdf_Resource $resource, array $parentClasses = []) + { + if ([] === $parentClasses) { + return $this->getParentClasses($resource, [$resource->getUri()]); + } + + $subclasses = $resource->all('rdfs:subClassOf'); + + if (!$subclasses) { + return $parentClasses; + } + + $parentClass = $subclasses[0]; + $parentClasses[] = $parentClass->getUri(); + + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType('rdfs:Class') as $type) { + if ($type->getUri() === $parentClass->getUri()) { + $parentClasses = $this->getParentClasses($type, $parentClasses); + + break 2; + } + } + } + + return $parentClasses; + } + /** * Create a maps between class an properties. * @@ -452,15 +487,19 @@ private function createPropertiesMap(array $types) $typesAsString = []; $map = []; foreach ($types as $type) { - $typesAsString[] = $type->getUri(); + // get all parent classes until the root + $parentClasses = $this->getParentClasses($type); + $typesAsString[] = $parentClasses; $map[$type->getUri()] = []; } foreach ($this->graphs as $graph) { foreach ($graph->allOfType('rdf:Property') as $property) { foreach ($property->all(self::SCHEMA_ORG_DOMAIN) as $domain) { - if (in_array($domain->getUri(), $typesAsString)) { - $map[$domain->getUri()][] = $property; + foreach ($typesAsString as $typesAsStringItem) { + if (in_array($domain->getUri(), $typesAsStringItem)) { + $map[$typesAsStringItem[0]][] = $property; + } } } } diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index 405d0ecd..ea96e9fc 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -1,7 +1,7 @@ # The PHP namespace of generated entities namespaces: entity: "AddressBook\Entity" -# Enable DunglasJsonLdApiAnnotationGenerator +# Enable DunglasApiAnnotationGenerator annotationGenerators: - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator @@ -9,12 +9,10 @@ annotationGenerators: - SchemaOrgModel\AnnotationGenerator\DunglasApiAnnotationGenerator # The list of types and properties we want to use types: - # Parent class of Person - Thing: - properties: - name: ~ Person: + parent: false properties: + name: ~ familyName: ~ givenName: ~ additionalName: ~ @@ -41,4 +39,7 @@ types: postOfficeBoxNumber: ~ postalCode: ~ streetAddress: ~ - Organization: {} + Organization: + parent: false + properties: + name: ~ diff --git a/tests/run-tests.sh b/tests/run-tests.sh index c066d09d..3b5f305a 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -9,7 +9,6 @@ rm -Rf build/ mkdir -p build/full/ build/ecommerce/ build/address-book/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml -bin/schema generate-types build/full/ # Check code CS vendor/bin/php-cs-fixer --dry-run --diff -vvv fix src/ From b1e6af02c663cfa0f76b0c73196d5ad37e26b39d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 14 Jul 2015 18:14:22 +0200 Subject: [PATCH 010/258] Revert "Read external rdfa data" --- doc/configuration.md | 43 +------------------ .../DunglasApiAnnotationGenerator.php | 5 +-- src/SchemaOrgModel/TypesGenerator.php | 5 +-- tests/config/custom.yml | 9 ---- tests/data/custom.rdfa | 33 -------------- tests/run-tests.sh | 3 +- 6 files changed, 5 insertions(+), 93 deletions(-) delete mode 100644 tests/config/custom.yml delete mode 100644 tests/data/custom.rdfa diff --git a/doc/configuration.md b/doc/configuration.md index 4ae906e3..10ba9cac 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -203,49 +203,10 @@ Example: ```yaml rdfa: - https://raw.githubusercontent.com/rvguha/schemaorg/master/data/schema.rdfa # Experimental version of Schema.org - - http://example.com/data/myschema.rdfa # Additional types -types: - http://example.com/Language: - properties: - http://example.com/Locale: ~ + - http://example.com/data/myschema.rfa # Additional types ``` -myschema.rdfa -```html - - - - Custom RDFa - - - - - - -
- Language - Natural languages such as Spanish, Tamil, Hindi, English, etc. and programming languages such as Scheme and Lisp. -
- -
- Locale - User's language, country and any special variant preferences that the user wants to see in their user interface (in 2-letter <a href='https://en.wikipedia.org/wiki/ISO_639-1'>ISO 639-1</a> format). - Domain: Language - Range: Text -
- - - -``` +*Support for other namespaces than `http://schema.org` is planned for future versions but not currently available.* ## Checking GoodRelation compatibility diff --git a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php index b52a2a0c..69c5b2d5 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -35,10 +35,7 @@ public function generateClassAnnotations($className) */ public function generateFieldAnnotations($className, $fieldName) { - $resource = $this->classes[$className]['resource']; - $resourceUrl = parse_url(http://github.com/$resource-%3EgetUri()); - - return 'id' === $fieldName ? [] : [sprintf('@Iri("%s://%s/%s")', $resourceUrl['scheme'], $resourceUrl['host'], $fieldName)]; + return 'id' === $fieldName ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; } /** diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index cd5a416a..7814e0b8 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -135,9 +135,6 @@ public function generate($config) if (isset($resources[self::SCHEMA_ORG_NAMESPACE.$key])) { $resource = $graph->resource(self::SCHEMA_ORG_NAMESPACE.$key, 'rdfs:Class'); break; - } else if (isset($resources[$key])) { - $resource = $graph->resource($key, 'rdfs:Class'); - break; } } @@ -233,7 +230,7 @@ public function generate($config) $ranges[] = $typeConfig['properties'][$property->localName()]['range']; } else { foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { - if (!$typesDefined || $this->isDatatype($range->localName()) || (isset($config['types'][$range->localName()]) || isset($config['types'][$range->getUri()]))) { + if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { $ranges[] = $range->localName(); } } diff --git a/tests/config/custom.yml b/tests/config/custom.yml deleted file mode 100644 index c8e074c3..00000000 --- a/tests/config/custom.yml +++ /dev/null @@ -1,9 +0,0 @@ -rdfa: - - tests/data/schema.rdfa - - tests/data/custom.rdfa -namespaces: - entity: "Custom\Entity" -types: - http://example.com/Language: - properties: - http://example.com/Locale: ~ diff --git a/tests/data/custom.rdfa b/tests/data/custom.rdfa deleted file mode 100644 index 631e7305..00000000 --- a/tests/data/custom.rdfa +++ /dev/null @@ -1,33 +0,0 @@ - - - - Custom RDFa - - - - - - -
- Language - Natural languages such as Spanish, Tamil, Hindi, English, etc. and programming languages such as Scheme and Lisp. -
- -
- Locale - User's language, country and any special variant preferences that the user wants to see in their user interface (in 2-letter <a href='https://en.wikipedia.org/wiki/ISO_639-1'>ISO 639-1</a> format). - Domain: Language - Range: Text -
- - - diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 7f89263c..c066d09d 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -6,10 +6,9 @@ bin/schema extract-cardinalities # Build models rm -Rf build/ -mkdir -p build/full/ build/ecommerce/ build/address-book/ build/custom/ +mkdir -p build/full/ build/ecommerce/ build/address-book/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml -bin/schema generate-types build/custom/ tests/config/custom.yml bin/schema generate-types build/full/ # Check code CS From b07729cd408f25b85f51c244b9cd463d528c7f97 Mon Sep 17 00:00:00 2001 From: Gert Date: Thu, 20 Aug 2015 14:18:55 +0200 Subject: [PATCH 011/258] 0...* cardinality is also an array --- src/SchemaOrgModel/TypesGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index 7814e0b8..c8bd463a 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -250,6 +250,7 @@ public function generate($config) } $isArray = in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_0_N, CardinalitiesExtractor::CARDINALITY_1_N, CardinalitiesExtractor::CARDINALITY_N_N, ]); From 6d7d58d73da36ea4ec2aff0e68eff08eb4a11c44 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hubert?= Date: Sun, 23 Aug 2015 16:41:44 +0200 Subject: [PATCH 012/258] handle relation table name customization --- doc/configuration.md | 16 ++++++++++++++++ .../DoctrineOrmAnnotationGenerator.php | 13 +++++++++++-- .../TypesGeneratorConfiguration.php | 1 + tests/config/address-book.yml | 6 ++++++ 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/doc/configuration.md b/doc/configuration.md index 10ba9cac..8bd32f48 100644 --- a/doc/configuration.md +++ b/doc/configuration.md @@ -69,6 +69,22 @@ types: cardinality: "(0..1)" ``` +## Forcing a relation table name + +The relation table name between two entities is automatically guessed by Doctrine. The `relationTableName` option allows +to override the default value. + +This is useful when you need two entities to have more than one relation. + +Example: + +```yaml + Organization: + properties: + contactPoint: { range: Person, relationTableName: organization_contactPoint } + member: { range: Person, cardinality: (1..*) } ## Will be default value : organization_person +``` + ## Forcing (or disabling) a class parent Override the guessed class hierarchy of a given type with this option. diff --git a/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index d1961554..fbcf9765 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -50,6 +50,10 @@ public function generateFieldAnnotations($className, $fieldName) $this->classes[$className]; $field = $this->classes[$className]['fields'][$fieldName]; + $field['relationTableName'] = null; + if (!$field['isId'] && isset($this->config['types'][$className]['properties'][$fieldName])) { + $field['relationTableName'] = $this->config['types'][$className]['properties'][$fieldName]['relationTableName']; + } $annotations = []; if ($field['isEnum']) { @@ -140,16 +144,21 @@ public function generateFieldAnnotations($className, $fieldName) case CardinalitiesExtractor::CARDINALITY_0_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - $annotations[] = '@ORM\JoinTable(inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; + $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; + $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; break; case CardinalitiesExtractor::CARDINALITY_1_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - $annotations[] = '@ORM\JoinTable(inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; + $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; + $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; break; case CardinalitiesExtractor::CARDINALITY_N_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); + if ($field['relationTableName']) { + $annotations[] = sprintf('@ORM\JoinTable(name="%s")', $field['relationTableName']); + } break; } } diff --git a/src/SchemaOrgModel/TypesGeneratorConfiguration.php b/src/SchemaOrgModel/TypesGeneratorConfiguration.php index 4b440de3..d2aafa3b 100644 --- a/src/SchemaOrgModel/TypesGeneratorConfiguration.php +++ b/src/SchemaOrgModel/TypesGeneratorConfiguration.php @@ -97,6 +97,7 @@ public function getConfigTreeBuilder() ->addDefaultsIfNotSet() ->children() ->scalarNode('range')->defaultNull()->info('The property range')->example('Offer')->end() + ->scalarNode('relationTableName')->defaultNull()->info('The relation table name')->example('organization_member')->end() ->enumNode('cardinality')->defaultValue(CardinalitiesExtractor::CARDINALITY_UNKNOWN)->values([ CardinalitiesExtractor::CARDINALITY_0_1, CardinalitiesExtractor::CARDINALITY_0_N, diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index c866ece4..405d0ecd 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -25,6 +25,11 @@ types: email: ~ url: ~ jobTitle: ~ + # Default relation table name would be "person_organization" for all following fields, but we customize them + affiliation: ~ + brand: { relationTableName: "person_brand"} + memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} + worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} PostalAddress: # Disable the generation of the class hierarchy for this type parent: false @@ -36,3 +41,4 @@ types: postOfficeBoxNumber: ~ postalCode: ~ streetAddress: ~ + Organization: {} From 47d01f056d35f60bc696dcf0e1aecf8a36426cb7 Mon Sep 17 00:00:00 2001 From: aureluster Date: Thu, 13 Aug 2015 20:36:46 +0200 Subject: [PATCH 013/258] Allow using parent properties in child classes Refactor #15 and add tests. --- composer.lock | 460 ++++++++++-------- .../PhpDocAnnotationGenerator.php | 2 +- src/SchemaOrgModel/TypesGenerator.php | 47 +- tests/config/address-book.yml | 13 +- tests/run-tests.sh | 1 - 5 files changed, 306 insertions(+), 217 deletions(-) diff --git a/composer.lock b/composer.lock index e8ba14e3..b5f2ee8c 100644 --- a/composer.lock +++ b/composer.lock @@ -70,16 +70,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.9", + "version": "v1.10", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "ef528b9d3f1dd66197baabf8f77c8402c62bb9fc" + "reference": "8e21b4fb32c4618a425817d9f0daf3d57a9808d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/ef528b9d3f1dd66197baabf8f77c8402c62bb9fc", - "reference": "ef528b9d3f1dd66197baabf8f77c8402c62bb9fc", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/8e21b4fb32c4618a425817d9f0daf3d57a9808d1", + "reference": "8e21b4fb32c4618a425817d9f0daf3d57a9808d1", "shasum": "" }, "require": { @@ -120,7 +120,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-06-13 09:30:19" + "time": "2015-07-27 20:56:10" }, { "name": "nickcernis/html-to-markdown", @@ -260,16 +260,16 @@ }, { "name": "symfony/config", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Config.git", - "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374" + "reference": "5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/58ded81f1f582a87c528ef3dae9a859f78b5f374", - "reference": "58ded81f1f582a87c528ef3dae9a859f78b5f374", + "url": "https://api.github.com/repos/symfony/Config/zipball/5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8", + "reference": "5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8", "shasum": "" }, "require": { @@ -306,20 +306,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 14:06:56" + "time": "2015-08-27 06:45:45" }, { "name": "symfony/console", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Console.git", - "reference": "564398bc1f33faf92fc2ec86859983d30eb81806" + "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/564398bc1f33faf92fc2ec86859983d30eb81806", - "reference": "564398bc1f33faf92fc2ec86859983d30eb81806", + "url": "https://api.github.com/repos/symfony/Console/zipball/9ff9032151186bd66ecee727d728f1319f52d1d8", + "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8", "shasum": "" }, "require": { @@ -363,20 +363,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com/", - "time": "2015-06-10 15:30:22" + "time": "2015-09-03 11:40:38" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9" + "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/be3c5ff8d503c46768aeb78ce6333051aa6f26d9", - "reference": "be3c5ff8d503c46768aeb78ce6333051aa6f26d9", + "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/b58c916f1db03a611b72dd702564f30ad8fe83fa", + "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa", "shasum": "" }, "require": { @@ -421,20 +421,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/filesystem", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Filesystem.git", - "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3" + "reference": "f079e9933799929584200b9a926f72f29e291654" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/a0d43eb3e17d4f4c6990289805a488a0482a07f3", - "reference": "a0d43eb3e17d4f4c6990289805a488a0482a07f3", + "url": "https://api.github.com/repos/symfony/Filesystem/zipball/f079e9933799929584200b9a926f72f29e291654", + "reference": "f079e9933799929584200b9a926f72f29e291654", "shasum": "" }, "require": { @@ -470,20 +470,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-27 07:03:44" }, { "name": "symfony/finder", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Finder.git", - "reference": "c13a40d638aeede1e8400f8c956c7f9246c05f75" + "reference": "fff4b0c362640a0ab7355e2647b3d461608e9065" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/c13a40d638aeede1e8400f8c956c7f9246c05f75", - "reference": "c13a40d638aeede1e8400f8c956c7f9246c05f75", + "url": "https://api.github.com/repos/symfony/Finder/zipball/fff4b0c362640a0ab7355e2647b3d461608e9065", + "reference": "fff4b0c362640a0ab7355e2647b3d461608e9065", "shasum": "" }, "require": { @@ -519,20 +519,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com/", - "time": "2015-06-04 20:11:48" + "time": "2015-08-26 17:56:37" }, { "name": "symfony/process", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Process.git", - "reference": "552d8efdc80980cbcca50b28d626ac8e36e3cdd1" + "reference": "f7b3f73f70a7f8f49a1c838dc3debbf054732d8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/552d8efdc80980cbcca50b28d626ac8e36e3cdd1", - "reference": "552d8efdc80980cbcca50b28d626ac8e36e3cdd1", + "url": "https://api.github.com/repos/symfony/Process/zipball/f7b3f73f70a7f8f49a1c838dc3debbf054732d8e", + "reference": "f7b3f73f70a7f8f49a1c838dc3debbf054732d8e", "shasum": "" }, "require": { @@ -568,20 +568,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-27 06:45:45" }, { "name": "symfony/stopwatch", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Stopwatch.git", - "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b" + "reference": "abc61bac76fb10ffa2c6373d7932bc35190dbf3b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", - "reference": "c653f1985f6c2b7dbffd04d48b9c0a96aaef814b", + "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/abc61bac76fb10ffa2c6373d7932bc35190dbf3b", + "reference": "abc61bac76fb10ffa2c6373d7932bc35190dbf3b", "shasum": "" }, "require": { @@ -617,20 +617,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com/", - "time": "2015-06-04 20:11:48" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/yaml", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Yaml.git", - "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160" + "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/9808e75c609a14f6db02f70fccf4ca4aab53c160", - "reference": "9808e75c609a14f6db02f70fccf4ca4aab53c160", + "url": "https://api.github.com/repos/symfony/Yaml/zipball/2dc7b06c065df96cc686c66da2705e5e18aef661", + "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661", "shasum": "" }, "require": { @@ -666,29 +666,33 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com/", - "time": "2015-06-10 15:30:22" + "time": "2015-08-24 07:13:45" }, { "name": "twig/twig", - "version": "v1.18.2", + "version": "v1.22.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e8e6575abf6102af53ec283f7f14b89e304fa602" + "reference": "b7fc2469fa009897871fb95b68237286fc54a5ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e8e6575abf6102af53ec283f7f14b89e304fa602", - "reference": "e8e6575abf6102af53ec283f7f14b89e304fa602", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/b7fc2469fa009897871fb95b68237286fc54a5ad", + "reference": "b7fc2469fa009897871fb95b68237286fc54a5ad", "shasum": "" }, "require": { "php": ">=5.2.7" }, + "require-dev": { + "symfony/debug": "~2.7", + "symfony/phpunit-bridge": "~2.7" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.18-dev" + "dev-master": "1.22-dev" } }, "autoload": { @@ -723,22 +727,22 @@ "keywords": [ "templating" ], - "time": "2015-06-06 23:31:24" + "time": "2015-09-15 06:50:16" } ], "packages-dev": [ { "name": "doctrine/annotations", - "version": "v1.2.6", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4" + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/f4a91702ca3cd2e568c3736aa031ed00c3752af4", - "reference": "f4a91702ca3cd2e568c3736aa031ed00c3752af4", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", + "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", "shasum": "" }, "require": { @@ -793,20 +797,20 @@ "docblock", "parser" ], - "time": "2015-06-17 12:21:22" + "time": "2015-08-31 12:32:49" }, { "name": "doctrine/cache", - "version": "v1.4.1", + "version": "v1.4.2", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03" + "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/c9eadeb743ac6199f7eec423cb9426bc518b7b03", - "reference": "c9eadeb743ac6199f7eec423cb9426bc518b7b03", + "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca", + "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca", "shasum": "" }, "require": { @@ -863,7 +867,7 @@ "cache", "caching" ], - "time": "2015-04-15 00:11:59" + "time": "2015-08-31 12:36:41" }, { "name": "doctrine/collections", @@ -933,16 +937,16 @@ }, { "name": "doctrine/common", - "version": "v2.5.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3" + "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/cd8daf2501e10c63dced7b8b9b905844316ae9d3", - "reference": "cd8daf2501e10c63dced7b8b9b905844316ae9d3", + "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9", + "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9", "shasum": "" }, "require": { @@ -1002,20 +1006,20 @@ "persistence", "spl" ], - "time": "2015-04-02 19:55:44" + "time": "2015-08-31 13:00:22" }, { "name": "doctrine/dbal", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "628c2256b646ae2417d44e063bce8aec5199d48d" + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/628c2256b646ae2417d44e063bce8aec5199d48d", - "reference": "628c2256b646ae2417d44e063bce8aec5199d48d", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c", "shasum": "" }, "require": { @@ -1073,20 +1077,20 @@ "persistence", "queryobject" ], - "time": "2015-01-12 21:52:47" + "time": "2015-09-16 16:29:33" }, { "name": "doctrine/doctrine-bundle", - "version": "v1.5.0", + "version": "v1.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f" + "reference": "8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/0b9e27037c4fdbad515ee5ec89842e9091a6480f", - "reference": "0b9e27037c4fdbad515ee5ec89842e9091a6480f", + "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01", + "reference": "8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01", "shasum": "" }, "require": { @@ -1094,16 +1098,16 @@ "doctrine/doctrine-cache-bundle": "~1.0", "jdorn/sql-formatter": "~1.1", "php": ">=5.3.2", - "symfony/console": "~2.3", - "symfony/doctrine-bridge": "~2.2", - "symfony/framework-bundle": "~2.3" + "symfony/console": "~2.3|~3.0", + "symfony/doctrine-bridge": "~2.2|~3.0", + "symfony/framework-bundle": "~2.3|~3.0" }, "require-dev": { "doctrine/orm": "~2.3", "phpunit/phpunit": "~4", "satooshi/php-coveralls": "~0.6.1", - "symfony/validator": "~2.2", - "symfony/yaml": "~2.2", + "symfony/validator": "~2.2|~3.0", + "symfony/yaml": "~2.2|~3.0", "twig/twig": "~1.10" }, "suggest": { @@ -1151,7 +1155,7 @@ "orm", "persistence" ], - "time": "2015-05-28 12:27:15" + "time": "2015-08-12 15:52:00" }, { "name": "doctrine/doctrine-cache-bundle", @@ -1414,16 +1418,16 @@ }, { "name": "doctrine/orm", - "version": "v2.5.0", + "version": "v2.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe" + "reference": "e6a83bedbe67579cb0bfb688e982e617943a2945" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe", - "reference": "aa80c7d2c55a372f5f9f825f5c66dbda53a6e3fe", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/e6a83bedbe67579cb0bfb688e982e617943a2945", + "reference": "e6a83bedbe67579cb0bfb688e982e617943a2945", "shasum": "" }, "require": { @@ -1487,7 +1491,7 @@ "database", "orm" ], - "time": "2015-04-02 20:40:18" + "time": "2015-08-31 12:59:39" }, { "name": "dunglas/api-bundle", @@ -1495,12 +1499,12 @@ "source": { "type": "git", "url": "https://github.com/dunglas/DunglasApiBundle.git", - "reference": "b1f39f756f220148b58b9b39a892f0c8abe569b2" + "reference": "7882ec0c993e69f82cf66784f82c6b6df3ada6bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/b1f39f756f220148b58b9b39a892f0c8abe569b2", - "reference": "b1f39f756f220148b58b9b39a892f0c8abe569b2", + "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/7882ec0c993e69f82cf66784f82c6b6df3ada6bf", + "reference": "7882ec0c993e69f82cf66784f82c6b6df3ada6bf", "shasum": "" }, "require": { @@ -1513,8 +1517,9 @@ "phpdocumentor/reflection": "^1.0.7", "symfony/framework-bundle": "~2.6|~3.0", "symfony/proxy-manager-bridge": "~2.3", - "symfony/serializer": "~2.7|~3.0", - "symfony/validator": "~2.5|~3.0" + "symfony/serializer": "^2.7.2|~3.0", + "symfony/validator": "~2.5|~3.0", + "willdurand/negotiation": "~1.4" }, "require-dev": { "behat/behat": "~3.0", @@ -1522,10 +1527,11 @@ "behat/mink-browserkit-driver": "~1.1", "behat/mink-extension": "~2.0", "behat/symfony2-extension": "~2.0", - "behatch/contexts": "dev-master#eef7ab39ca896796bf3ba25a0fa5a95f15276eb7", + "behatch/contexts": "dev-master", "friendsofsymfony/user-bundle": "~1.3", "phpunit/phpunit": "~4.6", - "symfony/finder": "~2.3" + "symfony/finder": "~2.3", + "symfony/security": "~2.7.2|~3.0" }, "suggest": { "friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge." @@ -1561,7 +1567,7 @@ "json", "rest" ], - "time": "2015-07-08 09:05:56" + "time": "2015-09-17 07:26:14" }, { "name": "dunglas/php-property-info", @@ -1715,16 +1721,16 @@ }, { "name": "ocramius/proxy-manager", - "version": "1.0.0", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/Ocramius/ProxyManager.git", - "reference": "a80a39fac4fbd771aea7d3871929933a3a1bbf3e" + "reference": "57e9272ec0e8deccf09421596e0e2252df440e11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/a80a39fac4fbd771aea7d3871929933a3a1bbf3e", - "reference": "a80a39fac4fbd771aea7d3871929933a3a1bbf3e", + "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/57e9272ec0e8deccf09421596e0e2252df440e11", + "reference": "57e9272ec0e8deccf09421596e0e2252df440e11", "shasum": "" }, "require": { @@ -1774,7 +1780,7 @@ "proxy pattern", "service proxies" ], - "time": "2014-12-12 10:59:05" + "time": "2015-08-09 04:28:19" }, { "name": "phpdocumentor/reflection", @@ -1881,16 +1887,16 @@ }, { "name": "symfony/asset", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/asset.git", - "reference": "11f8e32ff4a854297f8a5ea3497e78f9d57d3b22" + "reference": "290cc813d01532de9a04884f32f300b67eb3b84d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/11f8e32ff4a854297f8a5ea3497e78f9d57d3b22", - "reference": "11f8e32ff4a854297f8a5ea3497e78f9d57d3b22", + "url": "https://api.github.com/repos/symfony/asset/zipball/290cc813d01532de9a04884f32f300b67eb3b84d", + "reference": "290cc813d01532de9a04884f32f300b67eb3b84d", "shasum": "" }, "require": { @@ -1930,20 +1936,20 @@ ], "description": "Symfony Asset Component", "homepage": "https://symfony.com/", - "time": "2015-05-01 14:16:41" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/debug", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Debug.git", - "reference": "075070230c5bbc65abde8241191655bbce0716e2" + "reference": "726bf9651d29f53243281d0b6418cfaa5e318281" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/075070230c5bbc65abde8241191655bbce0716e2", - "reference": "075070230c5bbc65abde8241191655bbce0716e2", + "url": "https://api.github.com/repos/symfony/Debug/zipball/726bf9651d29f53243281d0b6418cfaa5e318281", + "reference": "726bf9651d29f53243281d0b6418cfaa5e318281", "shasum": "" }, "require": { @@ -1955,14 +1961,9 @@ }, "require-dev": { "symfony/class-loader": "~2.2", - "symfony/http-foundation": "~2.1", "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2", "symfony/phpunit-bridge": "~2.7" }, - "suggest": { - "symfony/http-foundation": "", - "symfony/http-kernel": "" - }, "type": "library", "extra": { "branch-alias": { @@ -1990,20 +1991,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-29 11:12:16" }, { "name": "symfony/dependency-injection", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "1a409e52a38ec891de0a7a61a191d1c62080b69d" + "reference": "c0a3a97b9450d77cd8eff81c5825efb3624c255b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/1a409e52a38ec891de0a7a61a191d1c62080b69d", - "reference": "1a409e52a38ec891de0a7a61a191d1c62080b69d", + "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/c0a3a97b9450d77cd8eff81c5825efb3624c255b", + "reference": "c0a3a97b9450d77cd8eff81c5825efb3624c255b", "shasum": "" }, "require": { @@ -2050,20 +2051,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 19:13:11" + "time": "2015-08-24 07:16:32" }, { "name": "symfony/doctrine-bridge", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/DoctrineBridge.git", - "reference": "50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a" + "reference": "a1c0ede6fe783f204455a3cfe867f8639afe371f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a", - "reference": "50bb5d6f96b1ada9cbfea57dcc09c194ed249d1a", + "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/a1c0ede6fe783f204455a3cfe867f8639afe371f", + "reference": "a1c0ede6fe783f204455a3cfe867f8639afe371f", "shasum": "" }, "require": { @@ -2119,20 +2120,20 @@ ], "description": "Symfony Doctrine Bridge", "homepage": "https://symfony.com/", - "time": "2015-06-10 18:57:31" + "time": "2015-09-04 20:16:46" }, { "name": "symfony/framework-bundle", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/FrameworkBundle.git", - "reference": "dee055c00ac76bb079439aac4ec04897f00e1d43" + "reference": "5c2a5e8bf1f47a917714877eb17bb5b5add2796f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/dee055c00ac76bb079439aac4ec04897f00e1d43", - "reference": "dee055c00ac76bb079439aac4ec04897f00e1d43", + "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/5c2a5e8bf1f47a917714877eb17bb5b5add2796f", + "reference": "5c2a5e8bf1f47a917714877eb17bb5b5add2796f", "shasum": "" }, "require": { @@ -2160,7 +2161,7 @@ "symfony/dom-crawler": "~2.0,>=2.0.5", "symfony/expression-language": "~2.6", "symfony/finder": "~2.0,>=2.0.5", - "symfony/form": "~2.7", + "symfony/form": "~2.7,>=2.7.2", "symfony/intl": "~2.3", "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.0,>=2.0.5", @@ -2203,20 +2204,20 @@ ], "description": "Symfony FrameworkBundle", "homepage": "https://symfony.com/", - "time": "2015-06-11 17:26:34" + "time": "2015-09-03 11:40:38" }, { "name": "symfony/http-foundation", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "4f363c426b0ced57e3d14460022feb63937980ff" + "reference": "7253c2041652353e71560bbd300d6256d170ddaf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/4f363c426b0ced57e3d14460022feb63937980ff", - "reference": "4f363c426b0ced57e3d14460022feb63937980ff", + "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/7253c2041652353e71560bbd300d6256d170ddaf", + "reference": "7253c2041652353e71560bbd300d6256d170ddaf", "shasum": "" }, "require": { @@ -2256,27 +2257,27 @@ ], "description": "Symfony HttpFoundation Component", "homepage": "https://symfony.com/", - "time": "2015-06-10 15:30:22" + "time": "2015-08-27 06:45:45" }, { "name": "symfony/http-kernel", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/HttpKernel.git", - "reference": "208101c7a11e31933183bd2a380486e528c74302" + "reference": "fd9c7af92c9e3ade1327cc3af10b17731eebc4a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/208101c7a11e31933183bd2a380486e528c74302", - "reference": "208101c7a11e31933183bd2a380486e528c74302", + "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/fd9c7af92c9e3ade1327cc3af10b17731eebc4a7", + "reference": "fd9c7af92c9e3ade1327cc3af10b17731eebc4a7", "shasum": "" }, "require": { "php": ">=5.3.9", "psr/log": "~1.0", "symfony/debug": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.5.9|~2.6,>=2.6.2", + "symfony/event-dispatcher": "~2.6,>=2.6.7", "symfony/http-foundation": "~2.5,>=2.5.4" }, "conflict": { @@ -2336,11 +2337,11 @@ ], "description": "Symfony HttpKernel Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 21:15:28" + "time": "2015-09-08 14:26:39" }, { "name": "symfony/proxy-manager-bridge", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/ProxyManagerBridge.git", @@ -2392,16 +2393,16 @@ }, { "name": "symfony/routing", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Routing.git", - "reference": "5581be29185b8fb802398904555f70da62f6d50d" + "reference": "20b1378cb6efffb77ea0608232f18c8f0dd25109" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/5581be29185b8fb802398904555f70da62f6d50d", - "reference": "5581be29185b8fb802398904555f70da62f6d50d", + "url": "https://api.github.com/repos/symfony/Routing/zipball/20b1378cb6efffb77ea0608232f18c8f0dd25109", + "reference": "20b1378cb6efffb77ea0608232f18c8f0dd25109", "shasum": "" }, "require": { @@ -2459,21 +2460,21 @@ "uri", "url" ], - "time": "2015-06-11 17:20:40" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/security", - "version": "v2.3.30", + "version": "v2.3.32", "target-dir": "Symfony/Component/Security", "source": { "type": "git", "url": "https://github.com/symfony/Security.git", - "reference": "b3d032613d74a7d5d7babeee28d9ac8f870ff36c" + "reference": "e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Security/zipball/b3d032613d74a7d5d7babeee28d9ac8f870ff36c", - "reference": "b3d032613d74a7d5d7babeee28d9ac8f870ff36c", + "url": "https://api.github.com/repos/symfony/Security/zipball/e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb", + "reference": "e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb", "shasum": "" }, "require": { @@ -2529,20 +2530,20 @@ ], "description": "Symfony Security Component", "homepage": "https://symfony.com/", - "time": "2015-05-21 04:29:49" + "time": "2015-08-07 07:22:48" }, { "name": "symfony/security-core", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/security-core.git", - "reference": "08cd68cea42ad73476d3900e675662db363c8fba" + "reference": "fba105731ce43dcb512ace74c82b72d042b6938c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/08cd68cea42ad73476d3900e675662db363c8fba", - "reference": "08cd68cea42ad73476d3900e675662db363c8fba", + "url": "https://api.github.com/repos/symfony/security-core/zipball/fba105731ce43dcb512ace74c82b72d042b6938c", + "reference": "fba105731ce43dcb512ace74c82b72d042b6938c", "shasum": "" }, "require": { @@ -2592,20 +2593,20 @@ ], "description": "Symfony Security Component - Core Library", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-30 11:26:29" }, { "name": "symfony/security-csrf", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/security-csrf.git", - "reference": "e438b3e7de930e2147e397830126d2f0d32a0088" + "reference": "238d6aea56008bfeae16cb9703d52b123582288b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/e438b3e7de930e2147e397830126d2f0d32a0088", - "reference": "e438b3e7de930e2147e397830126d2f0d32a0088", + "url": "https://api.github.com/repos/symfony/security-csrf/zipball/238d6aea56008bfeae16cb9703d52b123582288b", + "reference": "238d6aea56008bfeae16cb9703d52b123582288b", "shasum": "" }, "require": { @@ -2646,20 +2647,20 @@ ], "description": "Symfony Security Component - CSRF Library", "homepage": "https://symfony.com/", - "time": "2015-05-13 11:34:46" + "time": "2015-08-24 07:13:45" }, { "name": "symfony/serializer", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Serializer.git", - "reference": "edf2820c4948389e3f168a0160151806cefd6ac3" + "reference": "baf24f86a8656eea9c80988f332e51461bfcb67f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Serializer/zipball/edf2820c4948389e3f168a0160151806cefd6ac3", - "reference": "edf2820c4948389e3f168a0160151806cefd6ac3", + "url": "https://api.github.com/repos/symfony/Serializer/zipball/baf24f86a8656eea9c80988f332e51461bfcb67f", + "reference": "baf24f86a8656eea9c80988f332e51461bfcb67f", "shasum": "" }, "require": { @@ -2671,7 +2672,7 @@ "symfony/config": "~2.2", "symfony/phpunit-bridge": "~2.7", "symfony/property-access": "~2.3", - "symfony/yaml": "~2.0" + "symfony/yaml": "~2.0,>=2.0.5" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", @@ -2707,20 +2708,20 @@ ], "description": "Symfony Serializer Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-31 16:44:53" }, { "name": "symfony/templating", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Templating.git", - "reference": "3a2ed707230bae834ee24248a1a2a76f14eb3649" + "reference": "cb1b7421c53642bc515bc10caa81cc097775d6a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Templating/zipball/3a2ed707230bae834ee24248a1a2a76f14eb3649", - "reference": "3a2ed707230bae834ee24248a1a2a76f14eb3649", + "url": "https://api.github.com/repos/symfony/Templating/zipball/cb1b7421c53642bc515bc10caa81cc097775d6a1", + "reference": "cb1b7421c53642bc515bc10caa81cc097775d6a1", "shasum": "" }, "require": { @@ -2760,20 +2761,20 @@ ], "description": "Symfony Templating Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-08-30 11:26:29" }, { "name": "symfony/translation", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Translation.git", - "reference": "8349a2b0d11bd0311df9e8914408080912983a0b" + "reference": "485877661835e188cd78345c6d4eef1290d17571" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/8349a2b0d11bd0311df9e8914408080912983a0b", - "reference": "8349a2b0d11bd0311df9e8914408080912983a0b", + "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571", + "reference": "485877661835e188cd78345c6d4eef1290d17571", "shasum": "" }, "require": { @@ -2785,7 +2786,7 @@ "require-dev": { "psr/log": "~1.0", "symfony/config": "~2.7", - "symfony/intl": "~2.3", + "symfony/intl": "~2.4", "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.2" }, @@ -2821,20 +2822,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com/", - "time": "2015-06-11 17:26:34" + "time": "2015-09-06 08:36:38" }, { "name": "symfony/validator", - "version": "v2.7.1", + "version": "v2.7.4", "source": { "type": "git", "url": "https://github.com/symfony/Validator.git", - "reference": "3c58b1ef26ab2114f8f84d1808937b9b76bad8f5" + "reference": "356459a697e26274d44c608513c05c23dc1d8ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/3c58b1ef26ab2114f8f84d1808937b9b76bad8f5", - "reference": "3c58b1ef26ab2114f8f84d1808937b9b76bad8f5", + "url": "https://api.github.com/repos/symfony/Validator/zipball/356459a697e26274d44c608513c05c23dc1d8ea7", + "reference": "356459a697e26274d44c608513c05c23dc1d8ea7", "shasum": "" }, "require": { @@ -2848,7 +2849,7 @@ "symfony/config": "~2.2", "symfony/expression-language": "~2.4", "symfony/http-foundation": "~2.1", - "symfony/intl": "~2.3", + "symfony/intl": "~2.4", "symfony/phpunit-bridge": "~2.7", "symfony/property-access": "~2.3", "symfony/yaml": "~2.0,>=2.0.5" @@ -2891,24 +2892,73 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", - "time": "2015-06-08 09:37:21" + "time": "2015-09-06 08:36:38" + }, + { + "name": "willdurand/negotiation", + "version": "1.4.0", + "source": { + "type": "git", + "url": "https://github.com/willdurand/Negotiation.git", + "reference": "8a84c5956e765f432542fc52a8c6e9aff4508eb3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/8a84c5956e765f432542fc52a8c6e9aff4508eb3", + "reference": "8a84c5956e765f432542fc52a8c6e9aff4508eb3", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4-dev" + } + }, + "autoload": { + "psr-4": { + "Negotiation\\": "src/Negotiation" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "William DURAND", + "email": "william.durand1@gmail.com" + } + ], + "description": "Content Negotiation tools for PHP provided as a standalone library.", + "homepage": "http://williamdurand.fr/Negotiation/", + "keywords": [ + "accept", + "content", + "format", + "header", + "negotiation" + ], + "time": "2015-07-28 13:10:50" }, { "name": "zendframework/zend-code", - "version": "2.5.1", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-code.git", - "reference": "5d998f261ec2a55171c71da57a11622745680153" + "reference": "a97ef49f82496fabc3b7379b37f6bbff925b58b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/5d998f261ec2a55171c71da57a11622745680153", - "reference": "5d998f261ec2a55171c71da57a11622745680153", + "url": "https://api.github.com/repos/zendframework/zend-code/zipball/a97ef49f82496fabc3b7379b37f6bbff925b58b8", + "reference": "a97ef49f82496fabc3b7379b37f6bbff925b58b8", "shasum": "" }, "require": { - "php": ">=5.3.23", + "php": ">=5.5", "zendframework/zend-eventmanager": "~2.5" }, "require-dev": { @@ -2944,24 +2994,24 @@ "code", "zf2" ], - "time": "2015-06-03 15:31:59" + "time": "2015-07-21 22:40:59" }, { "name": "zendframework/zend-eventmanager", - "version": "2.5.1", + "version": "2.5.2", "source": { "type": "git", "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "d94a16039144936f107f906896349900fd634443" + "reference": "135af03d07fd048c322259aab6611d2be290475c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/d94a16039144936f107f906896349900fd634443", - "reference": "d94a16039144936f107f906896349900fd634443", + "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/135af03d07fd048c322259aab6611d2be290475c", + "reference": "135af03d07fd048c322259aab6611d2be290475c", "shasum": "" }, "require": { - "php": ">=5.3.23", + "php": ">=5.5", "zendframework/zend-stdlib": "~2.5" }, "require-dev": { @@ -2989,24 +3039,24 @@ "eventmanager", "zf2" ], - "time": "2015-06-03 15:32:01" + "time": "2015-07-16 19:00:49" }, { "name": "zendframework/zend-stdlib", - "version": "2.5.1", + "version": "2.6.0", "source": { "type": "git", "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae" + "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/cc8e90a60dd5d44b9730b77d07b97550091da1ae", - "reference": "cc8e90a60dd5d44b9730b77d07b97550091da1ae", + "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/a35758803fc9051ec1aff43989e679b6b451b1b4", + "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4", "shasum": "" }, "require": { - "php": ">=5.3.23" + "php": ">=5.5" }, "require-dev": { "fabpot/php-cs-fixer": "1.7.*", @@ -3027,8 +3077,8 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" + "dev-master": "2.6-dev", + "dev-develop": "2.7-dev" } }, "autoload": { @@ -3045,7 +3095,7 @@ "stdlib", "zf2" ], - "time": "2015-06-03 15:32:03" + "time": "2015-07-21 17:08:05" } ], "aliases": [], diff --git a/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php index 06b703e2..11931525 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -178,7 +178,7 @@ private function formatDoc($doc, $indent = false) if ($indent) { $count = count($doc); - for ($i = 1; $i < $count; $i++) { + for ($i = 1; $i < $count; ++$i) { $doc[$i] = self::INDENT.$doc[$i]; } } diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index c8bd463a..581dea70 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -235,7 +235,6 @@ public function generate($config) } } } - $numberOfRanges = count($ranges); if ($numberOfRanges === 0) { $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $property->localName(), $type->localName())); @@ -440,6 +439,42 @@ private function isEnum(\EasyRdf_Resource $type) return $subClassOf && $subClassOf->getUri() === self::SCHEMA_ORG_ENUMERATION; } + /** + * Gets the parent classes of the current one and add them to $parentClasses array. + * + * @param \EasyRdf_Resource $resource + * @param string[] $parentClasses + * + * @return array + */ + private function getParentClasses(\EasyRdf_Resource $resource, array $parentClasses = []) + { + if ([] === $parentClasses) { + return $this->getParentClasses($resource, [$resource->getUri()]); + } + + $subclasses = $resource->all('rdfs:subClassOf'); + + if (!$subclasses) { + return $parentClasses; + } + + $parentClass = $subclasses[0]; + $parentClasses[] = $parentClass->getUri(); + + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType('rdfs:Class') as $type) { + if ($type->getUri() === $parentClass->getUri()) { + $parentClasses = $this->getParentClasses($type, $parentClasses); + + break 2; + } + } + } + + return $parentClasses; + } + /** * Create a maps between class an properties. * @@ -452,15 +487,19 @@ private function createPropertiesMap(array $types) $typesAsString = []; $map = []; foreach ($types as $type) { - $typesAsString[] = $type->getUri(); + // get all parent classes until the root + $parentClasses = $this->getParentClasses($type); + $typesAsString[] = $parentClasses; $map[$type->getUri()] = []; } foreach ($this->graphs as $graph) { foreach ($graph->allOfType('rdf:Property') as $property) { foreach ($property->all(self::SCHEMA_ORG_DOMAIN) as $domain) { - if (in_array($domain->getUri(), $typesAsString)) { - $map[$domain->getUri()][] = $property; + foreach ($typesAsString as $typesAsStringItem) { + if (in_array($domain->getUri(), $typesAsStringItem)) { + $map[$typesAsStringItem[0]][] = $property; + } } } } diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index 405d0ecd..ea96e9fc 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -1,7 +1,7 @@ # The PHP namespace of generated entities namespaces: entity: "AddressBook\Entity" -# Enable DunglasJsonLdApiAnnotationGenerator +# Enable DunglasApiAnnotationGenerator annotationGenerators: - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator @@ -9,12 +9,10 @@ annotationGenerators: - SchemaOrgModel\AnnotationGenerator\DunglasApiAnnotationGenerator # The list of types and properties we want to use types: - # Parent class of Person - Thing: - properties: - name: ~ Person: + parent: false properties: + name: ~ familyName: ~ givenName: ~ additionalName: ~ @@ -41,4 +39,7 @@ types: postOfficeBoxNumber: ~ postalCode: ~ streetAddress: ~ - Organization: {} + Organization: + parent: false + properties: + name: ~ diff --git a/tests/run-tests.sh b/tests/run-tests.sh index c066d09d..3b5f305a 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -9,7 +9,6 @@ rm -Rf build/ mkdir -p build/full/ build/ecommerce/ build/address-book/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml -bin/schema generate-types build/full/ # Check code CS vendor/bin/php-cs-fixer --dry-run --diff -vvv fix src/ From 75e1cc72f28cf03692cee0aa701b10f825b59a41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hubert?= Date: Wed, 26 Aug 2015 11:07:34 +0200 Subject: [PATCH 014/258] Ability to create non-schema.org fields --- .../DunglasApiAnnotationGenerator.php | 2 +- src/SchemaOrgModel/TypesGenerator.php | 164 +++++++++++------- tests/config/address-book.yml | 4 +- 3 files changed, 102 insertions(+), 68 deletions(-) diff --git a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php index 69c5b2d5..2e2e9189 100644 --- a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -35,7 +35,7 @@ public function generateClassAnnotations($className) */ public function generateFieldAnnotations($className, $fieldName) { - return 'id' === $fieldName ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; + return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; } /** diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php index 581dea70..04ba6cdd 100644 --- a/src/SchemaOrgModel/TypesGenerator.php +++ b/src/SchemaOrgModel/TypesGenerator.php @@ -119,7 +119,6 @@ public function generate($config) 'abstract' => false, ]; - $typesDefined = !empty($config['types']); $typesToGenerate = []; if (empty($config['types'])) { @@ -190,7 +189,7 @@ public function generate($config) $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; } - if ($typesDefined && $class['parent'] && !isset($config['types'][$class['parent']])) { + if (!empty($config['types']) && $class['parent'] && !isset($config['types'][$class['parent']])) { $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class['parent'], $type->localName())); } @@ -208,72 +207,15 @@ public function generate($config) continue; } - // Warn when property are not part of GoodRelations - if ($config['checkIsGoodRelations']) { - if (!$this->goodRelationsBridge->exist($property->localName())) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $property->localName(), $type->localName())); - } - } - - // Ignore or warn when properties are legacy - if (preg_match('/legacy spelling/', $property->get('rdfs:comment'))) { - if (isset($typeConfig['properties'])) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $property->localName(), $type->localName())); - } else { - $this->logger->info(sprintf('The property "%s" (type "%s") is legacy. Ignoring.', $property->localName(), $type->localName())); - continue; - } - } - - $ranges = []; - if (isset($typeConfig['properties'][$property->localName()]['range']) && $typeConfig['properties'][$property->localName()]['range']) { - $ranges[] = $typeConfig['properties'][$property->localName()]['range']; - } else { - foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { - if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { - $ranges[] = $range->localName(); - } - } - } - $numberOfRanges = count($ranges); - if ($numberOfRanges === 0) { - $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $property->localName(), $type->localName())); - } else { - if ($numberOfRanges > 1) { - $this->logger->error(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $property->localName(), $type->localName())); - } + $class = $this->generateField($config, $class, $type, $property->localName(), $property); + } - $cardinality = isset($typeConfig['properties'][$property->localName()]['cardinality']) ? $typeConfig['properties'][$property->localName()]['cardinality'] : false; - if (!$cardinality || $cardinality === CardinalitiesExtractor::CARDINALITY_UNKNOWN) { - $cardinality = $this->cardinalities[$property->localName()]; - } + // Add custom fields (non schema.org) + if (is_array($typeConfig['properties'])) { + foreach (array_diff_key($typeConfig['properties'], $class['fields']) as $propertyName => $property) { + $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->localName())); - $isArray = in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_0_N, - CardinalitiesExtractor::CARDINALITY_1_N, - CardinalitiesExtractor::CARDINALITY_N_N, - ]); - $isNullable = !in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_1_1, - CardinalitiesExtractor::CARDINALITY_1_N, - ]); - - $class['fields'][$property->localName()] = [ - 'name' => $property->localName(), - 'resource' => $property, - 'range' => $ranges[0], - 'cardinality' => $cardinality, - 'isArray' => $isArray, - 'isNullable' => $isNullable, - 'isId' => false, - ]; - if ($isArray) { - $class['hasConstructor'] = true; - - if ($config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { - $class['uses'][] = self::DOCTRINE_COLLECTION_USE; - } - } + $class = $this->generateField($config, $class, $type, $propertyName); } } @@ -313,6 +255,7 @@ public function generate($config) 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, 'isArray' => false, 'isNullable' => false, + 'isCustom' => true, 'isEnum' => false, 'isId' => true, ], @@ -532,6 +475,95 @@ private function isDateTime($type) return in_array($type, ['Date', 'DateTime', 'Time']); } + /** + * Updates generated $class with given field config. + * + * @param array $config + * @param array $class + * @param EasyRdf_Resource $type + * @param string $propertyName + * @param EasyRdf_Resource $property + * + * @return array $class + */ + private function generateField($config, $class, $type, $propertyName, $property = null) + { + $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; + $typesDefined = !empty($config['types']); + + // Warn when property are not part of GoodRelations + if ($config['checkIsGoodRelations']) { + if (!$this->goodRelationsBridge->exist($propertyName)) { + $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyName, $type->localName())); + } + } + + // Ignore or warn when properties are legacy + if (!empty($property) && preg_match('/legacy spelling/', $property->get('rdfs:comment'))) { + if (isset($typeConfig['properties'])) { + $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyName, $type->localName())); + } else { + $this->logger->info(sprintf('The property "%s" (type "%s") is legacy. Ignoring.', $propertyName, $type->localName())); + + return $class; + } + } + + $ranges = []; + if (isset($typeConfig['properties'][$propertyName]['range']) && $typeConfig['properties'][$propertyName]['range']) { + $ranges[] = $typeConfig['properties'][$propertyName]['range']; + } elseif (!empty($property)) { + foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { + if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { + $ranges[] = $range->localName(); + } + } + } + + $numberOfRanges = count($ranges); + if (0 === $numberOfRanges) { + $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyName, $type->localName())); + } else { + if ($numberOfRanges > 1) { + $this->logger->error(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); + } + + $cardinality = isset($typeConfig['properties'][$propertyName]['cardinality']) ? $typeConfig['properties'][$propertyName]['cardinality'] : false; + if (!$cardinality || $cardinality === CardinalitiesExtractor::CARDINALITY_UNKNOWN) { + $cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1; + } + + $isArray = in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_1_N, + CardinalitiesExtractor::CARDINALITY_N_N, + ]); + $isNullable = !in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_1_1, + CardinalitiesExtractor::CARDINALITY_1_N, + ]); + + $class['fields'][$propertyName] = [ + 'name' => $propertyName, + 'resource' => $property, + 'range' => $ranges[0], + 'cardinality' => $cardinality, + 'isArray' => $isArray, + 'isNullable' => $isNullable, + 'isCustom' => empty($property), + 'isId' => false, + ]; + if ($isArray) { + $class['hasConstructor'] = true; + + if ($config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { + $class['uses'][] = self::DOCTRINE_COLLECTION_USE; + } + } + } + + return $class; + } + /** * Generates field's annotations. * diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index ea96e9fc..e72f45b5 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -21,13 +21,15 @@ types: birthDate: ~ telephone: ~ email: ~ - url: ~ jobTitle: ~ # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ brand: { relationTableName: "person_brand"} memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} + # url field is a custom one without definition, it should render error + url: ~ + friends: { range: "Person", cardinality: (0..*) } PostalAddress: # Disable the generation of the class hierarchy for this type parent: false From 481c8ff361300a03b87c11dbce7792e067a3d20e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 14 Jul 2015 18:14:22 +0200 Subject: [PATCH 015/258] Revert "Read external rdfa data" --- tests/run-tests.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 3b5f305a..bd900575 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -6,7 +6,7 @@ bin/schema extract-cardinalities # Build models rm -Rf build/ -mkdir -p build/full/ build/ecommerce/ build/address-book/ +mkdir -p build/ecommerce/ build/address-book/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml From c399bbaa86288d38a946585880e1d897c2c1d470 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 17 Sep 2015 11:50:55 +0200 Subject: [PATCH 016/258] Rebanding: move to the API Platform org. --- .travis.yml | 4 +- CONTRIBUTING.md | 4 +- bin/schema | 6 +- composer.json | 12 +- composer.lock | 1774 +---------------- couscous.yml | 23 - doc/configuration.md | 349 ---- doc/getting-started.md | 749 ------- .../AbstractAnnotationGenerator.php | 200 -- .../AnnotationGeneratorInterface.php | 122 -- .../ConstraintAnnotationGenerator.php | 107 - .../DoctrineOrmAnnotationGenerator.php | 204 -- .../DunglasApiAnnotationGenerator.php | 53 - .../PhpDocAnnotationGenerator.php | 188 -- src/SchemaOrgModel/CardinalitiesExtractor.php | 106 - .../Command/DumpConfigurationCommand.php | 45 - .../Command/ExtractCardinalitiesCommand.php | 55 - .../Command/GenerateTypesCommand.php | 100 - src/SchemaOrgModel/GoodRelationsBridge.php | 154 -- src/SchemaOrgModel/TypesGenerator.php | 812 -------- .../TypesGeneratorConfiguration.php | 131 -- tests/config/address-book.yml | 8 +- website/CNAME | 1 - website/css/bootstrap.min.css | 7 - website/css/highlight.dark.css | 104 - website/css/main.css | 105 - website/default.twig | 91 - 27 files changed, 83 insertions(+), 5431 deletions(-) delete mode 100644 couscous.yml delete mode 100644 doc/configuration.md delete mode 100644 doc/getting-started.md delete mode 100644 src/SchemaOrgModel/AnnotationGenerator/AbstractAnnotationGenerator.php delete mode 100644 src/SchemaOrgModel/AnnotationGenerator/AnnotationGeneratorInterface.php delete mode 100644 src/SchemaOrgModel/AnnotationGenerator/ConstraintAnnotationGenerator.php delete mode 100644 src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php delete mode 100644 src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php delete mode 100644 src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php delete mode 100644 src/SchemaOrgModel/CardinalitiesExtractor.php delete mode 100644 src/SchemaOrgModel/Command/DumpConfigurationCommand.php delete mode 100644 src/SchemaOrgModel/Command/ExtractCardinalitiesCommand.php delete mode 100644 src/SchemaOrgModel/Command/GenerateTypesCommand.php delete mode 100644 src/SchemaOrgModel/GoodRelationsBridge.php delete mode 100644 src/SchemaOrgModel/TypesGenerator.php delete mode 100644 src/SchemaOrgModel/TypesGeneratorConfiguration.php delete mode 100644 website/CNAME delete mode 100644 website/css/bootstrap.min.css delete mode 100644 website/css/highlight.dark.css delete mode 100644 website/css/main.css delete mode 100644 website/default.twig diff --git a/.travis.yml b/.travis.yml index 73de4556..fd9c8da5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,16 +7,16 @@ cache: - $HOME/.composer/cache php: + - 5.4 - 5.5 - 5.6 + - 7.0 - nightly - hhvm - - hhvm-nightly matrix: allow_failures: - php: nightly - - php: hhvm-nightly fast_finish: true before_script: diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 781d144a..1045b771 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,8 +10,8 @@ Run the following command: `tests/run-tests.sh` ## Make a Pull Request -All Pull Requests must be open on [the GitHub project page](https://github.com/dunglas/php-schema.org-model). +All Pull Requests must be open on [the GitHub project page](https://github.com/api-platform/schema-generator). ## Going further -Read [the Symfony documentation about contributing code](http://symfony.com/doc/current/contributing/code/patches.html). +Read [the Symfony documentation about contributing code](https://symfony.com/doc/current/contributing/code/patches.html). diff --git a/bin/schema b/bin/schema index dd5172df..3f1dd939 100755 --- a/bin/schema +++ b/bin/schema @@ -16,9 +16,9 @@ if (file_exists(__DIR__ . '/../../../autoload.php')) { } use Symfony\Component\Console\Application; -use SchemaOrgModel\Command\ExtractCardinalitiesCommand; -use SchemaOrgModel\Command\DumpConfigurationCommand; -use SchemaOrgModel\Command\GenerateTypesCommand; +use ApiPlatform\SchemaGenerator\Command\ExtractCardinalitiesCommand; +use ApiPlatform\SchemaGenerator\Command\DumpConfigurationCommand; +use ApiPlatform\SchemaGenerator\Command\GenerateTypesCommand; $application = new Application(); $application->add(new ExtractCardinalitiesCommand()); diff --git a/composer.json b/composer.json index 1c662ab0..c5eecfd6 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { - "name": "dunglas/php-schema", + "name": "api-platform/schema-generator", "type": "library", "description": "Various tools to generate a data model based on Schema.org vocables", "keywords": ["schema.org", "semantic", "model", "doctrine", "symfony", "entity", "enum"], - "homepage": "http://dunglas.fr/", + "homepage": "https://api-platform.com/", "license": "MIT", "authors": [ { @@ -12,9 +12,7 @@ } ], "autoload": { - "psr-0": { - "SchemaOrgModel": "src/" - } + "psr-4": { "ApiPlatform\\SchemaGenerator\\": "src/" } }, "require": { "php": ">=5.4", @@ -30,9 +28,7 @@ }, "require-dev": { "doctrine/orm": "~2.2", - "symfony/validator": "~2.6", - "symfony/serializer": "~2.7@beta", - "dunglas/api-bundle": "dev-master" + "symfony/validator": "~2.6" }, "suggest": { "myclabs/php-enum": "For enumerations", diff --git a/composer.lock b/composer.lock index b5f2ee8c..48197c94 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "dbb82a4d5c2b8ce56c643771b1c22506", + "hash": "b2730cf76318a1d8c4c04837c4e3a54b", "packages": [ { "name": "easyrdf/easyrdf", @@ -1079,168 +1079,6 @@ ], "time": "2015-09-16 16:29:33" }, - { - "name": "doctrine/doctrine-bundle", - "version": "v1.5.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/DoctrineBundle.git", - "reference": "8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineBundle/zipball/8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01", - "reference": "8c5cedb4f2f7ebb66a963ae46ad9daa1e31cee01", - "shasum": "" - }, - "require": { - "doctrine/dbal": "~2.3", - "doctrine/doctrine-cache-bundle": "~1.0", - "jdorn/sql-formatter": "~1.1", - "php": ">=5.3.2", - "symfony/console": "~2.3|~3.0", - "symfony/doctrine-bridge": "~2.2|~3.0", - "symfony/framework-bundle": "~2.3|~3.0" - }, - "require-dev": { - "doctrine/orm": "~2.3", - "phpunit/phpunit": "~4", - "satooshi/php-coveralls": "~0.6.1", - "symfony/validator": "~2.2|~3.0", - "symfony/yaml": "~2.2|~3.0", - "twig/twig": "~1.10" - }, - "suggest": { - "doctrine/orm": "The Doctrine ORM integration is optional in the bundle.", - "symfony/web-profiler-bundle": "to use the data collector" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.5.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Bundle\\DoctrineBundle\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony DoctrineBundle", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "database", - "dbal", - "orm", - "persistence" - ], - "time": "2015-08-12 15:52:00" - }, - { - "name": "doctrine/doctrine-cache-bundle", - "version": "v1.0.1", - "target-dir": "Doctrine/Bundle/DoctrineCacheBundle", - "source": { - "type": "git", - "url": "https://github.com/doctrine/DoctrineCacheBundle.git", - "reference": "e4b6f810aa047f9cbfe41c3d6a3d7e83d7477a9d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/DoctrineCacheBundle/zipball/e4b6f810aa047f9cbfe41c3d6a3d7e83d7477a9d", - "reference": "e4b6f810aa047f9cbfe41c3d6a3d7e83d7477a9d", - "shasum": "" - }, - "require": { - "doctrine/cache": "~1.3", - "doctrine/inflector": "~1.0", - "php": ">=5.3.2", - "symfony/doctrine-bridge": "~2.2", - "symfony/framework-bundle": "~2.2", - "symfony/security": "~2.2" - }, - "require-dev": { - "instaclick/coding-standard": "~1.1", - "instaclick/object-calisthenics-sniffs": "dev-master", - "instaclick/symfony2-coding-standard": "dev-remaster", - "phpunit/phpunit": "~3.7", - "satooshi/php-coveralls": "~0.6.1", - "squizlabs/php_codesniffer": "dev-master", - "symfony/console": "~2.2", - "symfony/finder": "~2.2", - "symfony/validator": "~2.2", - "symfony/yaml": "~2.2" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Bundle\\DoctrineCacheBundle": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Symfony Community", - "homepage": "http://symfony.com/contributors" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Fabio B. Silva", - "email": "fabio.bat.silva@gmail.com" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@hotmail.com" - }, - { - "name": "Doctrine Project", - "homepage": "http://www.doctrine-project.org/" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "Symfony2 Bundle for Doctrine Cache", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "cache", - "caching" - ], - "time": "2014-11-28 09:43:36" - }, { "name": "doctrine/inflector", "version": "v1.0.1", @@ -1494,57 +1332,46 @@ "time": "2015-08-31 12:59:39" }, { - "name": "dunglas/api-bundle", - "version": "dev-master", + "name": "symfony/translation", + "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/dunglas/DunglasApiBundle.git", - "reference": "7882ec0c993e69f82cf66784f82c6b6df3ada6bf" + "url": "https://github.com/symfony/Translation.git", + "reference": "485877661835e188cd78345c6d4eef1290d17571" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/DunglasApiBundle/zipball/7882ec0c993e69f82cf66784f82c6b6df3ada6bf", - "reference": "7882ec0c993e69f82cf66784f82c6b6df3ada6bf", + "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571", + "reference": "485877661835e188cd78345c6d4eef1290d17571", "shasum": "" }, "require": { - "doctrine/doctrine-bundle": "~1.2", - "doctrine/inflector": "~1.0", - "doctrine/orm": "~2.2,>=2.2.3", - "dunglas/php-property-info": "~0.2", - "ocramius/proxy-manager": "~1.0", - "php": ">=5.5", - "phpdocumentor/reflection": "^1.0.7", - "symfony/framework-bundle": "~2.6|~3.0", - "symfony/proxy-manager-bridge": "~2.3", - "symfony/serializer": "^2.7.2|~3.0", - "symfony/validator": "~2.5|~3.0", - "willdurand/negotiation": "~1.4" + "php": ">=5.3.9" + }, + "conflict": { + "symfony/config": "<2.7" }, "require-dev": { - "behat/behat": "~3.0", - "behat/mink": "~1.5", - "behat/mink-browserkit-driver": "~1.1", - "behat/mink-extension": "~2.0", - "behat/symfony2-extension": "~2.0", - "behatch/contexts": "dev-master", - "friendsofsymfony/user-bundle": "~1.3", - "phpunit/phpunit": "~4.6", - "symfony/finder": "~2.3", - "symfony/security": "~2.7.2|~3.0" + "psr/log": "~1.0", + "symfony/config": "~2.7", + "symfony/intl": "~2.4", + "symfony/phpunit-bridge": "~2.7", + "symfony/yaml": "~2.2" }, "suggest": { - "friendsofsymfony/user-bundle": "To use the FOSUserBundle bridge." + "psr/log": "To use logging capability in translator", + "symfony/config": "", + "symfony/yaml": "" }, - "type": "symfony-bundle", + "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.7-dev" } }, "autoload": { "psr-4": { - "Dunglas\\ApiBundle\\": "" + "Symfony\\Component\\Translation\\": "" } }, "notification-url": "https://packagist.org/downloads/", @@ -1553,107 +1380,69 @@ ], "authors": [ { - "name": "Kévin Dunglas", - "email": "dunglas@gmail.com", - "homepage": "http://dunglas.fr/" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], - "description": "JSON-LD / Hydra REST API for Symfony", - "homepage": "http://api-platform.com/", - "keywords": [ - "Hydra", - "JSON-LD", - "api", - "json", - "rest" - ], - "time": "2015-09-17 07:26:14" + "description": "Symfony Translation Component", + "homepage": "https://symfony.com/", + "time": "2015-09-06 08:36:38" }, { - "name": "dunglas/php-property-info", - "version": "v0.2.1", + "name": "symfony/validator", + "version": "v2.7.4", "source": { "type": "git", - "url": "https://github.com/dunglas/php-property-info.git", - "reference": "f378ad895f64885dcfcedfd198ad5aa1b19f6c97" + "url": "https://github.com/symfony/Validator.git", + "reference": "356459a697e26274d44c608513c05c23dc1d8ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/dunglas/php-property-info/zipball/f378ad895f64885dcfcedfd198ad5aa1b19f6c97", - "reference": "f378ad895f64885dcfcedfd198ad5aa1b19f6c97", + "url": "https://api.github.com/repos/symfony/Validator/zipball/356459a697e26274d44c608513c05c23dc1d8ea7", + "reference": "356459a697e26274d44c608513c05c23dc1d8ea7", "shasum": "" }, "require": { - "php": ">=5.4" + "php": ">=5.3.9", + "symfony/translation": "~2.4" }, "require-dev": { - "doctrine/orm": "~2.3", - "phpdocumentor/reflection": "~1.0", - "phpspec/phpspec": "~2.1" + "doctrine/annotations": "~1.0", + "doctrine/cache": "~1.0", + "egulias/email-validator": "~1.2,>=1.2.1", + "symfony/config": "~2.2", + "symfony/expression-language": "~2.4", + "symfony/http-foundation": "~2.1", + "symfony/intl": "~2.4", + "symfony/phpunit-bridge": "~2.7", + "symfony/property-access": "~2.3", + "symfony/yaml": "~2.0,>=2.0.5" }, "suggest": { - "doctrine/orm": "To use Doctrine metadata", - "phpdocumentor/reflection": "To use the PHPDoc", - "symfony/validator": "To use Symfony validator metadata" - }, - "type": "library", - "autoload": { - "psr-0": { - "PropertyInfo\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Kévin Dunglas", - "email": "dunglas@gmail.com" - } - ], - "description": "Retrieve type and description of PHP properties using various sources ", - "homepage": "http://dunglas.fr/", - "keywords": [ - "doctrine", - "phpdoc", - "property", - "symfony", - "type", - "validator" - ], - "time": "2015-04-03 17:49:18" - }, - { - "name": "jdorn/sql-formatter", - "version": "v1.2.17", - "source": { - "type": "git", - "url": "https://github.com/jdorn/sql-formatter.git", - "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/jdorn/sql-formatter/zipball/64990d96e0959dff8e059dfcdc1af130728d92bc", - "reference": "64990d96e0959dff8e059dfcdc1af130728d92bc", - "shasum": "" - }, - "require": { - "php": ">=5.2.4" - }, - "require-dev": { - "phpunit/phpunit": "3.7.*" + "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", + "doctrine/cache": "For using the default cached annotation reader and metadata cache.", + "egulias/email-validator": "Strict (RFC compliant) email validation", + "symfony/config": "", + "symfony/expression-language": "For using the 2.4 Expression validator", + "symfony/http-foundation": "", + "symfony/intl": "", + "symfony/property-access": "For using the 2.4 Validator API", + "symfony/yaml": "" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3.x-dev" + "dev-master": "2.7-dev" } }, "autoload": { - "classmap": [ - "lib" - ] + "psr-4": { + "Symfony\\Component\\Validator\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1661,1449 +1450,22 @@ ], "authors": [ { - "name": "Jeremy Dorn", - "email": "jeremy@jeremydorn.com", - "homepage": "http://jeremydorn.com/" - } - ], - "description": "a PHP SQL highlighting library", - "homepage": "https://github.com/jdorn/sql-formatter/", - "keywords": [ - "highlight", - "sql" - ], - "time": "2014-01-12 16:20:24" - }, - { - "name": "nikic/php-parser", - "version": "v0.9.5", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/ef70767475434bdb3615b43c327e2cae17ef12eb", - "reference": "ef70767475434bdb3615b43c327e2cae17ef12eb", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.9-dev" - } - }, - "autoload": { - "psr-0": { - "PHPParser": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2014-07-23 18:24:17" - }, - { - "name": "ocramius/proxy-manager", - "version": "1.0.2", - "source": { - "type": "git", - "url": "https://github.com/Ocramius/ProxyManager.git", - "reference": "57e9272ec0e8deccf09421596e0e2252df440e11" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Ocramius/ProxyManager/zipball/57e9272ec0e8deccf09421596e0e2252df440e11", - "reference": "57e9272ec0e8deccf09421596e0e2252df440e11", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "zendframework/zend-code": ">2.2.5,<3.0" - }, - "require-dev": { - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "1.5.*" - }, - "suggest": { - "ocramius/generated-hydrator": "To have very fast object to array to object conversion for ghost objects", - "zendframework/zend-json": "To have the JsonRpc adapter (Remote Object feature)", - "zendframework/zend-soap": "To have the Soap adapter (Remote Object feature)", - "zendframework/zend-stdlib": "To use the hydrator proxy", - "zendframework/zend-xmlrpc": "To have the XmlRpc adapter (Remote Object feature)" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "ProxyManager\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A library providing utilities to generate, instantiate and generally operate with Object Proxies", - "homepage": "https://github.com/Ocramius/ProxyManager", - "keywords": [ - "aop", - "lazy loading", - "proxy", - "proxy pattern", - "service proxies" - ], - "time": "2015-08-09 04:28:19" - }, - { - "name": "phpdocumentor/reflection", - "version": "1.0.7", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/Reflection.git", - "reference": "fc40c3f604ac2287eb5c314174d5109b2c699372" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/Reflection/zipball/fc40c3f604ac2287eb5c314174d5109b2c699372", - "reference": "fc40c3f604ac2287eb5c314174d5109b2c699372", - "shasum": "" - }, - "require": { - "nikic/php-parser": "~0.9.4", - "php": ">=5.3.3", - "phpdocumentor/reflection-docblock": "~2.0", - "psr/log": "~1.0" - }, - "require-dev": { - "behat/behat": "~2.4", - "mockery/mockery": "~0.8", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/", - "tests/unit/", - "tests/mocks/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Reflection library to do Static Analysis for PHP Projects", - "homepage": "http://www.phpdoc.org/", - "keywords": [ - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2014-11-14 11:43:04" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "suggest": { - "dflydev/markdown": "~1.0", - "erusev/parsedown": "~1.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "phpDocumentor": [ - "src/" - ] - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "mike.vanriel@naenius.com" - } - ], - "time": "2015-02-03 12:10:50" - }, - { - "name": "symfony/asset", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/asset.git", - "reference": "290cc813d01532de9a04884f32f300b67eb3b84d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/asset/zipball/290cc813d01532de9a04884f32f300b67eb3b84d", - "reference": "290cc813d01532de9a04884f32f300b67eb3b84d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "symfony/http-foundation": "~2.4", - "symfony/phpunit-bridge": "~2.7" - }, - "suggest": { - "symfony/http-foundation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Asset\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Asset Component", - "homepage": "https://symfony.com/", - "time": "2015-08-24 07:13:45" - }, - { - "name": "symfony/debug", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Debug.git", - "reference": "726bf9651d29f53243281d0b6418cfaa5e318281" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Debug/zipball/726bf9651d29f53243281d0b6418cfaa5e318281", - "reference": "726bf9651d29f53243281d0b6418cfaa5e318281", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "psr/log": "~1.0" - }, - "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" - }, - "require-dev": { - "symfony/class-loader": "~2.2", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Debug\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Debug Component", - "homepage": "https://symfony.com/", - "time": "2015-08-29 11:12:16" - }, - { - "name": "symfony/dependency-injection", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/DependencyInjection.git", - "reference": "c0a3a97b9450d77cd8eff81c5825efb3624c255b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DependencyInjection/zipball/c0a3a97b9450d77cd8eff81c5825efb3624c255b", - "reference": "c0a3a97b9450d77cd8eff81c5825efb3624c255b", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "conflict": { - "symfony/expression-language": "<2.6" - }, - "require-dev": { - "symfony/config": "~2.2", - "symfony/expression-language": "~2.6", - "symfony/phpunit-bridge": "~2.7", - "symfony/yaml": "~2.1" - }, - "suggest": { - "symfony/config": "", - "symfony/proxy-manager-bridge": "Generate service proxies to lazy load them", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\DependencyInjection\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony DependencyInjection Component", - "homepage": "https://symfony.com/", - "time": "2015-08-24 07:16:32" - }, - { - "name": "symfony/doctrine-bridge", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/DoctrineBridge.git", - "reference": "a1c0ede6fe783f204455a3cfe867f8639afe371f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/DoctrineBridge/zipball/a1c0ede6fe783f204455a3cfe867f8639afe371f", - "reference": "a1c0ede6fe783f204455a3cfe867f8639afe371f", - "shasum": "" - }, - "require": { - "doctrine/common": "~2.3", - "php": ">=5.3.9" - }, - "require-dev": { - "doctrine/data-fixtures": "1.0.*", - "doctrine/dbal": "~2.2", - "doctrine/orm": "~2.2,>=2.2.3", - "symfony/dependency-injection": "~2.2", - "symfony/expression-language": "~2.2", - "symfony/form": "~2.7,>=2.7.1", - "symfony/http-kernel": "~2.2", - "symfony/phpunit-bridge": "~2.7", - "symfony/property-access": "~2.3", - "symfony/security": "~2.2", - "symfony/stopwatch": "~2.2", - "symfony/translation": "~2.0,>=2.0.5", - "symfony/validator": "~2.5,>=2.5.5" - }, - "suggest": { - "doctrine/data-fixtures": "", - "doctrine/dbal": "", - "doctrine/orm": "", - "symfony/form": "", - "symfony/validator": "" - }, - "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Bridge\\Doctrine\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Doctrine Bridge", - "homepage": "https://symfony.com/", - "time": "2015-09-04 20:16:46" - }, - { - "name": "symfony/framework-bundle", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/FrameworkBundle.git", - "reference": "5c2a5e8bf1f47a917714877eb17bb5b5add2796f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/FrameworkBundle/zipball/5c2a5e8bf1f47a917714877eb17bb5b5add2796f", - "reference": "5c2a5e8bf1f47a917714877eb17bb5b5add2796f", - "shasum": "" - }, - "require": { - "doctrine/annotations": "~1.0", - "php": ">=5.3.9", - "symfony/asset": "~2.7", - "symfony/config": "~2.4", - "symfony/dependency-injection": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.5", - "symfony/filesystem": "~2.3", - "symfony/http-foundation": "~2.4.9|~2.5,>=2.5.4", - "symfony/http-kernel": "~2.7", - "symfony/routing": "~2.6,>2.6.4", - "symfony/security-core": "~2.6", - "symfony/security-csrf": "~2.6", - "symfony/stopwatch": "~2.3", - "symfony/templating": "~2.1", - "symfony/translation": "~2.7" - }, - "require-dev": { - "symfony/browser-kit": "~2.4", - "symfony/class-loader": "~2.1", - "symfony/console": "~2.7", - "symfony/css-selector": "~2.0,>=2.0.5", - "symfony/dom-crawler": "~2.0,>=2.0.5", - "symfony/expression-language": "~2.6", - "symfony/finder": "~2.0,>=2.0.5", - "symfony/form": "~2.7,>=2.7.2", - "symfony/intl": "~2.3", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.0,>=2.0.5", - "symfony/security": "~2.6", - "symfony/validator": "~2.5", - "symfony/yaml": "~2.0,>=2.0.5" - }, - "suggest": { - "doctrine/cache": "For using alternative cache drivers", - "symfony/console": "For using the console commands", - "symfony/finder": "For using the translation loader and cache warmer", - "symfony/form": "For using forms", - "symfony/validator": "For using validation", - "symfony/yaml": "For using the debug:config and lint:yaml commands" - }, - "type": "symfony-bundle", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Bundle\\FrameworkBundle\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony FrameworkBundle", - "homepage": "https://symfony.com/", - "time": "2015-09-03 11:40:38" - }, - { - "name": "symfony/http-foundation", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpFoundation.git", - "reference": "7253c2041652353e71560bbd300d6256d170ddaf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpFoundation/zipball/7253c2041652353e71560bbd300d6256d170ddaf", - "reference": "7253c2041652353e71560bbd300d6256d170ddaf", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "symfony/expression-language": "~2.4", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" - }, - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony HttpFoundation Component", - "homepage": "https://symfony.com/", - "time": "2015-08-27 06:45:45" - }, - { - "name": "symfony/http-kernel", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/HttpKernel.git", - "reference": "fd9c7af92c9e3ade1327cc3af10b17731eebc4a7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/HttpKernel/zipball/fd9c7af92c9e3ade1327cc3af10b17731eebc4a7", - "reference": "fd9c7af92c9e3ade1327cc3af10b17731eebc4a7", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "psr/log": "~1.0", - "symfony/debug": "~2.6,>=2.6.2", - "symfony/event-dispatcher": "~2.6,>=2.6.7", - "symfony/http-foundation": "~2.5,>=2.5.4" - }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "symfony/browser-kit": "~2.3", - "symfony/class-loader": "~2.1", - "symfony/config": "~2.7", - "symfony/console": "~2.3", - "symfony/css-selector": "~2.0,>=2.0.5", - "symfony/dependency-injection": "~2.2", - "symfony/dom-crawler": "~2.0,>=2.0.5", - "symfony/expression-language": "~2.4", - "symfony/finder": "~2.0,>=2.0.5", - "symfony/phpunit-bridge": "~2.7", - "symfony/process": "~2.0,>=2.0.5", - "symfony/routing": "~2.2", - "symfony/stopwatch": "~2.3", - "symfony/templating": "~2.2", - "symfony/translation": "~2.0,>=2.0.5", - "symfony/var-dumper": "~2.6" - }, - "suggest": { - "symfony/browser-kit": "", - "symfony/class-loader": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "", - "symfony/finder": "", - "symfony/var-dumper": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony HttpKernel Component", - "homepage": "https://symfony.com/", - "time": "2015-09-08 14:26:39" - }, - { - "name": "symfony/proxy-manager-bridge", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/ProxyManagerBridge.git", - "reference": "d82b82d47e8d93db9dac4ed186d7f521265ed93e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/ProxyManagerBridge/zipball/d82b82d47e8d93db9dac4ed186d7f521265ed93e", - "reference": "d82b82d47e8d93db9dac4ed186d7f521265ed93e", - "shasum": "" - }, - "require": { - "ocramius/proxy-manager": "~0.4|~1.0", - "php": ">=5.3.9", - "symfony/dependency-injection": "~2.3" - }, - "require-dev": { - "symfony/config": "~2.3", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "symfony-bridge", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Bridge\\ProxyManager\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony ProxyManager Bridge", - "homepage": "https://symfony.com/", - "time": "2015-05-11 02:35:29" - }, - { - "name": "symfony/routing", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Routing.git", - "reference": "20b1378cb6efffb77ea0608232f18c8f0dd25109" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Routing/zipball/20b1378cb6efffb77ea0608232f18c8f0dd25109", - "reference": "20b1378cb6efffb77ea0608232f18c8f0dd25109", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/common": "~2.2", - "psr/log": "~1.0", - "symfony/config": "~2.7", - "symfony/expression-language": "~2.4", - "symfony/http-foundation": "~2.3", - "symfony/phpunit-bridge": "~2.7", - "symfony/yaml": "~2.0,>=2.0.5" - }, - "suggest": { - "doctrine/annotations": "For using the annotation loader", - "symfony/config": "For using the all-in-one router or any loader", - "symfony/expression-language": "For using expression matching", - "symfony/yaml": "For using the YAML loader" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Routing\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Routing Component", - "homepage": "https://symfony.com/", - "keywords": [ - "router", - "routing", - "uri", - "url" - ], - "time": "2015-08-24 07:13:45" - }, - { - "name": "symfony/security", - "version": "v2.3.32", - "target-dir": "Symfony/Component/Security", - "source": { - "type": "git", - "url": "https://github.com/symfony/Security.git", - "reference": "e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Security/zipball/e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb", - "reference": "e8a908c89e4be6db9d4b901086ae4d4e1e2c44eb", - "shasum": "" - }, - "require": { - "php": ">=5.3.3", - "symfony/event-dispatcher": "~2.2", - "symfony/http-foundation": "~2.1", - "symfony/http-kernel": "~2.1" - }, - "require-dev": { - "doctrine/common": "~2.2", - "doctrine/dbal": "~2.2", - "ircmaxell/password-compat": "~1.0", - "psr/log": "~1.0", - "symfony/form": "~2.0,>=2.0.5", - "symfony/intl": "~2.3", - "symfony/phpunit-bridge": "~2.7", - "symfony/routing": "~2.2", - "symfony/validator": "~2.2" - }, - "suggest": { - "doctrine/dbal": "to use the built-in ACL implementation", - "ircmaxell/password-compat": "", - "symfony/class-loader": "", - "symfony/finder": "", - "symfony/form": "", - "symfony/routing": "", - "symfony/validator": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.3-dev" - } - }, - "autoload": { - "psr-0": { - "Symfony\\Component\\Security\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Security Component", - "homepage": "https://symfony.com/", - "time": "2015-08-07 07:22:48" - }, - { - "name": "symfony/security-core", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/security-core.git", - "reference": "fba105731ce43dcb512ace74c82b72d042b6938c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/security-core/zipball/fba105731ce43dcb512ace74c82b72d042b6938c", - "reference": "fba105731ce43dcb512ace74c82b72d042b6938c", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "ircmaxell/password-compat": "1.0.*", - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/expression-language": "~2.6", - "symfony/http-foundation": "~2.4", - "symfony/phpunit-bridge": "~2.7", - "symfony/translation": "~2.0,>=2.0.5", - "symfony/validator": "~2.5,>=2.5.5" - }, - "suggest": { - "ircmaxell/password-compat": "For using the BCrypt password encoder in PHP <5.5", - "symfony/event-dispatcher": "", - "symfony/expression-language": "For using the expression voter", - "symfony/http-foundation": "", - "symfony/validator": "For using the user password constraint" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Security\\Core\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Security Component - Core Library", - "homepage": "https://symfony.com/", - "time": "2015-08-30 11:26:29" - }, - { - "name": "symfony/security-csrf", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/security-csrf.git", - "reference": "238d6aea56008bfeae16cb9703d52b123582288b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/security-csrf/zipball/238d6aea56008bfeae16cb9703d52b123582288b", - "reference": "238d6aea56008bfeae16cb9703d52b123582288b", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "symfony/security-core": "~2.4" - }, - "require-dev": { - "symfony/http-foundation": "~2.1", - "symfony/phpunit-bridge": "~2.7" - }, - "suggest": { - "symfony/http-foundation": "For using the class SessionTokenStorage." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Security\\Csrf\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Security Component - CSRF Library", - "homepage": "https://symfony.com/", - "time": "2015-08-24 07:13:45" - }, - { - "name": "symfony/serializer", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Serializer.git", - "reference": "baf24f86a8656eea9c80988f332e51461bfcb67f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Serializer/zipball/baf24f86a8656eea9c80988f332e51461bfcb67f", - "reference": "baf24f86a8656eea9c80988f332e51461bfcb67f", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "symfony/config": "~2.2", - "symfony/phpunit-bridge": "~2.7", - "symfony/property-access": "~2.3", - "symfony/yaml": "~2.0,>=2.0.5" - }, - "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/yaml": "For using the default YAML mapping loader." - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Serializer\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Serializer Component", - "homepage": "https://symfony.com/", - "time": "2015-08-31 16:44:53" - }, - { - "name": "symfony/templating", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Templating.git", - "reference": "cb1b7421c53642bc515bc10caa81cc097775d6a1" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Templating/zipball/cb1b7421c53642bc515bc10caa81cc097775d6a1", - "reference": "cb1b7421c53642bc515bc10caa81cc097775d6a1", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/phpunit-bridge": "~2.7" - }, - "suggest": { - "psr/log": "For using debug logging in loaders" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Templating\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Templating Component", - "homepage": "https://symfony.com/", - "time": "2015-08-30 11:26:29" - }, - { - "name": "symfony/translation", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "485877661835e188cd78345c6d4eef1290d17571" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571", - "reference": "485877661835e188cd78345c6d4eef1290d17571", - "shasum": "" - }, - "require": { - "php": ">=5.3.9" - }, - "conflict": { - "symfony/config": "<2.7" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.7", - "symfony/intl": "~2.4", - "symfony/phpunit-bridge": "~2.7", - "symfony/yaml": "~2.2" - }, - "suggest": { - "psr/log": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Translation\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Translation Component", - "homepage": "https://symfony.com/", - "time": "2015-09-06 08:36:38" - }, - { - "name": "symfony/validator", - "version": "v2.7.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/Validator.git", - "reference": "356459a697e26274d44c608513c05c23dc1d8ea7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/356459a697e26274d44c608513c05c23dc1d8ea7", - "reference": "356459a697e26274d44c608513c05c23dc1d8ea7", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "symfony/translation": "~2.4" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "egulias/email-validator": "~1.2,>=1.2.1", - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/http-foundation": "~2.1", - "symfony/intl": "~2.4", - "symfony/phpunit-bridge": "~2.7", - "symfony/property-access": "~2.3", - "symfony/yaml": "~2.0,>=2.0.5" - }, - "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "egulias/email-validator": "Strict (RFC compliant) email validation", - "symfony/config": "", - "symfony/expression-language": "For using the 2.4 Expression validator", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/property-access": "For using the 2.4 Validator API", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Validator\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" } ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", "time": "2015-09-06 08:36:38" - }, - { - "name": "willdurand/negotiation", - "version": "1.4.0", - "source": { - "type": "git", - "url": "https://github.com/willdurand/Negotiation.git", - "reference": "8a84c5956e765f432542fc52a8c6e9aff4508eb3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/8a84c5956e765f432542fc52a8c6e9aff4508eb3", - "reference": "8a84c5956e765f432542fc52a8c6e9aff4508eb3", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "psr-4": { - "Negotiation\\": "src/Negotiation" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "William DURAND", - "email": "william.durand1@gmail.com" - } - ], - "description": "Content Negotiation tools for PHP provided as a standalone library.", - "homepage": "http://williamdurand.fr/Negotiation/", - "keywords": [ - "accept", - "content", - "format", - "header", - "negotiation" - ], - "time": "2015-07-28 13:10:50" - }, - { - "name": "zendframework/zend-code", - "version": "2.5.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-code.git", - "reference": "a97ef49f82496fabc3b7379b37f6bbff925b58b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-code/zipball/a97ef49f82496fabc3b7379b37f6bbff925b58b8", - "reference": "a97ef49f82496fabc3b7379b37f6bbff925b58b8", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "zendframework/zend-eventmanager": "~2.5" - }, - "require-dev": { - "doctrine/common": ">=2.1", - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-stdlib": "~2.5", - "zendframework/zend-version": "~2.5" - }, - "suggest": { - "doctrine/common": "Doctrine\\Common >=2.1 for annotation features", - "zendframework/zend-stdlib": "Zend\\Stdlib component" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Code\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "provides facilities to generate arbitrary code using an object oriented interface", - "homepage": "https://github.com/zendframework/zend-code", - "keywords": [ - "code", - "zf2" - ], - "time": "2015-07-21 22:40:59" - }, - { - "name": "zendframework/zend-eventmanager", - "version": "2.5.2", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-eventmanager.git", - "reference": "135af03d07fd048c322259aab6611d2be290475c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-eventmanager/zipball/135af03d07fd048c322259aab6611d2be290475c", - "reference": "135af03d07fd048c322259aab6611d2be290475c", - "shasum": "" - }, - "require": { - "php": ">=5.5", - "zendframework/zend-stdlib": "~2.5" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5-dev", - "dev-develop": "2.6-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\EventManager\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-eventmanager", - "keywords": [ - "eventmanager", - "zf2" - ], - "time": "2015-07-16 19:00:49" - }, - { - "name": "zendframework/zend-stdlib", - "version": "2.6.0", - "source": { - "type": "git", - "url": "https://github.com/zendframework/zend-stdlib.git", - "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/zendframework/zend-stdlib/zipball/a35758803fc9051ec1aff43989e679b6b451b1b4", - "reference": "a35758803fc9051ec1aff43989e679b6b451b1b4", - "shasum": "" - }, - "require": { - "php": ">=5.5" - }, - "require-dev": { - "fabpot/php-cs-fixer": "1.7.*", - "phpunit/phpunit": "~4.0", - "zendframework/zend-config": "~2.5", - "zendframework/zend-eventmanager": "~2.5", - "zendframework/zend-filter": "~2.5", - "zendframework/zend-inputfilter": "~2.5", - "zendframework/zend-serializer": "~2.5", - "zendframework/zend-servicemanager": "~2.5" - }, - "suggest": { - "zendframework/zend-eventmanager": "To support aggregate hydrator usage", - "zendframework/zend-filter": "To support naming strategy hydrator usage", - "zendframework/zend-serializer": "Zend\\Serializer component", - "zendframework/zend-servicemanager": "To support hydrator plugin manager usage" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6-dev", - "dev-develop": "2.7-dev" - } - }, - "autoload": { - "psr-4": { - "Zend\\Stdlib\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "homepage": "https://github.com/zendframework/zend-stdlib", - "keywords": [ - "stdlib", - "zf2" - ], - "time": "2015-07-21 17:08:05" } ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "symfony/serializer": 10, - "dunglas/api-bundle": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/couscous.yml b/couscous.yml deleted file mode 100644 index 747f1dfe..00000000 --- a/couscous.yml +++ /dev/null @@ -1,23 +0,0 @@ -baseUrl: http://php-schema.dunglas.com - -github: - user: dunglas - repo: php-schema - -title: PHP Schema -subTitle: Generate PHP data model from Schema.org vocabulary - -menu: - items: - home: - text: Home - relativeUrl: ~ - getting-started: - text: Getting started - relativeUrl: doc/getting-started.html - configuration: - text: Configuration - relativeUrl: doc/configuration.html - github: - text: " GitHub" - absoluteUrl: http://github.com/dunglas/php-schema diff --git a/doc/configuration.md b/doc/configuration.md deleted file mode 100644 index 8bd32f48..00000000 --- a/doc/configuration.md +++ /dev/null @@ -1,349 +0,0 @@ -# Configuration - -The following options can be used in the configuration file. - -## Customizing PHP namespaces - -Namespaces of generated PHP classes can be set globally, respectively for entities, enumerations and interfaces (if used -with Doctrine Resolve Target Entity Listener option). - -Example: - -```yaml -namespaces: - entity: "Dunglas\EcommerceBundle\Entity" - enum: "Dunglas\EcommerceBundle\Enum" - interface: "Dunglas\EcommerceBundle\Model" -``` - -Namespaces can also be specified for a specific type. It will take precedence over any globally configured namespace. - -Example: - -```yaml -types: - Thing: - namespaces: - entity: "Dunglas\CoreBundle\Entity" # Namespace for the Thing entity (works for enumerations too) - interface: "Schema\Model" # Namespace of the related interface -``` - -## Forcing a field range - -Schema.org allows a property to have several types. However, the generator allows only one type by property. If not configured, -it will use the first defined type. -The `range` option is useful to set the type of a given property. It can also be used to force a type (even if not in the -Schema.org definition). - -Example: - -```yaml -types: - Brand: - properties: - logo: { range: "ImageObject" } # Force the range of the logo propery to ImageObject (can also be URL according to Schema.org) - - PostalAddress: - properties: - addressCountry: { range: "Text" } # Force the type to Text instead of Country -``` - -## Forcing a field cardinality - -The cardinality of a property is automatically guessed. The `cardinality` option allows to override the guessed value. -Supported cardinalities are: -* `(0..1)`: scalar, not required -* `(0..*)`: array, not required -* `(1..1)`: scalar, required -* `(1..*)`: array, required - -Cardinalities are enforced by the class generator, the Doctrine ORM generator and the Symfony validation generator. - -Example: - -```yaml -types: - Product: - properties: - sku: - cardinality: "(0..1)" -``` - -## Forcing a relation table name - -The relation table name between two entities is automatically guessed by Doctrine. The `relationTableName` option allows -to override the default value. - -This is useful when you need two entities to have more than one relation. - -Example: - -```yaml - Organization: - properties: - contactPoint: { range: Person, relationTableName: organization_contactPoint } - member: { range: Person, cardinality: (1..*) } ## Will be default value : organization_person -``` - -## Forcing (or disabling) a class parent - -Override the guessed class hierarchy of a given type with this option. - -Example: - -```yaml - ImageObject: - parent: Thing # Force the parent to be Thing instead of CreativeWork > MediaObject - properties: ~ - Drug: - parent: false # No parent -``` - -## Forcing a class to be abstract - -Force a class to be `abstract` (or to be not). - -Example: - -```yaml - Person: - abstract: true -``` - -## Author PHPDoc - -Add a `@author` PHPDoc annotation to class' DocBlock. - -Example: - -```yaml -author: "Kévin Dunglas " -``` - -## Disabling generators and creating custom ones - -By default, all generators except the `DunglasJsonLdApi` one are enabled. You can specify the list of generators to use -with the `generators` option. - -Example (enabling only the PHPDoc generator): - -```yaml -annotationGenerators: - - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator -``` - -You can write your generators by implementing the [AnnotationGeneratorInterface](src/SchemaOrgModel/AnnotationGenerator/AnnotationGeneratorInterface). -The [AbstractAnnotationGenerator](src/SchemaOrgModel/AnnotationGenerator/AbstractAnnotationGenerator) provides helper methods -useful when creating your own generators. - -Enabling a custom generator and the PHPDoc generator: - -```yaml -annotationGenerators: - - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - - Acme\Generators\MyGenerator -``` - -## Disabling `id` generator - -By default, the generator add a property called `id` not provided by Schema.org. This useful when using generated entity -with an ORM or an ODM. -This behavior can be disabled with the following setting: - -```yaml -generateId: false -``` - -## Disabling usage of Doctrine collection - -By default, the generator use 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. -This behavior can be disabled (to fallback to standard arrays) with the following setting: - -```yaml -doctrine: - useCollection: false -``` - -## Custom field visibility - -Generated fields have a `private` visibility and are exposed through getters and setters. -The default visibility can be changed with the `fieldVisibility` otion. - -Example: - -```yaml -fieldVisibility: "protected" -``` - -## Forcing Doctrine inheritance mapping annotation - -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 inheritance annotation can be forced for a given type like the following: - -```yaml -types: - Product: - doctrine: - inheritanceMapping: "@MappedSuperclass" -``` - -*This setting is only relevant when using the Doctrine ORM generator.* - -## Interfaces and Doctrine Resolve Target Entity Listener - -[`ResolveTargetEntityListener`](http://doctrine-orm.readthedocs.org/en/latest/cookbook/resolve-target-entity-listener.html) -is a feature of Doctrine to keep modules independent. It allows to specify interfaces and `abstract` classes in relation -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 generating the XML mapping file usable with Symfony add the following to your config file: - -```yaml -doctrine: - resolveTargetEntityConfigPath: path/to/doctrine.xml -``` - -## Custom schemas - -The generator can use your own schema definitions. They must be wrote in RDFa and follow the format of the [Schema.org's -definition](http://schema.org/docs/schema_org_rdfa.html). This is useful to document your [Schema.org extensions](http://schema.org/docs/extension.html) and use them -to generate the PHP data model of your application. - -Example: - -```yaml -rdfa: - - https://raw.githubusercontent.com/rvguha/schemaorg/master/data/schema.rdfa # Experimental version of Schema.org - - http://example.com/data/myschema.rfa # Additional types -``` - -*Support for other namespaces than `http://schema.org` is planned for future versions but not currently available.* - -## Checking GoodRelation compatibility - -If the `checkIsGoodRelations` option is set to `true`, the generator will emit a warning if an encountered property is not -par of the [GoodRelations](http://www.heppnetz.de/projects/goodrelations/) schema. - -This is useful when generating e-commerce data model. - -## PHP file header - -Prepend all generated PHP files with a custom comment. - -Example: - -```yaml -header: | - /* - * This file is part of the Ecommerce package. - * - * (c) Kévin Dunglas - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ -``` - - -## Full configuration reference - -```yaml -# RDFa files to use -rdfa: - - # Default: - - http://schema.org/docs/schema_org_rdfa.html - -# OWL relation files to use -relations: - - # Default: - - http://purl.org/goodrelations/v1.owl - -# Debug mode -debug: false - -# Automatically add an id field to entities -generateId: true - -# Generate interfaces and use Doctrine's Resolve Target Entity feature -useInterface: false - -# Emit a warning if a property is not derived from GoodRelations -checkIsGoodRelations: false - -# A license or any text to use as header of generated files -header: false # Example: // (c) Kévin Dunglas - -# PHP namespaces -namespaces: - - # The namespace of the generated entities - entity: SchemaOrg\Entity # Example: Acme\Entity - - # The namespace of the generated enumerations - enum: SchemaOrg\Enum # Example: Acme\Enum - - # The namespace of the generated interfaces - interface: SchemaOrg\Model # Example: Acme\Model - -# Doctrine -doctrine: - - # Use Doctrine's ArrayCollection instead of standard arrays - useCollection: true - - # The Resolve Target Entity Listener config file pass - resolveTargetEntityConfigPath: null - -# The value of the phpDoc's @author annotation -author: false # Example: Kévin Dunglas - -# Visibility of entities fields -fieldVisibility: ~ # One of "private"; "protected"; "public" - -# Schema.org's types to use -types: - - # Prototype - id: - - # Type namespaces - namespaces: - - # The namespace for the generated class (override any other defined namespace) - class: null - - # The namespace for the generated interface (override any other defined namespace) - interface: null - doctrine: - - # The Doctrine inheritance mapping type (override the guessed one) - inheritanceMapping: null - - # The parent class, set to false for a top level class - parent: null - - # Properties of this type to use - properties: - - # Prototype - id: - - # The property range - range: null # Example: Offer - cardinality: ~ # One of "(0..1)"; "(0..*)"; "(1..1)"; "(1..*)"; "unknown" - -# Annotation generators to use -annotationGenerators: - - # Defaults: - - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\ConstraintAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator -``` \ No newline at end of file diff --git a/doc/getting-started.md b/doc/getting-started.md deleted file mode 100644 index 14c168bc..00000000 --- a/doc/getting-started.md +++ /dev/null @@ -1,749 +0,0 @@ -# Usage - -## Installation - -Use [Composer](http://getcomposer.org) to install the generator. In standalone mode: - - composer create-project dunglas/php-schema - -Or directly as a development dependency of your project: - - composer require --dev dunglas/php-schema - -If you want to create an API exposing Schema.org types, take a look at [Dunglas's API platform](https://github.com/dunglas/api-platform), -a all-in-one skeleton including PHP Schema and integrated with a ton of other useful packages allowing to generate JSON-LD -REST API in minutes. - -## Model scaffolding - -Start by browsing [Schema.org](http://schema.org) and pick types applicable to your application. The website provides -tons of schemas including (but not limited too) representations of people, organization, event, postal address, creative -work and e-commerce structures. -Then, write a simple YAML config file like the following (here we will generate a data model for an address book): - -`address-book.yml`: - -```yml -rdfa: - - tests/data/schema.rdfa -relations: - - tests/data/v1.owl -# The PHP namespace of generated entities -namespaces: - entity: "AddressBook\Entity" -# The list of types and properties we want to use -types: - # Parent class of Person - Thing: - properties: - name: ~ - Person: - properties: - familyName: ~ - givenName: ~ - additionalName: ~ - gender: ~ - address: ~ - birthDate: ~ - telephone: ~ - email: ~ - url: ~ - jobTitle: ~ - 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" } - addressLocality: ~ - addressRegion: ~ - postOfficeBoxNumber: ~ - postalCode: ~ - streetAddress: ~ -``` - -Run the generator with this config file as parameter: - - bin/schema generate-types output-directory/ address-book.yml - -The following classes will be generated: - -`output-directory/AddressBook/Entity/Thing.php`: - -```php -name = $name; - - return $this; - } - - /** - * Gets name. - * - * @return string - */ - public function getName() - { - return $this->name; - } -} - -``` - -`output-directory/AddressBook/Entity/Person.php`: - -```php -id = $id; - - return $this; - } - - /** - * Gets id. - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Sets additionalName. - * - * @param string $additionalName - * @return $this - */ - public function setAdditionalName($additionalName) - { - $this->additionalName = $additionalName; - - return $this; - } - - /** - * Gets additionalName. - * - * @return string - */ - public function getAdditionalName() - { - return $this->additionalName; - } - - /** - * Sets address. - * - * @param PostalAddress $address - * @return $this - */ - public function setAddress(PostalAddress $address) - { - $this->address = $address; - - return $this; - } - - /** - * Gets address. - * - * @return PostalAddress - */ - public function getAddress() - { - return $this->address; - } - - /** - * Sets birthDate. - * - * @param \DateTime $birthDate - * @return $this - */ - public function setBirthDate(\DateTime $birthDate) - { - $this->birthDate = $birthDate; - - return $this; - } - - /** - * Gets birthDate. - * - * @return \DateTime - */ - public function getBirthDate() - { - return $this->birthDate; - } - - /** - * Sets email. - * - * @param string $email - * @return $this - */ - public function setEmail($email) - { - $this->email = $email; - - return $this; - } - - /** - * Gets email. - * - * @return string - */ - public function getEmail() - { - return $this->email; - } - - /** - * Sets familyName. - * - * @param string $familyName - * @return $this - */ - public function setFamilyName($familyName) - { - $this->familyName = $familyName; - - return $this; - } - - /** - * Gets familyName. - * - * @return string - */ - public function getFamilyName() - { - return $this->familyName; - } - - /** - * Sets gender. - * - * @param string $gender - * @return $this - */ - public function setGender($gender) - { - $this->gender = $gender; - - return $this; - } - - /** - * Gets gender. - * - * @return string - */ - public function getGender() - { - return $this->gender; - } - - /** - * Sets givenName. - * - * @param string $givenName - * @return $this - */ - public function setGivenName($givenName) - { - $this->givenName = $givenName; - - return $this; - } - - /** - * Gets givenName. - * - * @return string - */ - public function getGivenName() - { - return $this->givenName; - } - - /** - * Sets jobTitle. - * - * @param string $jobTitle - * @return $this - */ - public function setJobTitle($jobTitle) - { - $this->jobTitle = $jobTitle; - - return $this; - } - - /** - * Gets jobTitle. - * - * @return string - */ - public function getJobTitle() - { - return $this->jobTitle; - } - - /** - * Sets telephone. - * - * @param string $telephone - * @return $this - */ - public function setTelephone($telephone) - { - $this->telephone = $telephone; - - return $this; - } - - /** - * Gets telephone. - * - * @return string - */ - public function getTelephone() - { - return $this->telephone; - } -} - -``` - -`output-directory/AddressBook/Entity/PostalAddress.php`: - -```php -id = $id; - - return $this; - } - - /** - * Gets id. - * - * @return integer - */ - public function getId() - { - return $this->id; - } - - /** - * Sets addressCountry. - * - * @param string $addressCountry - * @return $this - */ - public function setAddressCountry($addressCountry) - { - $this->addressCountry = $addressCountry; - - return $this; - } - - /** - * Gets addressCountry. - * - * @return string - */ - public function getAddressCountry() - { - return $this->addressCountry; - } - - /** - * Sets addressLocality. - * - * @param string $addressLocality - * @return $this - */ - public function setAddressLocality($addressLocality) - { - $this->addressLocality = $addressLocality; - - return $this; - } - - /** - * Gets addressLocality. - * - * @return string - */ - public function getAddressLocality() - { - return $this->addressLocality; - } - - /** - * Sets addressRegion. - * - * @param string $addressRegion - * @return $this - */ - public function setAddressRegion($addressRegion) - { - $this->addressRegion = $addressRegion; - - return $this; - } - - /** - * Gets addressRegion. - * - * @return string - */ - public function getAddressRegion() - { - return $this->addressRegion; - } - - /** - * Sets postalCode. - * - * @param string $postalCode - * @return $this - */ - public function setPostalCode($postalCode) - { - $this->postalCode = $postalCode; - - return $this; - } - - /** - * Gets postalCode. - * - * @return string - */ - public function getPostalCode() - { - return $this->postalCode; - } - - /** - * Sets postOfficeBoxNumber. - * - * @param string $postOfficeBoxNumber - * @return $this - */ - public function setPostOfficeBoxNumber($postOfficeBoxNumber) - { - $this->postOfficeBoxNumber = $postOfficeBoxNumber; - - return $this; - } - - /** - * Gets postOfficeBoxNumber. - * - * @return string - */ - public function getPostOfficeBoxNumber() - { - return $this->postOfficeBoxNumber; - } - - /** - * Sets streetAddress. - * - * @param string $streetAddress - * @return $this - */ - public function setStreetAddress($streetAddress) - { - $this->streetAddress = $streetAddress; - - return $this; - } - - /** - * Gets streetAddress. - * - * @return string - */ - public function getStreetAddress() - { - return $this->streetAddress; - } -} - -``` - -Note that the generator take care of creating directories corresponding to the namespace structure. - -Without configuration file, the tool will build the entire Schema.org vocabulary. If no properties are specified for a given -type, all its properties will be generated. - -The generator also support enumerations generation. For subclasses of [`Enumeration`](https://schema.org/Enumeration), the -generator will automatically create a class extending the Enum type provided by [myclabs/php-enum](https://github.com/myclabs/php-enum). -Don't forget to install this library in your project. Refer you to PHP Enum documentation to see how to use it. The Symfony -validation annotation generator automatically takes care of enumerations to validate choices values. - -A config file generating an enum class: - -```yml -types: - OfferItemCondition: ~ # The generator will automatically guess that OfferItemCondition is subclass of Enum -``` - -The associated PHP class: - -```php - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\AnnotationGenerator; - -use Psr\Log\LoggerInterface; - -/** - * Abstract annotation generator. - * - * @author Kévin Dunglas - */ -abstract class AbstractAnnotationGenerator implements AnnotationGeneratorInterface -{ - /** - * @var LoggerInterface - */ - protected $logger; - /** - * @var \EasyRdf_Graph[] - */ - protected $graphs; - /** - * @var array - */ - protected $cardinalities; - /** - * @var array - */ - protected $config; - /** - * @var array - */ - protected $classes; - - /** - * {@inheritdoc} - */ - public function __construct( - LoggerInterface $logger, - array $graphs, - array $cardinalities, - array $config, - array $classes - ) { - $this->logger = $logger; - $this->graphs = $graphs; - $this->cardinalities = $cardinalities; - $this->config = $config; - $this->classes = $classes; - } - - /** - * {@inheritdoc} - */ - public function generateClassAnnotations($className) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateInterfaceAnnotations($className) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateConstantAnnotations($className, $constantName) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateFieldAnnotations($className, $fieldName) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateGetterAnnotations($className, $fieldName) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateSetterAnnotations($className, $fieldName) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateAdderAnnotations($className, $fieldName) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateRemoverAnnotations($className, $fieldName) - { - return []; - } - - /** - * {@inheritdoc} - */ - public function generateUses($className) - { - return []; - } - - /** - * Converts a Schema.org range to a PHP type. - * - * @param array $field - * @param bool $adderOrRemover - * - * @return string - */ - protected function toPhpType(array $field, $adderOrRemover = false) - { - $range = $field['range']; - - if ($field['isEnum']) { - if ($field['isArray']) { - return 'string[]'; - } else { - return 'string'; - } - } - - $data = false; - switch ($range) { - case 'Boolean': - $data = 'boolean'; - break; - case 'Date': - // No break - case 'DateTime': - // No break - case 'Time': - $data = '\DateTime'; - break; - case 'Number': - // No break - case 'Float': - $data = 'float'; - break; - case 'Integer': - $data = 'integer'; - break; - case 'Text': - // No break - case 'URL': - $data = 'string'; - break; - } - - if ($data) { - if ($field['isArray']) { - return sprintf('%s[]', $data); - } - - return $data; - } - - if (isset($this->classes[$field['range']]['interfaceName'])) { - $range = $this->classes[$field['range']]['interfaceName']; - } - - if ($field['isArray'] && !$adderOrRemover) { - if ($this->config['doctrine']['useCollection']) { - return sprintf('ArrayCollection<%s>', $range); - } - - return sprintf('%s[]', $range); - } - - return $range; - } -} diff --git a/src/SchemaOrgModel/AnnotationGenerator/AnnotationGeneratorInterface.php b/src/SchemaOrgModel/AnnotationGenerator/AnnotationGeneratorInterface.php deleted file mode 100644 index 36243123..00000000 --- a/src/SchemaOrgModel/AnnotationGenerator/AnnotationGeneratorInterface.php +++ /dev/null @@ -1,122 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\AnnotationGenerator; - -use Psr\Log\LoggerInterface; - -/** - * Annotation Generator Interface. - * - * @author Kévin Dunglas - */ -interface AnnotationGeneratorInterface -{ - /** - * @param LoggerInterface $logger - * @param \EasyRdf_Graph[] $graphs - * @param array $cardinalities - * @param array $config - * @param array $classes - */ - public function __construct( - LoggerInterface $logger, - array $graphs, - array $cardinalities, - array $config, - array $classes - ); - - /** - * Generates class' annotations. - * - * @param string $className - * - * @return array - */ - public function generateClassAnnotations($className); - - /** - * Generates interface's annotations. - * - * @param string $className - * - * @return array - */ - public function generateInterfaceAnnotations($className); - - /** - * Generates constant's annotations. - * - * @param string $className - * @param string $constantName - * - * @return array - */ - public function generateConstantAnnotations($className, $constantName); - - /** - * Generates field's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array - */ - public function generateFieldAnnotations($className, $fieldName); - - /** - * Generates getter's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array - */ - public function generateGetterAnnotations($className, $fieldName); - - /** - * Generates setter's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array - */ - public function generateSetterAnnotations($className, $fieldName); - - /** - * Generates adder's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array - */ - public function generateAdderAnnotations($className, $fieldName); - - /** - * Generates remover's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array - */ - public function generateRemoverAnnotations($className, $fieldName); - - /** - * Generates uses. - * - * @param string $className - * - * @return array - */ - public function generateUses($className); -} diff --git a/src/SchemaOrgModel/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/ConstraintAnnotationGenerator.php deleted file mode 100644 index e95c9fbe..00000000 --- a/src/SchemaOrgModel/AnnotationGenerator/ConstraintAnnotationGenerator.php +++ /dev/null @@ -1,107 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\AnnotationGenerator; - -/** - * Constraint annotation generator. - * - * @author Kévin Dunglas - */ -class ConstraintAnnotationGenerator extends AbstractAnnotationGenerator -{ - /** - * {@inheritdoc} - */ - public function generateFieldAnnotations($className, $fieldName) - { - $field = $this->classes[$className]['fields'][$fieldName]; - - if ($field['isId']) { - return []; - } - - $asserts = []; - if (!$field['isArray']) { - switch ($field['range']) { - case 'URL': - $asserts[] = '@Assert\Url'; - break; - - case 'Date': - $asserts[] = '@Assert\Date'; - break; - - case 'DateTime': - $asserts[] = '@Assert\DateTime'; - break; - - case 'Time': - $asserts[] = '@Assert\Time'; - break; - } - - if (isset($field['resource']) && 'email' === $field['resource']->localName()) { - $asserts[] = '@Assert\Email'; - } - - if (!$asserts) { - $phpType = $this->toPhpType($field); - if (in_array($phpType, ['boolean', 'float', 'integer', 'string'])) { - $asserts[] = sprintf('@Assert\Type(type="%s")', $phpType); - } - } - } - - if (!$field['isNullable']) { - $asserts[] = '@Assert\NotNull'; - } - - if ($field['isEnum']) { - $assert = sprintf('@Assert\Choice(callback={"%s", "toArray"}', $field['range']); - - if ($field['isArray']) { - $assert .= ', multiple=true'; - } - - $assert .= ')'; - - $asserts[] = $assert; - } - - return $asserts; - } - - /** - * {@inheritdoc} - */ - public function generateUses($className) - { - if ($this->classes[$className]['isEnum']) { - return []; - } - - $uses = []; - $uses[] = 'Symfony\Component\Validator\Constraints as Assert'; - - foreach ($this->classes[$className]['fields'] as $field) { - if ($field['isEnum']) { - $enumClass = $this->classes[$field['range']]; - $enumNamespace = isset($enumClass['namespaces']['class']) && $enumClass['namespaces']['class'] ? $enumClass['namespaces']['class'] : $this->config['namespaces']['enum']; - $use = sprintf('%s\%s', $enumNamespace, $field['range']); - - if (!in_array($use, $uses)) { - $uses[] = $use; - } - } - } - - return $uses; - } -} diff --git a/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php deleted file mode 100644 index fbcf9765..00000000 --- a/src/SchemaOrgModel/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ /dev/null @@ -1,204 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\AnnotationGenerator; - -use SchemaOrgModel\CardinalitiesExtractor; -use SchemaOrgModel\TypesGenerator; - -/** - * Doctrine annotation generator. - * - * @author Kévin Dunglas - */ -class DoctrineOrmAnnotationGenerator extends AbstractAnnotationGenerator -{ - /** - * {@inheritdoc} - */ - public function generateClassAnnotations($className) - { - $class = $this->classes[$className]; - - if ($class['isEnum']) { - return []; - } - - if (isset($this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping'])) { - $inheritanceMapping = $this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping']; - } else { - $inheritanceMapping = $class['abstract'] ? '@ORM\MappedSuperclass' : '@ORM\Entity'; - } - - return [ - '', - $inheritanceMapping, - ]; - } - - /** - * {@inheritdoc} - */ - public function generateFieldAnnotations($className, $fieldName) - { - $this->classes[$className]; - $field = $this->classes[$className]['fields'][$fieldName]; - - $field['relationTableName'] = null; - if (!$field['isId'] && isset($this->config['types'][$className]['properties'][$fieldName])) { - $field['relationTableName'] = $this->config['types'][$className]['properties'][$fieldName]['relationTableName']; - } - $annotations = []; - - if ($field['isEnum']) { - if ($field['isArray']) { - $type = 'simple_array'; - } else { - $type = 'string'; - } - } else { - switch ($field['range']) { - case 'Boolean': - $type = 'boolean'; - break; - case 'Date': - $type = 'date'; - break; - case 'DateTime': - $type = 'datetime'; - break; - case 'Time': - $type = 'time'; - break; - case 'Number': - // No break - case 'Float': - $type = 'float'; - break; - case 'Integer': - $type = 'integer'; - break; - case 'Text': - // No break - case 'URL': - $type = 'string'; - break; - } - } - - if (isset($type)) { - $annotation = '@ORM\Column'; - - if ($field['isArray']) { - $type = 'simple_array'; - } - - if ($type !== 'string' || $field['isNullable']) { - $annotation .= '('; - } - - if ($type !== 'string') { - $annotation .= sprintf('type="%s"', $type); - } - - if ($type !== 'string' && $field['isNullable']) { - $annotation .= ', '; - } - - if ($field['isNullable']) { - $annotation .= 'nullable=true'; - } - - if ($type !== 'string' || $field['isNullable']) { - $annotation .= ')'; - } - - $annotations[] = $annotation; - } else { - switch ($field['cardinality']) { - case CardinalitiesExtractor::CARDINALITY_0_1: - $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $this->getRelationName($field['range'])); - break; - - case CardinalitiesExtractor::CARDINALITY_1_1: - $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $this->getRelationName($field['range'])); - $annotations[] = '@ORM\JoinColumn(nullable=false)'; - break; - - case CardinalitiesExtractor::CARDINALITY_UNKNOWN: - // No break - case CardinalitiesExtractor::CARDINALITY_N_0: - $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $this->getRelationName($field['range'])); - break; - - case CardinalitiesExtractor::CARDINALITY_N_1: - $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $this->getRelationName($field['range'])); - $annotations[] = '@ORM\JoinColumn(nullable=false)'; - break; - - case CardinalitiesExtractor::CARDINALITY_0_N: - $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; - $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; - break; - - case CardinalitiesExtractor::CARDINALITY_1_N: - $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; - $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; - break; - - case CardinalitiesExtractor::CARDINALITY_N_N: - $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); - if ($field['relationTableName']) { - $annotations[] = sprintf('@ORM\JoinTable(name="%s")', $field['relationTableName']); - } - break; - } - } - - if ($field['isId']) { - $annotations[] = '@ORM\Id'; - $annotations[] = '@ORM\GeneratedValue(strategy="AUTO")'; - } - - return $annotations; - } - - /** - * {@inheritdoc} - */ - public function generateUses($className) - { - $resource = $this->classes[$className]['resource']; - - $subClassOf = $resource->get('rdfs:subClassOf'); - $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; - - return $typeIsEnum ? [] : ['Doctrine\ORM\Mapping as ORM']; - } - - /** - * Gets class or interface name to use in relations. - * - * @param string $range - * - * @return string - */ - private function getRelationName($range) - { - $class = $this->classes[$range]; - - if (isset($class['interfaceName'])) { - return $class['interfaceName']; - } - - return $class['name']; - } -} diff --git a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php deleted file mode 100644 index 2e2e9189..00000000 --- a/src/SchemaOrgModel/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ /dev/null @@ -1,53 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\AnnotationGenerator; - -use SchemaOrgModel\TypesGenerator; - -/** - * Generates Iri annotations provided by DunglasApiBundle. - * - * @author Kévin Dunglas - * - * @link https://github.com/dunglas/DunglasApiBundle - */ -class DunglasApiAnnotationGenerator extends AbstractAnnotationGenerator -{ - /** - * {@inheritdoc} - */ - public function generateClassAnnotations($className) - { - $resource = $this->classes[$className]['resource']; - - return [sprintf('@Iri("%s")', $resource->getUri())]; - } - - /** - * {@inheritdoc} - */ - public function generateFieldAnnotations($className, $fieldName) - { - return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; - } - - /** - * {@inheritdoc} - */ - public function generateUses($className) - { - $resource = $this->classes[$className]['resource']; - - $subClassOf = $resource->get('rdfs:subClassOf'); - $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; - - return $typeIsEnum ? [] : ['Dunglas\ApiBundle\Annotation\Iri']; - } -} diff --git a/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php deleted file mode 100644 index 11931525..00000000 --- a/src/SchemaOrgModel/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ /dev/null @@ -1,188 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\AnnotationGenerator; - -/** - * PHPDoc annotation generator. - * - * @author Kévin Dunglas - */ -class PhpDocAnnotationGenerator extends AbstractAnnotationGenerator -{ - const INDENT = ' '; - - /** - * {@inheritdoc} - */ - public function generateClassAnnotations($className) - { - return $this->generateDoc($className); - } - - /** - * {@inheritdoc} - */ - public function generateInterfaceAnnotations($className) - { - return $this->generateDoc($className, true); - } - - /** - * {@inheritdoc} - */ - public function generateConstantAnnotations($className, $constantName) - { - $resource = $this->classes[$className]['constants'][$constantName]['resource']; - - $annotations = $this->formatDoc($resource->get('rdfs:comment'), true); - $annotations[0] = sprintf( - '@var string %s', - $annotations[0] - ); - - return $annotations; - } - - /** - * {@inheritdoc} - */ - public function generateFieldAnnotations($className, $fieldName) - { - $field = $this->classes[$className]['fields'][$fieldName]; - $comment = $field['resource'] ? $field['resource']->get('rdfs:comment') : ''; - - $annotations = $this->formatDoc($comment, true); - $annotations[0] = sprintf( - '@var %s %s', - $this->toPhpType($field), - $annotations[0] - ); - $annotations[] = ''; - - return $annotations; - } - - /** - * {@inheritdoc} - */ - public function generateGetterAnnotations($className, $fieldName) - { - return [ - sprintf('Gets %s.', $fieldName), - '', - sprintf('@return %s', $this->toPhpType($this->classes[$className]['fields'][$fieldName])), - ]; - } - - /** - * {@inheritdoc} - */ - public function generateSetterAnnotations($className, $fieldName) - { - return [ - sprintf('Sets %s.', $fieldName), - '', - sprintf( - '@param %s $%s', - $this->toPhpType($this->classes[$className]['fields'][$fieldName]), - $fieldName - ), - '', - '@return $this', - ]; - } - - /** - * {@inheritdoc} - */ - public function generateAdderAnnotations($className, $fieldName) - { - return [ - sprintf('Adds %s.', $fieldName), - '', - sprintf( - '@param %s $%s', - $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), - $fieldName - ), - '', - '@return $this', - ]; - } - - /** - * {@inheritdoc} - */ - public function generateRemoverAnnotations($className, $fieldName) - { - return [ - sprintf('Removes %s.', $fieldName), - '', - sprintf( - '@param %s $%s', - $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), - $fieldName - ), - '', - '@return $this', - ]; - } - - /** - * Generates class or interface PHPDoc. - * - * @param string $className - * @param bool $interface - * - * @return array - */ - private function generateDoc($className, $interface = false) - { - $resource = $this->classes[$className]['resource']; - $annotations = []; - - if (!$interface && isset($this->classes[$className]['interfaceName'])) { - $annotations[] = '{@inheritdoc}'; - $annotations[] = ''; - } else { - $annotations = $this->formatDoc($resource->get('rdfs:comment')); - $annotations[] = ''; - $annotations[] = sprintf('@see %s %s', $resource->getUri(), 'Documentation on Schema.org'); - } - - if ($this->config['author']) { - $annotations[] = sprintf('@author %s', $this->config['author']); - } - - return $annotations; - } - - /** - * Converts HTML to Markdown and explode. - * - * @param string $doc - * @param bool $indent - * - * @return array - */ - private function formatDoc($doc, $indent = false) - { - $doc = explode("\n", (new \HTML_To_Markdown($doc))->output()); - - if ($indent) { - $count = count($doc); - for ($i = 1; $i < $count; ++$i) { - $doc[$i] = self::INDENT.$doc[$i]; - } - } - - return $doc; - } -} diff --git a/src/SchemaOrgModel/CardinalitiesExtractor.php b/src/SchemaOrgModel/CardinalitiesExtractor.php deleted file mode 100644 index bfd742e5..00000000 --- a/src/SchemaOrgModel/CardinalitiesExtractor.php +++ /dev/null @@ -1,106 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel; - -/** - * Cardinality extractor. - * - * @author Kévin Dunglas - */ -class CardinalitiesExtractor -{ - const CARDINALITY_0_1 = '(0..1)'; - const CARDINALITY_0_N = '(0..*)'; - const CARDINALITY_1_1 = '(1..1)'; - const CARDINALITY_1_N = '(1..*)'; - const CARDINALITY_N_0 = '(*..0)'; - const CARDINALITY_N_1 = '(*..1)'; - const CARDINALITY_N_N = '(*..*)'; - const CARDINALITY_UNKNOWN = 'unknown'; - - /** - * @var \EasyRdf_Graph[] - */ - private $graphs; - /** - * @var GoodRelationsBridge - */ - private $goodRelationsBridge; - - /** - * @param \EasyRdf_Graph[] $graphs - * @param GoodRelationsBridge $goodRelationsBridge - */ - public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBridge) - { - $this->graphs = $graphs; - $this->goodRelationsBridge = $goodRelationsBridge; - } - - /** - * Extracts cardinality of properties. - * - * @return array - */ - public function extract() - { - $properties = []; - - foreach ($this->graphs as $graph) { - foreach ($graph->allOfType('rdf:Property') as $property) { - $properties[$property->localName()] = $this->extractForProperty($property); - } - } - - return $properties; - } - - /** - * Extracts the cardinality of a property. - * - * Based on [Geraint Luff work](https://github.com/geraintluff/schema-org-gen). - * - * @param \EasyRdf_Resource $property - * - * @return string The cardinality - */ - private function extractForProperty(\EasyRdf_Resource $property) - { - $localName = $property->localName(); - $fromGoodRelations = $this->goodRelationsBridge->extractCardinality($localName); - if ($fromGoodRelations) { - return $fromGoodRelations; - } - - $comment = $property->get('rdfs:comment')->getValue(); - - if ( - // http://schema.org/acceptedOffer, http://schema.org/acceptedPaymentMethod, http://schema.org/exerciseType - preg_match('/\(s\)/', $comment) - || - // http://schema.org/follows - preg_match('/^The most generic uni-directional social relation./', $comment) - || - preg_match('/one or more/i', $comment) - ) { - return self::CARDINALITY_0_N; - } - - if ( - preg_match('/^is/', $localName) - || - preg_match('/^The /', $comment) - ) { - return self::CARDINALITY_0_1; - } - - return self::CARDINALITY_UNKNOWN; - } -} diff --git a/src/SchemaOrgModel/Command/DumpConfigurationCommand.php b/src/SchemaOrgModel/Command/DumpConfigurationCommand.php deleted file mode 100644 index c0e6e09b..00000000 --- a/src/SchemaOrgModel/Command/DumpConfigurationCommand.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\Command; - -use SchemaOrgModel\TypesGeneratorConfiguration; -use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Dump configuration command. - * - * @author Kévin Dunglas - */ -class DumpConfigurationCommand extends Command -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('dump-configuration') - ->setDescription('Dump configuration') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $configuration = new TypesGeneratorConfiguration(); - $dumper = new YamlReferenceDumper(); - $output->writeln($dumper->dump($configuration)); - } -} diff --git a/src/SchemaOrgModel/Command/ExtractCardinalitiesCommand.php b/src/SchemaOrgModel/Command/ExtractCardinalitiesCommand.php deleted file mode 100644 index 40912611..00000000 --- a/src/SchemaOrgModel/Command/ExtractCardinalitiesCommand.php +++ /dev/null @@ -1,55 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\Command; - -use SchemaOrgModel\CardinalitiesExtractor; -use SchemaOrgModel\TypesGeneratorConfiguration; -use SchemaOrgModel\GoodRelationsBridge; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Output\OutputInterface; - -/** - * Extract cardinality command. - * - * @author Kévin Dunglas - */ -class ExtractCardinalitiesCommand extends Command -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('extract-cardinalities') - ->setDescription('Extract properties\' cardinality') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $relations = []; - $schemaOrg = new \EasyRdf_Graph(); - $schemaOrg->load(TypesGeneratorConfiguration::SCHEMA_ORG_RDFA_URL, 'rdfa'); - $relations[] = $schemaOrg; - - $goodRelations = [new \SimpleXMLElement(TypesGeneratorConfiguration::GOOD_RELATIONS_OWL_URL, 0, true)]; - - $goodRelationsBridge = new GoodRelationsBridge($goodRelations); - $cardinalitiesExtractor = new CardinalitiesExtractor($relations, $goodRelationsBridge); - $result = $cardinalitiesExtractor->extract(); - - $output->writeln(json_encode($result, JSON_PRETTY_PRINT)); - } -} diff --git a/src/SchemaOrgModel/Command/GenerateTypesCommand.php b/src/SchemaOrgModel/Command/GenerateTypesCommand.php deleted file mode 100644 index 9335ac16..00000000 --- a/src/SchemaOrgModel/Command/GenerateTypesCommand.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel\Command; - -use SchemaOrgModel\TypesGenerator; -use SchemaOrgModel\TypesGeneratorConfiguration; -use SchemaOrgModel\GoodRelationsBridge; -use SchemaOrgModel\CardinalitiesExtractor; -use Symfony\Component\Console\Command\Command; -use Symfony\Component\Console\Input\InputArgument; -use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Logger\ConsoleLogger; -use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Config\Definition\Processor; -use Symfony\Component\Yaml\Parser; - -/** - * Generate entities command. - * - * @author Kévin Dunglas - */ -class GenerateTypesCommand extends Command -{ - /** - * {@inheritdoc} - */ - protected function configure() - { - $this - ->setName('generate-types') - ->setDescription('Generate types') - ->addArgument('output', InputArgument::REQUIRED, 'The output directory') - ->addArgument('config', InputArgument::OPTIONAL, 'The config file to use') - ; - } - - /** - * {@inheritdoc} - */ - protected function execute(InputInterface $input, OutputInterface $output) - { - $configArgument = $input->getArgument('config'); - if ($configArgument) { - $parser = new Parser(); - $config = $parser->parse(file_get_contents($configArgument)); - unset($parser); - } else { - $config = []; - } - - $processor = new Processor(); - $configuration = new TypesGeneratorConfiguration(); - $processedConfiguration = $processor->processConfiguration($configuration, [$config]); - $processedConfiguration['output'] = realpath($input->getArgument('output')); - if (!$processedConfiguration['output']) { - throw new \RuntimeException('The specified output is invalid'); - } - - $graphs = []; - foreach ($processedConfiguration['rdfa'] as $rdfa) { - $graph = new \EasyRdf_Graph(); - if ('http://' === substr($rdfa, 0, 7) || 'https://' === substr($rdfa, 0, 8)) { - $graph->load($rdfa, 'rdfa'); - } else { - $graph->parseFile($rdfa); - } - - $graphs[] = $graph; - } - - $relations = []; - foreach ($processedConfiguration['relations'] as $relation) { - $relations[] = new \SimpleXMLElement($relation, 0, true); - } - - $goodRelationsBridge = new GoodRelationsBridge($relations); - $cardinalitiesExtractor = new CardinalitiesExtractor($graphs, $goodRelationsBridge); - - $ucfirstFilter = new \Twig_SimpleFilter('ucfirst', 'ucfirst'); - $loader = new \Twig_Loader_Filesystem(__DIR__.'/../../../templates/'); - $twig = new \Twig_Environment($loader, ['autoescape' => false, 'debug' => $processedConfiguration['debug']]); - $twig->addFilter($ucfirstFilter); - - if ($processedConfiguration['debug']) { - $twig->addExtension(new \Twig_Extension_Debug()); - } - - $logger = new ConsoleLogger($output); - - $entitiesGenerator = new TypesGenerator($twig, $logger, $graphs, $cardinalitiesExtractor, $goodRelationsBridge); - $entitiesGenerator->generate($processedConfiguration); - } -} diff --git a/src/SchemaOrgModel/GoodRelationsBridge.php b/src/SchemaOrgModel/GoodRelationsBridge.php deleted file mode 100644 index 81201d05..00000000 --- a/src/SchemaOrgModel/GoodRelationsBridge.php +++ /dev/null @@ -1,154 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel; - -/** - * Schema.org to GoodRelations bridge. - * - * @author Kévin Dunglas - */ -class GoodRelationsBridge -{ - const GOOD_RELATIONS_NAMESPACE = 'http://purl.org/goodrelations/v1#'; - const RDF_SCHEMA_NAMESPACE = 'http://www.w3.org/2000/01/rdf-schema#'; - - /** - * @var \SimpleXMLElement[] - */ - protected $relations; - - /** - * @var array - */ - protected static $objectPropertiesTable = [ - 'priceSpecification' => 'hasPriceSpecification', - 'businessFunction' => 'hasBusinessFunction', - 'eligibleCustomerType' => 'eligibleCustomerTypes', - 'manufacturer' => 'hasManufacturer', - 'warrantyScope' => 'hasWarrantyScope', - 'inventoryLevel' => 'hasInventoryLevel', - 'dayOfWeek' => 'hasOpeningHoursDayOfWeek', - 'brand' => 'hasBrand', - 'itemOffered' => 'includes', - 'makesOffer' => 'offers', - 'availableDeliveryMethod' => 'availableDeliveryMethods', - 'openingHoursSpecification' => 'hasOpeningHoursSpecification', - 'eligibleQuantity' => 'hasEligibleQuantity', - 'warranty' => 'hasWarrantyPromise', - 'acceptedPaymentMethod' => 'acceptedPaymentMethods', - ]; - /** - * @var array - */ - protected static $datatypePropertiesTable = [ - 'minPrice' => 'hasMinCurrencyValue', - 'unitCode' => 'hasUnitOfMeasurement', - 'isicV4' => 'hasISICv4', - 'gtin8' => 'hasGTIN-8', - 'maxPrice' => 'hasMaxCurrencyValue', - 'gtin14' => 'hasGTIN-14', - 'maxValue' => 'hasMaxValue', - 'mpn' => 'hasMPN', - 'value' => 'hasValue', - 'model' => 'hasMakeAndModel', - 'gtin13' => 'hasEAN_UCC-13', - 'globalLocationNumber' => 'hasGlobalLocationNumber', - 'naics' => 'hasNAICS', - 'priceCurrency' => 'hasCurrency', - 'sku' => 'hasStockKeepingUnit', - 'duns' => 'hasDUNS', - 'minValue' => 'hasMinValue', - 'eligibleRegion' => 'eligibleRegions', - ]; - - /** - * @param \SimpleXMLElement[] $relations - */ - public function __construct(array $relations) - { - $this->relations = $relations; - - foreach ($this->relations as $relation) { - $relation->registerXPathNamespace('rdfs', static::RDF_SCHEMA_NAMESPACE); - } - } - - /** - * Checks if a property exists in GoodRelations. - * - * @param string $id - * - * @return bool - */ - public function exist($id) - { - foreach ($this->relations as $relation) { - $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]', static::getPropertyUrl($id))); - if (!empty($result)) { - return true; - } - } - - return false; - } - - /** - * Extracts cardinality from the Good Relations OWL. - * - * @param string $id - * - * @return string|bool - */ - public function extractCardinality($id) - { - foreach ($this->relations as $relation) { - $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', static::getPropertyUrl($id))); - if (count($result)) { - preg_match('/\(.\.\..\)/', $result[0]->asXML(), $matches); - - return $matches[0]; - } - } - - return false; - } - - /** - * Converts Schema.org's id to Good Relations id. - * - * @param string $id - * - * @return string - */ - private static function convertPropertyId($id) - { - if (isset(static::$datatypePropertiesTable[$id])) { - return static::$datatypePropertiesTable[$id]; - } - - if (isset(static::$objectPropertiesTable[$id])) { - return static::$objectPropertiesTable[$id]; - } - - return $id; - } - - /** - * Gets a property URL. - * - * @param string $id - * - * @return string - */ - private static function getPropertyUrl($id) - { - return sprintf('%s%s', static::GOOD_RELATIONS_NAMESPACE, static::convertPropertyId($id)); - } -} diff --git a/src/SchemaOrgModel/TypesGenerator.php b/src/SchemaOrgModel/TypesGenerator.php deleted file mode 100644 index 04ba6cdd..00000000 --- a/src/SchemaOrgModel/TypesGenerator.php +++ /dev/null @@ -1,812 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel; - -use Psr\Log\LoggerInterface; -use Symfony\CS\Config\Config; -use Symfony\CS\ConfigurationResolver; -use Symfony\CS\Fixer; - -/** - * Entities generator. - * - * @author Kévin Dunglas - */ -class TypesGenerator -{ - /** - * @var string - * - * @see https://github.com/myclabs/php-enum Used enum implementation - */ - const ENUM_USE = 'MyCLabs\Enum\Enum'; - /** - * @var string - * - * @see https://github.com/doctrine/collections - */ - const DOCTRINE_COLLECTION_USE = 'Doctrine\Common\Collections\ArrayCollection'; - /** - * @var string - * - * @see https://github.com/myclabs/php-enum Used enum implementation - */ - const ENUM_EXTENDS = 'Enum'; - /** - * @var string - */ - const SCHEMA_ORG_NAMESPACE = 'http://schema.org/'; - /** - * @var string - */ - const SCHEMA_ORG_ENUMERATION = 'http://schema.org/Enumeration'; - /** - * @var string - */ - const SCHEMA_ORG_DOMAIN = 'schema:domainIncludes'; - /** - * @var string - */ - const SCHEMA_ORG_RANGE = 'schema:rangeIncludes'; - - /** - * @var \Twig_Environment - */ - private $twig; - /** - * @var LoggerInterface - */ - private $logger; - /** - * @var \EasyRdf_Graph[] - */ - private $graphs; - /** - * @var CardinalitiesExtractor - */ - private $cardinalitiesExtractor; - /** - * @var GoodRelationsBridge - */ - private $goodRelationsBridge; - /** - * @var array - */ - private $cardinalities; - - /** - * @param \Twig_Environment $twig - * @param LoggerInterface $logger - * @param \EasyRdf_Graph[] $graphs - * @param CardinalitiesExtractor $cardinalitiesExtractor - * @param GoodRelationsBridge $goodRelationsBridge - */ - public function __construct( - \Twig_Environment $twig, - LoggerInterface $logger, - array $graphs, - CardinalitiesExtractor $cardinalitiesExtractor, - GoodRelationsBridge $goodRelationsBridge - ) { - $this->twig = $twig; - $this->logger = $logger; - $this->graphs = $graphs; - $this->cardinalitiesExtractor = $cardinalitiesExtractor; - $this->goodRelationsBridge = $goodRelationsBridge; - - $this->cardinalities = $this->cardinalitiesExtractor->extract(); - } - - /** - * Generates files. - */ - public function generate($config) - { - $baseClass = [ - 'constants' => [], - 'fields' => [], - 'uses' => [], - 'hasConstructor' => false, - 'parentHasConstructor' => false, - 'hasChild' => false, - 'abstract' => false, - ]; - - $typesToGenerate = []; - - if (empty($config['types'])) { - foreach ($this->graphs as $graph) { - $typesToGenerate = $graph->allOfType('rdfs:Class'); - } - } else { - foreach ($config['types'] as $key => $value) { - $resource = null; - foreach ($this->graphs as $graph) { - $resources = $graph->resources(); - - if (isset($resources[self::SCHEMA_ORG_NAMESPACE.$key])) { - $resource = $graph->resource(self::SCHEMA_ORG_NAMESPACE.$key, 'rdfs:Class'); - break; - } - } - - if ($resource) { - $typesToGenerate[] = $resource; - } else { - $this->logger->critical('Type "{key}" cannot be found.', ['key' => $key]); - } - } - } - - $classes = []; - $propertiesMap = $this->createPropertiesMap($typesToGenerate); - - foreach ($typesToGenerate as $type) { - $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; - $class = $baseClass; - - $class['name'] = $type->localName(); - $class['label'] = $type->get('rdfs:comment')->getValue(); - $class['resource'] = $type; - $class['config'] = $typeConfig; - - $class['isEnum'] = $this->isEnum($type); - if ($class['isEnum']) { - $class['namespace'] = isset($typeConfig['namespace']) ? $typeConfig['namespace'] : $config['namespaces']['enum']; - $class['parent'] = self::ENUM_EXTENDS; - $class['uses'][] = self::ENUM_USE; - - // Constants - foreach ($this->graphs as $graph) { - foreach ($graph->allOfType($type->getUri()) as $instance) { - $class['constants'][$instance->localName()] = [ - 'name' => strtoupper(substr(preg_replace('/([A-Z])/', '_$1', $instance->localName()), 1)), - 'resource' => $instance, - 'value' => $instance->getUri(), - ]; - } - } - } else { - // Entities - $class['namespace'] = isset($typeConfig['namespaces']['class']) ? $typeConfig['namespaces']['class'] : $config['namespaces']['entity']; - - // Parent - $class['parent'] = isset($typeConfig['parent']) ? $typeConfig['parent'] : null; - if (null === $class['parent']) { - $numberOfSupertypes = count($type->all('rdfs:subClassOf')); - - if ($numberOfSupertypes > 1) { - $this->logger->error(sprintf('The type "%s" has several supertypes. Using the first one.', $type->localName())); - } - - $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; - } - - if (!empty($config['types']) && $class['parent'] && !isset($config['types'][$class['parent']])) { - $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class['parent'], $type->localName())); - } - - // Interfaces - if ($config['useInterface']) { - $class['interfaceNamespace'] = isset($typeConfig['namespaces']['interface']) && $typeConfig['namespaces']['interface'] ? $typeConfig['namespaces']['interface'] : $config['namespaces']['interface']; - $class['interfaceName'] = sprintf('%sInterface', $type->localName()); - } - } - - // Fields - foreach ($propertiesMap[$type->getUri()] as $property) { - // Ignore properties not set if using a config file - if (is_array($typeConfig['properties']) && !isset($typeConfig['properties'][$property->localName()])) { - continue; - } - - $class = $this->generateField($config, $class, $type, $property->localName(), $property); - } - - // Add custom fields (non schema.org) - if (is_array($typeConfig['properties'])) { - foreach (array_diff_key($typeConfig['properties'], $class['fields']) as $propertyName => $property) { - $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->localName())); - - $class = $this->generateField($config, $class, $type, $propertyName); - } - } - - $classes[$type->localName()] = $class; - } - - // Second pass - foreach ($classes as &$class) { - if ($class['parent'] && isset($classes[$class['parent']])) { - $classes[$class['parent']]['hasChild'] = true; - $class['parentHasConstructor'] = $classes[$class['parent']]['hasConstructor']; - } - - foreach ($class['fields'] as &$field) { - $field['isEnum'] = isset($classes[$field['range']]) && $classes[$field['range']]['isEnum']; - } - } - - // Third pass - foreach ($classes as &$class) { - if (isset($config['types'][$class['name']]['abstract']) && null !== $config['types'][$class['name']]['abstract']) { - $class['abstract'] = $config['types'][$class['name']]['abstract']; - } else { - $class['abstract'] = $class['hasChild']; - } - } - - // Generate ID - if ($config['generateId']) { - foreach ($classes as &$class) { - if (!$class['hasChild'] && !$class['isEnum']) { - $class['fields'] = [ - 'id' => [ - 'name' => 'id', - 'resource' => null, - 'range' => 'Integer', - 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, - 'isArray' => false, - 'isNullable' => false, - 'isCustom' => true, - 'isEnum' => false, - 'isId' => true, - ], - ] + $class['fields']; - } - } - } - - // Initialize annotation generators - $annotationGenerators = []; - foreach ($config['annotationGenerators'] as $annotationGenerator) { - $generator = new $annotationGenerator($this->logger, $this->graphs, $this->cardinalities, $config, $classes); - - $annotationGenerators[] = $generator; - } - - if (isset($class['interfaceNamespace']) && $config['doctrine']['resolveTargetEntityConfigPath']) { - $interfaceMappings = []; - } - - $generatedFiles = []; - foreach ($classes as $className => &$class) { - $class['uses'] = $this->generateClassUses($annotationGenerators, $classes, $className); - $class['annotations'] = $this->generateClassAnnotations($annotationGenerators, $className); - $class['interfaceAnnotations'] = $this->generateInterfaceAnnotations($annotationGenerators, $className); - - foreach ($class['constants'] as $constantName => $constant) { - $class['constants'][$constantName]['annotations'] = $this->generateConstantAnnotations($annotationGenerators, $className, $constantName); - } - - foreach ($class['fields'] as $fieldName => &$field) { - $typeHint = false; - if ($this->isDateTime($field['range'])) { - $typeHint = '\\DateTime'; - } elseif (!($this->isDatatype($field['range']) || $field['isEnum'])) { - if (isset($classes[$field['range']]['interfaceName'])) { - $typeHint = $classes[$field['range']]['interfaceName']; - } else { - $typeHint = $classes[$field['range']]['name']; - } - } - - $field['typeHint'] = $typeHint; - $field['annotations'] = $this->generateFieldAnnotations($annotationGenerators, $className, $fieldName); - $field['getterAnnotations'] = $this->generateGetterAnnotations($annotationGenerators, $className, $fieldName); - - if ($field['isArray']) { - $field['adderAnnotations'] = $this->generateAdderAnnotations($annotationGenerators, $className, $fieldName); - $field['removerAnnotations'] = $this->generateRemoverAnnotations($annotationGenerators, $className, $fieldName); - } else { - $field['setterAnnotations'] = $this->generateSetterAnnotations($annotationGenerators, $className, $fieldName); - } - } - - $classDir = $this->namespaceToDir($config, $class['namespace']); - - if (!file_exists($classDir)) { - mkdir($classDir, 0777, true); - } - - $path = sprintf('%s%s.php', $classDir, $className); - $generatedFiles[] = $path; - - file_put_contents( - $path, - $this->twig->render('class.php.twig', [ - 'config' => $config, - 'class' => $class, - ]) - ); - - if (isset($class['interfaceNamespace'])) { - $interfaceDir = $this->namespaceToDir($config, $class['interfaceNamespace']); - - if (!file_exists($interfaceDir)) { - mkdir($interfaceDir, 0777, true); - } - - $path = sprintf('%s%s.php', $interfaceDir, $class['interfaceName']); - $generatedFiles[] = $path; - file_put_contents( - $path, - $this->twig->render('interface.php.twig', [ - 'config' => $config, - 'class' => $class, - ]) - ); - - if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class['abstract']) { - $interfaceMappings[$class['interfaceNamespace'].'\\'.$class['interfaceName']] = $class['namespace'].'\\'.$className; - } - } - } - - if (isset($interfaceMappings) && $config['doctrine']['resolveTargetEntityConfigPath']) { - $file = $config['output'].'/'.$config['doctrine']['resolveTargetEntityConfigPath']; - $dir = dirname($file); - if (!file_exists($dir)) { - mkdir($dir, 0777, true); - } - - file_put_contents( - $file, - $this->twig->render('doctrine.xml.twig', ['mappings' => $interfaceMappings]) - ); - - $generatedFiles[] = $file; - } - - $this->fixCs($generatedFiles); - } - - /** - * Tests if a type is an enum. - * - * @param \EasyRdf_Resource $type - * - * @return bool - */ - private function isEnum(\EasyRdf_Resource $type) - { - $subClassOf = $type->get('rdfs:subClassOf'); - - return $subClassOf && $subClassOf->getUri() === self::SCHEMA_ORG_ENUMERATION; - } - - /** - * Gets the parent classes of the current one and add them to $parentClasses array. - * - * @param \EasyRdf_Resource $resource - * @param string[] $parentClasses - * - * @return array - */ - private function getParentClasses(\EasyRdf_Resource $resource, array $parentClasses = []) - { - if ([] === $parentClasses) { - return $this->getParentClasses($resource, [$resource->getUri()]); - } - - $subclasses = $resource->all('rdfs:subClassOf'); - - if (!$subclasses) { - return $parentClasses; - } - - $parentClass = $subclasses[0]; - $parentClasses[] = $parentClass->getUri(); - - foreach ($this->graphs as $graph) { - foreach ($graph->allOfType('rdfs:Class') as $type) { - if ($type->getUri() === $parentClass->getUri()) { - $parentClasses = $this->getParentClasses($type, $parentClasses); - - break 2; - } - } - } - - return $parentClasses; - } - - /** - * Create a maps between class an properties. - * - * @param array $types - * - * @return array - */ - private function createPropertiesMap(array $types) - { - $typesAsString = []; - $map = []; - foreach ($types as $type) { - // get all parent classes until the root - $parentClasses = $this->getParentClasses($type); - $typesAsString[] = $parentClasses; - $map[$type->getUri()] = []; - } - - foreach ($this->graphs as $graph) { - foreach ($graph->allOfType('rdf:Property') as $property) { - foreach ($property->all(self::SCHEMA_ORG_DOMAIN) as $domain) { - foreach ($typesAsString as $typesAsStringItem) { - if (in_array($domain->getUri(), $typesAsStringItem)) { - $map[$typesAsStringItem[0]][] = $property; - } - } - } - } - } - - return $map; - } - - /** - * Is this type a datatype? - * - * @param string $type - * - * @return bool - */ - private function isDatatype($type) - { - return in_array($type, ['Boolean', 'DataType', 'Date', 'DateTime', 'Float', 'Integer', 'Number', 'Text', 'Time', 'URL']); - } - - /** - * Is this type a \DateTime? - * - * @param $type - * - * @return bool - */ - private function isDateTime($type) - { - return in_array($type, ['Date', 'DateTime', 'Time']); - } - - /** - * Updates generated $class with given field config. - * - * @param array $config - * @param array $class - * @param EasyRdf_Resource $type - * @param string $propertyName - * @param EasyRdf_Resource $property - * - * @return array $class - */ - private function generateField($config, $class, $type, $propertyName, $property = null) - { - $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; - $typesDefined = !empty($config['types']); - - // Warn when property are not part of GoodRelations - if ($config['checkIsGoodRelations']) { - if (!$this->goodRelationsBridge->exist($propertyName)) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyName, $type->localName())); - } - } - - // Ignore or warn when properties are legacy - if (!empty($property) && preg_match('/legacy spelling/', $property->get('rdfs:comment'))) { - if (isset($typeConfig['properties'])) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyName, $type->localName())); - } else { - $this->logger->info(sprintf('The property "%s" (type "%s") is legacy. Ignoring.', $propertyName, $type->localName())); - - return $class; - } - } - - $ranges = []; - if (isset($typeConfig['properties'][$propertyName]['range']) && $typeConfig['properties'][$propertyName]['range']) { - $ranges[] = $typeConfig['properties'][$propertyName]['range']; - } elseif (!empty($property)) { - foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { - if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { - $ranges[] = $range->localName(); - } - } - } - - $numberOfRanges = count($ranges); - if (0 === $numberOfRanges) { - $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyName, $type->localName())); - } else { - if ($numberOfRanges > 1) { - $this->logger->error(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); - } - - $cardinality = isset($typeConfig['properties'][$propertyName]['cardinality']) ? $typeConfig['properties'][$propertyName]['cardinality'] : false; - if (!$cardinality || $cardinality === CardinalitiesExtractor::CARDINALITY_UNKNOWN) { - $cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1; - } - - $isArray = in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_1_N, - CardinalitiesExtractor::CARDINALITY_N_N, - ]); - $isNullable = !in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_1_1, - CardinalitiesExtractor::CARDINALITY_1_N, - ]); - - $class['fields'][$propertyName] = [ - 'name' => $propertyName, - 'resource' => $property, - 'range' => $ranges[0], - 'cardinality' => $cardinality, - 'isArray' => $isArray, - 'isNullable' => $isNullable, - 'isCustom' => empty($property), - 'isId' => false, - ]; - if ($isArray) { - $class['hasConstructor'] = true; - - if ($config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { - $class['uses'][] = self::DOCTRINE_COLLECTION_USE; - } - } - } - - return $class; - } - - /** - * Generates field's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array - */ - private function generateFieldAnnotations($annotationGenerators, $className, $fieldName) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateFieldAnnotations($className, $fieldName)); - } - - return $annotations; - } - - /** - * Generates constant's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $constantName - * - * @return array - */ - private function generateConstantAnnotations(array $annotationGenerators, $className, $constantName) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateConstantAnnotations($className, $constantName)); - } - - return $annotations; - } - - /** - * Generates class' annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * - * @return array - */ - private function generateClassAnnotations(array $annotationGenerators, $className) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateClassAnnotations($className)); - } - - return $annotations; - } - - /** - * Generates interface's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * - * @return array - */ - private function generateInterfaceAnnotations(array $annotationGenerators, $className) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateInterfaceAnnotations($className)); - } - - return $annotations; - } - - /** - * Generates getter's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array - */ - private function generateGetterAnnotations(array $annotationGenerators, $className, $fieldName) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateGetterAnnotations($className, $fieldName)); - } - - return $annotations; - } - - /** - * Generates adder's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array - */ - private function generateAdderAnnotations(array $annotationGenerators, $className, $fieldName) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateAdderAnnotations($className, $fieldName)); - } - - return $annotations; - } - - /** - * Generates remover's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array - */ - private function generateRemoverAnnotations(array $annotationGenerators, $className, $fieldName) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateRemoverAnnotations($className, $fieldName)); - } - - return $annotations; - } - - /** - * Generates getter's annotations. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array - */ - private function generateSetterAnnotations(array $annotationGenerators, $className, $fieldName) - { - $annotations = []; - foreach ($annotationGenerators as $generator) { - $annotations = array_merge($annotations, $generator->generateSetterAnnotations($className, $fieldName)); - } - - return $annotations; - } - - /** - * Generates uses. - * - * @param \SchemaOrgModel\AnnotationGenerator\AnnotationGeneratorInterface[] $annotationGenerators - * @param array $classes - * @param string $className - * - * @return array - */ - private function generateClassUses($annotationGenerators, $classes, $className) - { - $uses = $classes[$className]['uses']; - - if ( - isset($classes[$className]['interfaceNamespace']) - && $classes[$className]['interfaceNamespace'] !== $classes[$className]['namespace'] - ) { - $uses[] = sprintf( - '%s\\%s', - $classes[$className]['interfaceNamespace'], - $classes[$className]['interfaceName'] - ); - } - - foreach ($classes[$className]['fields'] as $field) { - if (isset($classes[$field['range']]['interfaceName'])) { - $use = sprintf( - '%s\\%s', - $classes[$field['range']]['interfaceNamespace'], - $classes[$field['range']]['interfaceName'] - ); - - if (!in_array($use, $uses)) { - $uses[] = $use; - } - } - } - - foreach ($annotationGenerators as $generator) { - $uses = array_merge($uses, $generator->generateUses($className)); - } - - // Order alphabetically - sort($uses); - - return $uses; - } - - /** - * Converts a namespace to a directory path according to PSR-4. - * - * @param array $config - * @param string $namespace - * - * @return string - */ - private function namespaceToDir($config, $namespace) - { - return sprintf('%s/%s/', $config['output'], strtr($namespace, '\\', '/')); - } - - /** - * Uses PHP CS Fixer to make generated files following PSR and Symfony Coding Standards. - * - * @param array $files - */ - private function fixCs(array $files) - { - $config = new Config(); - $fixer = new Fixer(); - $fixer->registerBuiltInConfigs(); - $fixer->registerBuiltInFixers(); - - $resolver = new ConfigurationResolver(); - $resolver - ->setAllFixers($fixer->getFixers()) - ->setConfig($config) - ->setOptions(array( - 'level' => 'symfony', - 'fixers' => null, - 'progress' => false, - )) - ->resolve() - ; - - $config->fixers($resolver->getFixers()); - - $finder = []; - foreach ($files as $file) { - $finder[] = new \SplFileInfo($file); - } - - $config->finder(new \ArrayIterator($finder)); - $fixer->fix($config); - } -} diff --git a/src/SchemaOrgModel/TypesGeneratorConfiguration.php b/src/SchemaOrgModel/TypesGeneratorConfiguration.php deleted file mode 100644 index d2aafa3b..00000000 --- a/src/SchemaOrgModel/TypesGeneratorConfiguration.php +++ /dev/null @@ -1,131 +0,0 @@ - - * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. - */ - -namespace SchemaOrgModel; - -use Symfony\Component\Config\Definition\Builder\TreeBuilder; -use Symfony\Component\Config\Definition\ConfigurationInterface; - -/** - * Types Generator Configuration. - * - * @author Kévin Dunglas - */ -class TypesGeneratorConfiguration implements ConfigurationInterface -{ - const SCHEMA_ORG_RDFA_URL = 'http://schema.org/docs/schema_org_rdfa.html'; - const GOOD_RELATIONS_OWL_URL = 'http://purl.org/goodrelations/v1.owl'; - - /** - * {@inheritdoc} - */ - public function getConfigTreeBuilder() - { - $treeBuilder = new TreeBuilder(); - $rootNode = $treeBuilder->root('config'); - $rootNode - ->children() - ->arrayNode('rdfa') - ->info('RDFa files to use') - ->defaultValue([ - self::SCHEMA_ORG_RDFA_URL, - ]) - ->prototype('scalar')->end() - ->end() - ->arrayNode('relations') - ->info('OWL relation files to use') - ->defaultValue([ - self::GOOD_RELATIONS_OWL_URL, - ]) - ->prototype('scalar')->end() - ->end() - ->booleanNode('debug')->defaultFalse()->info('Debug mode')->end() - ->booleanNode('generateId')->defaultTrue()->info('Automatically add an id field to entities')->end() - ->booleanNode('useInterface')->defaultFalse()->info('Generate interfaces and use Doctrine\'s Resolve Target Entity feature')->end() - ->booleanNode('checkIsGoodRelations')->defaultFalse()->info('Emit a warning if a property is not derived from GoodRelations')->end() - ->scalarNode('header')->defaultFalse()->info('A license or any text to use as header of generated files')->example('// (c) Kévin Dunglas ')->end() - ->arrayNode('namespaces') - ->addDefaultsIfNotSet() - ->info('PHP namespaces') - ->children() - ->scalarNode('entity')->defaultValue('SchemaOrg\Entity')->info('The namespace of the generated entities')->example('Acme\Entity')->end() - ->scalarNode('enum')->defaultValue('SchemaOrg\Enum')->info('The namespace of the generated enumerations')->example('Acme\Enum')->end() - ->scalarNode('interface')->defaultValue('SchemaOrg\Model')->info('The namespace of the generated interfaces')->example('Acme\Model')->end() - ->end() - ->end() - ->arrayNode('doctrine') - ->addDefaultsIfNotSet() - ->info('Doctrine') - ->children() - ->booleanNode('useCollection')->defaultTrue()->info('Use Doctrine\'s ArrayCollection instead of standard arrays')->end() - ->scalarNode('resolveTargetEntityConfigPath')->defaultNull()->info('The Resolve Target Entity Listener config file pass')->end() - ->end() - ->end() - ->scalarNode('author')->defaultFalse()->info('The value of the phpDoc\'s @author annotation')->example('Kévin Dunglas ')->end() - ->enumNode('fieldVisibility')->values(['private', 'protected', 'public'])->defaultValue('private')->cannotBeEmpty()->info('Visibility of entities fields')->end() - ->arrayNode('types') - ->info('Schema.org\'s types to use') - ->useAttributeAsKey('id') - ->prototype('array') - ->children() - ->booleanNode('abstract')->defaultNull()->info('Is the class abstract? (null to guess)')->end() - ->arrayNode('namespaces') - ->addDefaultsIfNotSet() - ->info('Type namespaces') - ->children() - ->scalarNode('class')->defaultNull()->info('The namespace for the generated class (override any other defined namespace)')->end() - ->scalarNode('interface')->defaultNull()->info('The namespace for the generated interface (override any other defined namespace)')->end() - ->end() - ->end() - ->arrayNode('doctrine') - ->addDefaultsIfNotSet() - ->children() - ->scalarNode('inheritanceMapping')->defaultNull()->info('The Doctrine inheritance mapping type (override the guessed one)')->end() - ->end() - ->end() - ->scalarNode('parent')->defaultNull()->info('The parent class, set to false for a top level class')->end() - ->arrayNode('properties') - ->info('Properties of this type to use') - ->useAttributeAsKey('id') - ->prototype('array') - ->addDefaultsIfNotSet() - ->children() - ->scalarNode('range')->defaultNull()->info('The property range')->example('Offer')->end() - ->scalarNode('relationTableName')->defaultNull()->info('The relation table name')->example('organization_member')->end() - ->enumNode('cardinality')->defaultValue(CardinalitiesExtractor::CARDINALITY_UNKNOWN)->values([ - CardinalitiesExtractor::CARDINALITY_0_1, - CardinalitiesExtractor::CARDINALITY_0_N, - CardinalitiesExtractor::CARDINALITY_1_1, - CardinalitiesExtractor::CARDINALITY_1_N, - CardinalitiesExtractor::CARDINALITY_N_0, - CardinalitiesExtractor::CARDINALITY_N_1, - CardinalitiesExtractor::CARDINALITY_N_N, - CardinalitiesExtractor::CARDINALITY_UNKNOWN, - ])->end() - ->end() - ->end() - ->end() - ->end() - ->end() - ->end() - ->arrayNode('annotationGenerators') - ->info('Annotation generators to use') - ->defaultValue([ - 'SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator', - 'SchemaOrgModel\AnnotationGenerator\ConstraintAnnotationGenerator', - 'SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator', - ]) - ->prototype('scalar')->end() - ->end() - ->end() - ; - - return $treeBuilder; - } -} diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index e72f45b5..38c59c92 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -3,10 +3,10 @@ namespaces: entity: "AddressBook\Entity" # Enable DunglasApiAnnotationGenerator annotationGenerators: - - SchemaOrgModel\AnnotationGenerator\PhpDocAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\DoctrineOrmAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\ConstraintAnnotationGenerator - - SchemaOrgModel\AnnotationGenerator\DunglasApiAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator # The list of types and properties we want to use types: Person: diff --git a/website/CNAME b/website/CNAME deleted file mode 100644 index 57869c1d..00000000 --- a/website/CNAME +++ /dev/null @@ -1 +0,0 @@ -php-schema.dunglas.com diff --git a/website/css/bootstrap.min.css b/website/css/bootstrap.min.css deleted file mode 100644 index dc57de05..00000000 --- a/website/css/bootstrap.min.css +++ /dev/null @@ -1,7 +0,0 @@ -@import url("http://fonts.googleapis.com/css?family=Roboto:300,400,500");/*! - * bootswatch v3.3.1+2 - * Homepage: http://bootswatch.com - * Copyright 2012-2014 Thomas Park - * Licensed under MIT - * Based on Bootstrap -*//*! normalize.css v3.0.2 | MIT License | git.io/normalize */html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:0.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-0.5em}sub{bottom:-0.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace, monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid #c0c0c0;margin:0 2px;padding:0.35em 0.625em 0.75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}/*! Source: https://github.com/h5bp/html5-boilerplate/blob/master/src/css/main.css */@media print{*,*:before,*:after{background:transparent !important;color:#000 !important;-webkit-box-shadow:none !important;box-shadow:none !important;text-shadow:none !important}a,a:visited{text-decoration:underline}a[href]:after{content:" (" attr(href) ")"}abbr[title]:after{content:" (" attr(title) ")"}a[href^="#"]:after,a[href^="javascript:"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}p,h2,h3{orphans:3;widows:3}h2,h3{page-break-after:avoid}select{background:#fff !important}.navbar{display:none}.btn>.caret,.dropup>.btn>.caret{border-top-color:#000 !important}.label{border:1px solid #000}.table{border-collapse:collapse !important}.table td,.table th{background-color:#fff !important}.table-bordered th,.table-bordered td{border:1px solid #ddd !important}}@font-face{font-family:'Glyphicons Halflings';src:url('http://github.com/fonts/glyphicons-halflings-regular.eot');src:url('http://github.com/fonts/glyphicons-halflings-regular.eot?#iefix') format('embedded-opentype'),url('http://github.com/fonts/glyphicons-halflings-regular.woff') format('woff'),url('http://github.com/fonts/glyphicons-halflings-regular.ttf') format('truetype'),url('http://github.com/fonts/glyphicons-halflings-regular.svg#glyphicons_halflingsregular') format('svg')}.glyphicon{position:relative;top:1px;display:inline-block;font-family:'Glyphicons Halflings';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}.glyphicon-asterisk:before{content:"\2a"}.glyphicon-plus:before{content:"\2b"}.glyphicon-euro:before,.glyphicon-eur:before{content:"\20ac"}.glyphicon-minus:before{content:"\2212"}.glyphicon-cloud:before{content:"\2601"}.glyphicon-envelope:before{content:"\2709"}.glyphicon-pencil:before{content:"\270f"}.glyphicon-glass:before{content:"\e001"}.glyphicon-music:before{content:"\e002"}.glyphicon-search:before{content:"\e003"}.glyphicon-heart:before{content:"\e005"}.glyphicon-star:before{content:"\e006"}.glyphicon-star-empty:before{content:"\e007"}.glyphicon-user:before{content:"\e008"}.glyphicon-film:before{content:"\e009"}.glyphicon-th-large:before{content:"\e010"}.glyphicon-th:before{content:"\e011"}.glyphicon-th-list:before{content:"\e012"}.glyphicon-ok:before{content:"\e013"}.glyphicon-remove:before{content:"\e014"}.glyphicon-zoom-in:before{content:"\e015"}.glyphicon-zoom-out:before{content:"\e016"}.glyphicon-off:before{content:"\e017"}.glyphicon-signal:before{content:"\e018"}.glyphicon-cog:before{content:"\e019"}.glyphicon-trash:before{content:"\e020"}.glyphicon-home:before{content:"\e021"}.glyphicon-file:before{content:"\e022"}.glyphicon-time:before{content:"\e023"}.glyphicon-road:before{content:"\e024"}.glyphicon-download-alt:before{content:"\e025"}.glyphicon-download:before{content:"\e026"}.glyphicon-upload:before{content:"\e027"}.glyphicon-inbox:before{content:"\e028"}.glyphicon-play-circle:before{content:"\e029"}.glyphicon-repeat:before{content:"\e030"}.glyphicon-refresh:before{content:"\e031"}.glyphicon-list-alt:before{content:"\e032"}.glyphicon-lock:before{content:"\e033"}.glyphicon-flag:before{content:"\e034"}.glyphicon-headphones:before{content:"\e035"}.glyphicon-volume-off:before{content:"\e036"}.glyphicon-volume-down:before{content:"\e037"}.glyphicon-volume-up:before{content:"\e038"}.glyphicon-qrcode:before{content:"\e039"}.glyphicon-barcode:before{content:"\e040"}.glyphicon-tag:before{content:"\e041"}.glyphicon-tags:before{content:"\e042"}.glyphicon-book:before{content:"\e043"}.glyphicon-bookmark:before{content:"\e044"}.glyphicon-print:before{content:"\e045"}.glyphicon-camera:before{content:"\e046"}.glyphicon-font:before{content:"\e047"}.glyphicon-bold:before{content:"\e048"}.glyphicon-italic:before{content:"\e049"}.glyphicon-text-height:before{content:"\e050"}.glyphicon-text-width:before{content:"\e051"}.glyphicon-align-left:before{content:"\e052"}.glyphicon-align-center:before{content:"\e053"}.glyphicon-align-right:before{content:"\e054"}.glyphicon-align-justify:before{content:"\e055"}.glyphicon-list:before{content:"\e056"}.glyphicon-indent-left:before{content:"\e057"}.glyphicon-indent-right:before{content:"\e058"}.glyphicon-facetime-video:before{content:"\e059"}.glyphicon-picture:before{content:"\e060"}.glyphicon-map-marker:before{content:"\e062"}.glyphicon-adjust:before{content:"\e063"}.glyphicon-tint:before{content:"\e064"}.glyphicon-edit:before{content:"\e065"}.glyphicon-share:before{content:"\e066"}.glyphicon-check:before{content:"\e067"}.glyphicon-move:before{content:"\e068"}.glyphicon-step-backward:before{content:"\e069"}.glyphicon-fast-backward:before{content:"\e070"}.glyphicon-backward:before{content:"\e071"}.glyphicon-play:before{content:"\e072"}.glyphicon-pause:before{content:"\e073"}.glyphicon-stop:before{content:"\e074"}.glyphicon-forward:before{content:"\e075"}.glyphicon-fast-forward:before{content:"\e076"}.glyphicon-step-forward:before{content:"\e077"}.glyphicon-eject:before{content:"\e078"}.glyphicon-chevron-left:before{content:"\e079"}.glyphicon-chevron-right:before{content:"\e080"}.glyphicon-plus-sign:before{content:"\e081"}.glyphicon-minus-sign:before{content:"\e082"}.glyphicon-remove-sign:before{content:"\e083"}.glyphicon-ok-sign:before{content:"\e084"}.glyphicon-question-sign:before{content:"\e085"}.glyphicon-info-sign:before{content:"\e086"}.glyphicon-screenshot:before{content:"\e087"}.glyphicon-remove-circle:before{content:"\e088"}.glyphicon-ok-circle:before{content:"\e089"}.glyphicon-ban-circle:before{content:"\e090"}.glyphicon-arrow-left:before{content:"\e091"}.glyphicon-arrow-right:before{content:"\e092"}.glyphicon-arrow-up:before{content:"\e093"}.glyphicon-arrow-down:before{content:"\e094"}.glyphicon-share-alt:before{content:"\e095"}.glyphicon-resize-full:before{content:"\e096"}.glyphicon-resize-small:before{content:"\e097"}.glyphicon-exclamation-sign:before{content:"\e101"}.glyphicon-gift:before{content:"\e102"}.glyphicon-leaf:before{content:"\e103"}.glyphicon-fire:before{content:"\e104"}.glyphicon-eye-open:before{content:"\e105"}.glyphicon-eye-close:before{content:"\e106"}.glyphicon-warning-sign:before{content:"\e107"}.glyphicon-plane:before{content:"\e108"}.glyphicon-calendar:before{content:"\e109"}.glyphicon-random:before{content:"\e110"}.glyphicon-comment:before{content:"\e111"}.glyphicon-magnet:before{content:"\e112"}.glyphicon-chevron-up:before{content:"\e113"}.glyphicon-chevron-down:before{content:"\e114"}.glyphicon-retweet:before{content:"\e115"}.glyphicon-shopping-cart:before{content:"\e116"}.glyphicon-folder-close:before{content:"\e117"}.glyphicon-folder-open:before{content:"\e118"}.glyphicon-resize-vertical:before{content:"\e119"}.glyphicon-resize-horizontal:before{content:"\e120"}.glyphicon-hdd:before{content:"\e121"}.glyphicon-bullhorn:before{content:"\e122"}.glyphicon-bell:before{content:"\e123"}.glyphicon-certificate:before{content:"\e124"}.glyphicon-thumbs-up:before{content:"\e125"}.glyphicon-thumbs-down:before{content:"\e126"}.glyphicon-hand-right:before{content:"\e127"}.glyphicon-hand-left:before{content:"\e128"}.glyphicon-hand-up:before{content:"\e129"}.glyphicon-hand-down:before{content:"\e130"}.glyphicon-circle-arrow-right:before{content:"\e131"}.glyphicon-circle-arrow-left:before{content:"\e132"}.glyphicon-circle-arrow-up:before{content:"\e133"}.glyphicon-circle-arrow-down:before{content:"\e134"}.glyphicon-globe:before{content:"\e135"}.glyphicon-wrench:before{content:"\e136"}.glyphicon-tasks:before{content:"\e137"}.glyphicon-filter:before{content:"\e138"}.glyphicon-briefcase:before{content:"\e139"}.glyphicon-fullscreen:before{content:"\e140"}.glyphicon-dashboard:before{content:"\e141"}.glyphicon-paperclip:before{content:"\e142"}.glyphicon-heart-empty:before{content:"\e143"}.glyphicon-link:before{content:"\e144"}.glyphicon-phone:before{content:"\e145"}.glyphicon-pushpin:before{content:"\e146"}.glyphicon-usd:before{content:"\e148"}.glyphicon-gbp:before{content:"\e149"}.glyphicon-sort:before{content:"\e150"}.glyphicon-sort-by-alphabet:before{content:"\e151"}.glyphicon-sort-by-alphabet-alt:before{content:"\e152"}.glyphicon-sort-by-order:before{content:"\e153"}.glyphicon-sort-by-order-alt:before{content:"\e154"}.glyphicon-sort-by-attributes:before{content:"\e155"}.glyphicon-sort-by-attributes-alt:before{content:"\e156"}.glyphicon-unchecked:before{content:"\e157"}.glyphicon-expand:before{content:"\e158"}.glyphicon-collapse-down:before{content:"\e159"}.glyphicon-collapse-up:before{content:"\e160"}.glyphicon-log-in:before{content:"\e161"}.glyphicon-flash:before{content:"\e162"}.glyphicon-log-out:before{content:"\e163"}.glyphicon-new-window:before{content:"\e164"}.glyphicon-record:before{content:"\e165"}.glyphicon-save:before{content:"\e166"}.glyphicon-open:before{content:"\e167"}.glyphicon-saved:before{content:"\e168"}.glyphicon-import:before{content:"\e169"}.glyphicon-export:before{content:"\e170"}.glyphicon-send:before{content:"\e171"}.glyphicon-floppy-disk:before{content:"\e172"}.glyphicon-floppy-saved:before{content:"\e173"}.glyphicon-floppy-remove:before{content:"\e174"}.glyphicon-floppy-save:before{content:"\e175"}.glyphicon-floppy-open:before{content:"\e176"}.glyphicon-credit-card:before{content:"\e177"}.glyphicon-transfer:before{content:"\e178"}.glyphicon-cutlery:before{content:"\e179"}.glyphicon-header:before{content:"\e180"}.glyphicon-compressed:before{content:"\e181"}.glyphicon-earphone:before{content:"\e182"}.glyphicon-phone-alt:before{content:"\e183"}.glyphicon-tower:before{content:"\e184"}.glyphicon-stats:before{content:"\e185"}.glyphicon-sd-video:before{content:"\e186"}.glyphicon-hd-video:before{content:"\e187"}.glyphicon-subtitles:before{content:"\e188"}.glyphicon-sound-stereo:before{content:"\e189"}.glyphicon-sound-dolby:before{content:"\e190"}.glyphicon-sound-5-1:before{content:"\e191"}.glyphicon-sound-6-1:before{content:"\e192"}.glyphicon-sound-7-1:before{content:"\e193"}.glyphicon-copyright-mark:before{content:"\e194"}.glyphicon-registration-mark:before{content:"\e195"}.glyphicon-cloud-download:before{content:"\e197"}.glyphicon-cloud-upload:before{content:"\e198"}.glyphicon-tree-conifer:before{content:"\e199"}.glyphicon-tree-deciduous:before{content:"\e200"}*{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}*:before,*:after{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}html{font-size:10px;-webkit-tap-highlight-color:rgba(0,0,0,0)}body{font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;line-height:1.846;color:#666666;background-color:#ffffff}input,button,select,textarea{font-family:inherit;font-size:inherit;line-height:inherit}a{color:#2196f3;text-decoration:none}a:hover,a:focus{color:#0a6ebd;text-decoration:underline}a:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}figure{margin:0}img{vertical-align:middle}.img-responsive,.thumbnail>img,.thumbnail a>img,.carousel-inner>.item>img,.carousel-inner>.item>a>img{display:block;max-width:100%;height:auto}.img-rounded{border-radius:3px}.img-thumbnail{padding:4px;line-height:1.846;background-color:#ffffff;border:1px solid #dddddd;border-radius:3px;-webkit-transition:all .2s ease-in-out;-o-transition:all .2s ease-in-out;transition:all .2s ease-in-out;display:inline-block;max-width:100%;height:auto}.img-circle{border-radius:50%}hr{margin-top:23px;margin-bottom:23px;border:0;border-top:1px solid #eeeeee}.sr-only{position:absolute;width:1px;height:1px;margin:-1px;padding:0;overflow:hidden;clip:rect(0, 0, 0, 0);border:0}.sr-only-focusable:active,.sr-only-focusable:focus{position:static;width:auto;height:auto;margin:0;overflow:visible;clip:auto}h1,h2,h3,h4,h5,h6,.h1,.h2,.h3,.h4,.h5,.h6{font-family:inherit;font-weight:400;line-height:1.1;color:#444444}h1 small,h2 small,h3 small,h4 small,h5 small,h6 small,.h1 small,.h2 small,.h3 small,.h4 small,.h5 small,.h6 small,h1 .small,h2 .small,h3 .small,h4 .small,h5 .small,h6 .small,.h1 .small,.h2 .small,.h3 .small,.h4 .small,.h5 .small,.h6 .small{font-weight:normal;line-height:1;color:#bbbbbb}h1,.h1,h2,.h2,h3,.h3{margin-top:23px;margin-bottom:11.5px}h1 small,.h1 small,h2 small,.h2 small,h3 small,.h3 small,h1 .small,.h1 .small,h2 .small,.h2 .small,h3 .small,.h3 .small{font-size:65%}h4,.h4,h5,.h5,h6,.h6{margin-top:11.5px;margin-bottom:11.5px}h4 small,.h4 small,h5 small,.h5 small,h6 small,.h6 small,h4 .small,.h4 .small,h5 .small,.h5 .small,h6 .small,.h6 .small{font-size:75%}h1,.h1{font-size:56px}h2,.h2{font-size:45px}h3,.h3{font-size:34px}h4,.h4{font-size:24px}h5,.h5{font-size:20px}h6,.h6{font-size:14px}p{margin:0 0 11.5px}.lead{margin-bottom:23px;font-size:14px;font-weight:300;line-height:1.4}@media (min-width:768px){.lead{font-size:19.5px}}small,.small{font-size:92%}mark,.mark{background-color:#ffe0b2;padding:.2em}.text-left{text-align:left}.text-right{text-align:right}.text-center{text-align:center}.text-justify{text-align:justify}.text-nowrap{white-space:nowrap}.text-lowercase{text-transform:lowercase}.text-uppercase{text-transform:uppercase}.text-capitalize{text-transform:capitalize}.text-muted{color:#bbbbbb}.text-primary{color:#2196f3}a.text-primary:hover{color:#0c7cd5}.text-success{color:#4caf50}a.text-success:hover{color:#3d8b40}.text-info{color:#9c27b0}a.text-info:hover{color:#771e86}.text-warning{color:#ff9800}a.text-warning:hover{color:#cc7a00}.text-danger{color:#e51c23}a.text-danger:hover{color:#b9151b}.bg-primary{color:#fff;background-color:#2196f3}a.bg-primary:hover{background-color:#0c7cd5}.bg-success{background-color:#dff0d8}a.bg-success:hover{background-color:#c1e2b3}.bg-info{background-color:#e1bee7}a.bg-info:hover{background-color:#d099d9}.bg-warning{background-color:#ffe0b2}a.bg-warning:hover{background-color:#ffcb7f}.bg-danger{background-color:#f9bdbb}a.bg-danger:hover{background-color:#f5908c}.page-header{padding-bottom:10.5px;margin:46px 0 23px;border-bottom:1px solid #eeeeee}ul,ol{margin-top:0;margin-bottom:11.5px}ul ul,ol ul,ul ol,ol ol{margin-bottom:0}.list-unstyled{padding-left:0;list-style:none}.list-inline{padding-left:0;list-style:none;margin-left:-5px}.list-inline>li{display:inline-block;padding-left:5px;padding-right:5px}dl{margin-top:0;margin-bottom:23px}dt,dd{line-height:1.846}dt{font-weight:bold}dd{margin-left:0}@media (min-width:768px){.dl-horizontal dt{float:left;width:160px;clear:left;text-align:right;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.dl-horizontal dd{margin-left:180px}}abbr[title],abbr[data-original-title]{cursor:help;border-bottom:1px dotted #bbbbbb}.initialism{font-size:90%;text-transform:uppercase}blockquote{padding:11.5px 23px;margin:0 0 23px;font-size:16.25px;border-left:5px solid #eeeeee}blockquote p:last-child,blockquote ul:last-child,blockquote ol:last-child{margin-bottom:0}blockquote footer,blockquote small,blockquote .small{display:block;font-size:80%;line-height:1.846;color:#bbbbbb}blockquote footer:before,blockquote small:before,blockquote .small:before{content:'\2014 \00A0'}.blockquote-reverse,blockquote.pull-right{padding-right:15px;padding-left:0;border-right:5px solid #eeeeee;border-left:0;text-align:right}.blockquote-reverse footer:before,blockquote.pull-right footer:before,.blockquote-reverse small:before,blockquote.pull-right small:before,.blockquote-reverse .small:before,blockquote.pull-right .small:before{content:''}.blockquote-reverse footer:after,blockquote.pull-right footer:after,.blockquote-reverse small:after,blockquote.pull-right small:after,.blockquote-reverse .small:after,blockquote.pull-right .small:after{content:'\00A0 \2014'}address{margin-bottom:23px;font-style:normal;line-height:1.846}code,kbd,pre,samp{font-family:Menlo,Monaco,Consolas,"Courier New",monospace}code{padding:2px 4px;font-size:90%;color:#c7254e;background-color:#f9f2f4;border-radius:3px}kbd{padding:2px 4px;font-size:90%;color:#ffffff;background-color:#333333;border-radius:3px;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.25)}kbd kbd{padding:0;font-size:100%;font-weight:bold;-webkit-box-shadow:none;box-shadow:none}pre{display:block;padding:11px;margin:0 0 11.5px;font-size:12px;line-height:1.846;word-break:break-all;word-wrap:break-word;color:#212121;background-color:#f5f5f5;border:1px solid #cccccc;border-radius:3px}pre code{padding:0;font-size:inherit;color:inherit;white-space:pre-wrap;background-color:transparent;border-radius:0}.pre-scrollable{max-height:340px;overflow-y:scroll}.container{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}@media (min-width:768px){.container{width:750px}}@media (min-width:992px){.container{width:970px}}@media (min-width:1200px){.container{width:1170px}}.container-fluid{margin-right:auto;margin-left:auto;padding-left:15px;padding-right:15px}.row{margin-left:-15px;margin-right:-15px}.col-xs-1,.col-sm-1,.col-md-1,.col-lg-1,.col-xs-2,.col-sm-2,.col-md-2,.col-lg-2,.col-xs-3,.col-sm-3,.col-md-3,.col-lg-3,.col-xs-4,.col-sm-4,.col-md-4,.col-lg-4,.col-xs-5,.col-sm-5,.col-md-5,.col-lg-5,.col-xs-6,.col-sm-6,.col-md-6,.col-lg-6,.col-xs-7,.col-sm-7,.col-md-7,.col-lg-7,.col-xs-8,.col-sm-8,.col-md-8,.col-lg-8,.col-xs-9,.col-sm-9,.col-md-9,.col-lg-9,.col-xs-10,.col-sm-10,.col-md-10,.col-lg-10,.col-xs-11,.col-sm-11,.col-md-11,.col-lg-11,.col-xs-12,.col-sm-12,.col-md-12,.col-lg-12{position:relative;min-height:1px;padding-left:15px;padding-right:15px}.col-xs-1,.col-xs-2,.col-xs-3,.col-xs-4,.col-xs-5,.col-xs-6,.col-xs-7,.col-xs-8,.col-xs-9,.col-xs-10,.col-xs-11,.col-xs-12{float:left}.col-xs-12{width:100%}.col-xs-11{width:91.66666667%}.col-xs-10{width:83.33333333%}.col-xs-9{width:75%}.col-xs-8{width:66.66666667%}.col-xs-7{width:58.33333333%}.col-xs-6{width:50%}.col-xs-5{width:41.66666667%}.col-xs-4{width:33.33333333%}.col-xs-3{width:25%}.col-xs-2{width:16.66666667%}.col-xs-1{width:8.33333333%}.col-xs-pull-12{right:100%}.col-xs-pull-11{right:91.66666667%}.col-xs-pull-10{right:83.33333333%}.col-xs-pull-9{right:75%}.col-xs-pull-8{right:66.66666667%}.col-xs-pull-7{right:58.33333333%}.col-xs-pull-6{right:50%}.col-xs-pull-5{right:41.66666667%}.col-xs-pull-4{right:33.33333333%}.col-xs-pull-3{right:25%}.col-xs-pull-2{right:16.66666667%}.col-xs-pull-1{right:8.33333333%}.col-xs-pull-0{right:auto}.col-xs-push-12{left:100%}.col-xs-push-11{left:91.66666667%}.col-xs-push-10{left:83.33333333%}.col-xs-push-9{left:75%}.col-xs-push-8{left:66.66666667%}.col-xs-push-7{left:58.33333333%}.col-xs-push-6{left:50%}.col-xs-push-5{left:41.66666667%}.col-xs-push-4{left:33.33333333%}.col-xs-push-3{left:25%}.col-xs-push-2{left:16.66666667%}.col-xs-push-1{left:8.33333333%}.col-xs-push-0{left:auto}.col-xs-offset-12{margin-left:100%}.col-xs-offset-11{margin-left:91.66666667%}.col-xs-offset-10{margin-left:83.33333333%}.col-xs-offset-9{margin-left:75%}.col-xs-offset-8{margin-left:66.66666667%}.col-xs-offset-7{margin-left:58.33333333%}.col-xs-offset-6{margin-left:50%}.col-xs-offset-5{margin-left:41.66666667%}.col-xs-offset-4{margin-left:33.33333333%}.col-xs-offset-3{margin-left:25%}.col-xs-offset-2{margin-left:16.66666667%}.col-xs-offset-1{margin-left:8.33333333%}.col-xs-offset-0{margin-left:0%}@media (min-width:768px){.col-sm-1,.col-sm-2,.col-sm-3,.col-sm-4,.col-sm-5,.col-sm-6,.col-sm-7,.col-sm-8,.col-sm-9,.col-sm-10,.col-sm-11,.col-sm-12{float:left}.col-sm-12{width:100%}.col-sm-11{width:91.66666667%}.col-sm-10{width:83.33333333%}.col-sm-9{width:75%}.col-sm-8{width:66.66666667%}.col-sm-7{width:58.33333333%}.col-sm-6{width:50%}.col-sm-5{width:41.66666667%}.col-sm-4{width:33.33333333%}.col-sm-3{width:25%}.col-sm-2{width:16.66666667%}.col-sm-1{width:8.33333333%}.col-sm-pull-12{right:100%}.col-sm-pull-11{right:91.66666667%}.col-sm-pull-10{right:83.33333333%}.col-sm-pull-9{right:75%}.col-sm-pull-8{right:66.66666667%}.col-sm-pull-7{right:58.33333333%}.col-sm-pull-6{right:50%}.col-sm-pull-5{right:41.66666667%}.col-sm-pull-4{right:33.33333333%}.col-sm-pull-3{right:25%}.col-sm-pull-2{right:16.66666667%}.col-sm-pull-1{right:8.33333333%}.col-sm-pull-0{right:auto}.col-sm-push-12{left:100%}.col-sm-push-11{left:91.66666667%}.col-sm-push-10{left:83.33333333%}.col-sm-push-9{left:75%}.col-sm-push-8{left:66.66666667%}.col-sm-push-7{left:58.33333333%}.col-sm-push-6{left:50%}.col-sm-push-5{left:41.66666667%}.col-sm-push-4{left:33.33333333%}.col-sm-push-3{left:25%}.col-sm-push-2{left:16.66666667%}.col-sm-push-1{left:8.33333333%}.col-sm-push-0{left:auto}.col-sm-offset-12{margin-left:100%}.col-sm-offset-11{margin-left:91.66666667%}.col-sm-offset-10{margin-left:83.33333333%}.col-sm-offset-9{margin-left:75%}.col-sm-offset-8{margin-left:66.66666667%}.col-sm-offset-7{margin-left:58.33333333%}.col-sm-offset-6{margin-left:50%}.col-sm-offset-5{margin-left:41.66666667%}.col-sm-offset-4{margin-left:33.33333333%}.col-sm-offset-3{margin-left:25%}.col-sm-offset-2{margin-left:16.66666667%}.col-sm-offset-1{margin-left:8.33333333%}.col-sm-offset-0{margin-left:0%}}@media (min-width:992px){.col-md-1,.col-md-2,.col-md-3,.col-md-4,.col-md-5,.col-md-6,.col-md-7,.col-md-8,.col-md-9,.col-md-10,.col-md-11,.col-md-12{float:left}.col-md-12{width:100%}.col-md-11{width:91.66666667%}.col-md-10{width:83.33333333%}.col-md-9{width:75%}.col-md-8{width:66.66666667%}.col-md-7{width:58.33333333%}.col-md-6{width:50%}.col-md-5{width:41.66666667%}.col-md-4{width:33.33333333%}.col-md-3{width:25%}.col-md-2{width:16.66666667%}.col-md-1{width:8.33333333%}.col-md-pull-12{right:100%}.col-md-pull-11{right:91.66666667%}.col-md-pull-10{right:83.33333333%}.col-md-pull-9{right:75%}.col-md-pull-8{right:66.66666667%}.col-md-pull-7{right:58.33333333%}.col-md-pull-6{right:50%}.col-md-pull-5{right:41.66666667%}.col-md-pull-4{right:33.33333333%}.col-md-pull-3{right:25%}.col-md-pull-2{right:16.66666667%}.col-md-pull-1{right:8.33333333%}.col-md-pull-0{right:auto}.col-md-push-12{left:100%}.col-md-push-11{left:91.66666667%}.col-md-push-10{left:83.33333333%}.col-md-push-9{left:75%}.col-md-push-8{left:66.66666667%}.col-md-push-7{left:58.33333333%}.col-md-push-6{left:50%}.col-md-push-5{left:41.66666667%}.col-md-push-4{left:33.33333333%}.col-md-push-3{left:25%}.col-md-push-2{left:16.66666667%}.col-md-push-1{left:8.33333333%}.col-md-push-0{left:auto}.col-md-offset-12{margin-left:100%}.col-md-offset-11{margin-left:91.66666667%}.col-md-offset-10{margin-left:83.33333333%}.col-md-offset-9{margin-left:75%}.col-md-offset-8{margin-left:66.66666667%}.col-md-offset-7{margin-left:58.33333333%}.col-md-offset-6{margin-left:50%}.col-md-offset-5{margin-left:41.66666667%}.col-md-offset-4{margin-left:33.33333333%}.col-md-offset-3{margin-left:25%}.col-md-offset-2{margin-left:16.66666667%}.col-md-offset-1{margin-left:8.33333333%}.col-md-offset-0{margin-left:0%}}@media (min-width:1200px){.col-lg-1,.col-lg-2,.col-lg-3,.col-lg-4,.col-lg-5,.col-lg-6,.col-lg-7,.col-lg-8,.col-lg-9,.col-lg-10,.col-lg-11,.col-lg-12{float:left}.col-lg-12{width:100%}.col-lg-11{width:91.66666667%}.col-lg-10{width:83.33333333%}.col-lg-9{width:75%}.col-lg-8{width:66.66666667%}.col-lg-7{width:58.33333333%}.col-lg-6{width:50%}.col-lg-5{width:41.66666667%}.col-lg-4{width:33.33333333%}.col-lg-3{width:25%}.col-lg-2{width:16.66666667%}.col-lg-1{width:8.33333333%}.col-lg-pull-12{right:100%}.col-lg-pull-11{right:91.66666667%}.col-lg-pull-10{right:83.33333333%}.col-lg-pull-9{right:75%}.col-lg-pull-8{right:66.66666667%}.col-lg-pull-7{right:58.33333333%}.col-lg-pull-6{right:50%}.col-lg-pull-5{right:41.66666667%}.col-lg-pull-4{right:33.33333333%}.col-lg-pull-3{right:25%}.col-lg-pull-2{right:16.66666667%}.col-lg-pull-1{right:8.33333333%}.col-lg-pull-0{right:auto}.col-lg-push-12{left:100%}.col-lg-push-11{left:91.66666667%}.col-lg-push-10{left:83.33333333%}.col-lg-push-9{left:75%}.col-lg-push-8{left:66.66666667%}.col-lg-push-7{left:58.33333333%}.col-lg-push-6{left:50%}.col-lg-push-5{left:41.66666667%}.col-lg-push-4{left:33.33333333%}.col-lg-push-3{left:25%}.col-lg-push-2{left:16.66666667%}.col-lg-push-1{left:8.33333333%}.col-lg-push-0{left:auto}.col-lg-offset-12{margin-left:100%}.col-lg-offset-11{margin-left:91.66666667%}.col-lg-offset-10{margin-left:83.33333333%}.col-lg-offset-9{margin-left:75%}.col-lg-offset-8{margin-left:66.66666667%}.col-lg-offset-7{margin-left:58.33333333%}.col-lg-offset-6{margin-left:50%}.col-lg-offset-5{margin-left:41.66666667%}.col-lg-offset-4{margin-left:33.33333333%}.col-lg-offset-3{margin-left:25%}.col-lg-offset-2{margin-left:16.66666667%}.col-lg-offset-1{margin-left:8.33333333%}.col-lg-offset-0{margin-left:0%}}table{background-color:transparent}caption{padding-top:8px;padding-bottom:8px;color:#bbbbbb;text-align:left}th{text-align:left}.table{width:100%;max-width:100%;margin-bottom:23px}.table>thead>tr>th,.table>tbody>tr>th,.table>tfoot>tr>th,.table>thead>tr>td,.table>tbody>tr>td,.table>tfoot>tr>td{padding:8px;line-height:1.846;vertical-align:top;border-top:1px solid #dddddd}.table>thead>tr>th{vertical-align:bottom;border-bottom:2px solid #dddddd}.table>caption+thead>tr:first-child>th,.table>colgroup+thead>tr:first-child>th,.table>thead:first-child>tr:first-child>th,.table>caption+thead>tr:first-child>td,.table>colgroup+thead>tr:first-child>td,.table>thead:first-child>tr:first-child>td{border-top:0}.table>tbody+tbody{border-top:2px solid #dddddd}.table .table{background-color:#ffffff}.table-condensed>thead>tr>th,.table-condensed>tbody>tr>th,.table-condensed>tfoot>tr>th,.table-condensed>thead>tr>td,.table-condensed>tbody>tr>td,.table-condensed>tfoot>tr>td{padding:5px}.table-bordered{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>tbody>tr>th,.table-bordered>tfoot>tr>th,.table-bordered>thead>tr>td,.table-bordered>tbody>tr>td,.table-bordered>tfoot>tr>td{border:1px solid #dddddd}.table-bordered>thead>tr>th,.table-bordered>thead>tr>td{border-bottom-width:2px}.table-striped>tbody>tr:nth-child(odd){background-color:#f9f9f9}.table-hover>tbody>tr:hover{background-color:#f5f5f5}table col[class*="col-"]{position:static;float:none;display:table-column}table td[class*="col-"],table th[class*="col-"]{position:static;float:none;display:table-cell}.table>thead>tr>td.active,.table>tbody>tr>td.active,.table>tfoot>tr>td.active,.table>thead>tr>th.active,.table>tbody>tr>th.active,.table>tfoot>tr>th.active,.table>thead>tr.active>td,.table>tbody>tr.active>td,.table>tfoot>tr.active>td,.table>thead>tr.active>th,.table>tbody>tr.active>th,.table>tfoot>tr.active>th{background-color:#f5f5f5}.table-hover>tbody>tr>td.active:hover,.table-hover>tbody>tr>th.active:hover,.table-hover>tbody>tr.active:hover>td,.table-hover>tbody>tr:hover>.active,.table-hover>tbody>tr.active:hover>th{background-color:#e8e8e8}.table>thead>tr>td.success,.table>tbody>tr>td.success,.table>tfoot>tr>td.success,.table>thead>tr>th.success,.table>tbody>tr>th.success,.table>tfoot>tr>th.success,.table>thead>tr.success>td,.table>tbody>tr.success>td,.table>tfoot>tr.success>td,.table>thead>tr.success>th,.table>tbody>tr.success>th,.table>tfoot>tr.success>th{background-color:#dff0d8}.table-hover>tbody>tr>td.success:hover,.table-hover>tbody>tr>th.success:hover,.table-hover>tbody>tr.success:hover>td,.table-hover>tbody>tr:hover>.success,.table-hover>tbody>tr.success:hover>th{background-color:#d0e9c6}.table>thead>tr>td.info,.table>tbody>tr>td.info,.table>tfoot>tr>td.info,.table>thead>tr>th.info,.table>tbody>tr>th.info,.table>tfoot>tr>th.info,.table>thead>tr.info>td,.table>tbody>tr.info>td,.table>tfoot>tr.info>td,.table>thead>tr.info>th,.table>tbody>tr.info>th,.table>tfoot>tr.info>th{background-color:#e1bee7}.table-hover>tbody>tr>td.info:hover,.table-hover>tbody>tr>th.info:hover,.table-hover>tbody>tr.info:hover>td,.table-hover>tbody>tr:hover>.info,.table-hover>tbody>tr.info:hover>th{background-color:#d8abe0}.table>thead>tr>td.warning,.table>tbody>tr>td.warning,.table>tfoot>tr>td.warning,.table>thead>tr>th.warning,.table>tbody>tr>th.warning,.table>tfoot>tr>th.warning,.table>thead>tr.warning>td,.table>tbody>tr.warning>td,.table>tfoot>tr.warning>td,.table>thead>tr.warning>th,.table>tbody>tr.warning>th,.table>tfoot>tr.warning>th{background-color:#ffe0b2}.table-hover>tbody>tr>td.warning:hover,.table-hover>tbody>tr>th.warning:hover,.table-hover>tbody>tr.warning:hover>td,.table-hover>tbody>tr:hover>.warning,.table-hover>tbody>tr.warning:hover>th{background-color:#ffd699}.table>thead>tr>td.danger,.table>tbody>tr>td.danger,.table>tfoot>tr>td.danger,.table>thead>tr>th.danger,.table>tbody>tr>th.danger,.table>tfoot>tr>th.danger,.table>thead>tr.danger>td,.table>tbody>tr.danger>td,.table>tfoot>tr.danger>td,.table>thead>tr.danger>th,.table>tbody>tr.danger>th,.table>tfoot>tr.danger>th{background-color:#f9bdbb}.table-hover>tbody>tr>td.danger:hover,.table-hover>tbody>tr>th.danger:hover,.table-hover>tbody>tr.danger:hover>td,.table-hover>tbody>tr:hover>.danger,.table-hover>tbody>tr.danger:hover>th{background-color:#f7a6a4}.table-responsive{overflow-x:auto;min-height:0.01%}@media screen and (max-width:767px){.table-responsive{width:100%;margin-bottom:17.25px;overflow-y:hidden;-ms-overflow-style:-ms-autohiding-scrollbar;border:1px solid #dddddd}.table-responsive>.table{margin-bottom:0}.table-responsive>.table>thead>tr>th,.table-responsive>.table>tbody>tr>th,.table-responsive>.table>tfoot>tr>th,.table-responsive>.table>thead>tr>td,.table-responsive>.table>tbody>tr>td,.table-responsive>.table>tfoot>tr>td{white-space:nowrap}.table-responsive>.table-bordered{border:0}.table-responsive>.table-bordered>thead>tr>th:first-child,.table-responsive>.table-bordered>tbody>tr>th:first-child,.table-responsive>.table-bordered>tfoot>tr>th:first-child,.table-responsive>.table-bordered>thead>tr>td:first-child,.table-responsive>.table-bordered>tbody>tr>td:first-child,.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.table-responsive>.table-bordered>thead>tr>th:last-child,.table-responsive>.table-bordered>tbody>tr>th:last-child,.table-responsive>.table-bordered>tfoot>tr>th:last-child,.table-responsive>.table-bordered>thead>tr>td:last-child,.table-responsive>.table-bordered>tbody>tr>td:last-child,.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.table-responsive>.table-bordered>tbody>tr:last-child>th,.table-responsive>.table-bordered>tfoot>tr:last-child>th,.table-responsive>.table-bordered>tbody>tr:last-child>td,.table-responsive>.table-bordered>tfoot>tr:last-child>td{border-bottom:0}}fieldset{padding:0;margin:0;border:0;min-width:0}legend{display:block;width:100%;padding:0;margin-bottom:23px;font-size:19.5px;line-height:inherit;color:#212121;border:0;border-bottom:1px solid #e5e5e5}label{display:inline-block;max-width:100%;margin-bottom:5px;font-weight:bold}input[type="search"]{-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box}input[type="radio"],input[type="checkbox"]{margin:4px 0 0;margin-top:1px \9;line-height:normal}input[type="file"]{display:block}input[type="range"]{display:block;width:100%}select[multiple],select[size]{height:auto}input[type="file"]:focus,input[type="radio"]:focus,input[type="checkbox"]:focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}output{display:block;padding-top:7px;font-size:13px;line-height:1.846;color:#666666}.form-control{display:block;width:100%;height:37px;padding:6px 16px;font-size:13px;line-height:1.846;color:#666666;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);-webkit-transition:border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s;-o-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.form-control:focus{border-color:#66afe9;outline:0;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 8px rgba(102,175,233,0.6)}.form-control::-moz-placeholder{color:#bbbbbb;opacity:1}.form-control:-ms-input-placeholder{color:#bbbbbb}.form-control::-webkit-input-placeholder{color:#bbbbbb}.form-control[disabled],.form-control[readonly],fieldset[disabled] .form-control{cursor:not-allowed;background-color:transparent;opacity:1}textarea.form-control{height:auto}input[type="search"]{-webkit-appearance:none}@media screen and (-webkit-min-device-pixel-ratio:0){input[type="date"],input[type="time"],input[type="datetime-local"],input[type="month"]{line-height:37px}input[type="date"].input-sm,input[type="time"].input-sm,input[type="datetime-local"].input-sm,input[type="month"].input-sm{line-height:30px}input[type="date"].input-lg,input[type="time"].input-lg,input[type="datetime-local"].input-lg,input[type="month"].input-lg{line-height:45px}}.form-group{margin-bottom:15px}.radio,.checkbox{position:relative;display:block;margin-top:10px;margin-bottom:10px}.radio label,.checkbox label{min-height:23px;padding-left:20px;margin-bottom:0;font-weight:normal;cursor:pointer}.radio input[type="radio"],.radio-inline input[type="radio"],.checkbox input[type="checkbox"],.checkbox-inline input[type="checkbox"]{position:absolute;margin-left:-20px;margin-top:4px \9}.radio+.radio,.checkbox+.checkbox{margin-top:-5px}.radio-inline,.checkbox-inline{display:inline-block;padding-left:20px;margin-bottom:0;vertical-align:middle;font-weight:normal;cursor:pointer}.radio-inline+.radio-inline,.checkbox-inline+.checkbox-inline{margin-top:0;margin-left:10px}input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"].disabled,input[type="checkbox"].disabled,fieldset[disabled] input[type="radio"],fieldset[disabled] input[type="checkbox"]{cursor:not-allowed}.radio-inline.disabled,.checkbox-inline.disabled,fieldset[disabled] .radio-inline,fieldset[disabled] .checkbox-inline{cursor:not-allowed}.radio.disabled label,.checkbox.disabled label,fieldset[disabled] .radio label,fieldset[disabled] .checkbox label{cursor:not-allowed}.form-control-static{padding-top:7px;padding-bottom:7px;margin-bottom:0}.form-control-static.input-lg,.form-control-static.input-sm{padding-left:0;padding-right:0}.input-sm,.form-group-sm .form-control{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-sm,select.form-group-sm .form-control{height:30px;line-height:30px}textarea.input-sm,textarea.form-group-sm .form-control,select[multiple].input-sm,select[multiple].form-group-sm .form-control{height:auto}.input-lg,.form-group-lg .form-control{height:45px;padding:10px 16px;font-size:17px;line-height:1.33;border-radius:3px}select.input-lg,select.form-group-lg .form-control{height:45px;line-height:45px}textarea.input-lg,textarea.form-group-lg .form-control,select[multiple].input-lg,select[multiple].form-group-lg .form-control{height:auto}.has-feedback{position:relative}.has-feedback .form-control{padding-right:46.25px}.form-control-feedback{position:absolute;top:0;right:0;z-index:2;display:block;width:37px;height:37px;line-height:37px;text-align:center;pointer-events:none}.input-lg+.form-control-feedback{width:45px;height:45px;line-height:45px}.input-sm+.form-control-feedback{width:30px;height:30px;line-height:30px}.has-success .help-block,.has-success .control-label,.has-success .radio,.has-success .checkbox,.has-success .radio-inline,.has-success .checkbox-inline,.has-success.radio label,.has-success.checkbox label,.has-success.radio-inline label,.has-success.checkbox-inline label{color:#4caf50}.has-success .form-control{border-color:#4caf50;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-success .form-control:focus{border-color:#3d8b40;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #92cf94;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #92cf94}.has-success .input-group-addon{color:#4caf50;border-color:#4caf50;background-color:#dff0d8}.has-success .form-control-feedback{color:#4caf50}.has-warning .help-block,.has-warning .control-label,.has-warning .radio,.has-warning .checkbox,.has-warning .radio-inline,.has-warning .checkbox-inline,.has-warning.radio label,.has-warning.checkbox label,.has-warning.radio-inline label,.has-warning.checkbox-inline label{color:#ff9800}.has-warning .form-control{border-color:#ff9800;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-warning .form-control:focus{border-color:#cc7a00;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ffc166;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ffc166}.has-warning .input-group-addon{color:#ff9800;border-color:#ff9800;background-color:#ffe0b2}.has-warning .form-control-feedback{color:#ff9800}.has-error .help-block,.has-error .control-label,.has-error .radio,.has-error .checkbox,.has-error .radio-inline,.has-error .checkbox-inline,.has-error.radio label,.has-error.checkbox label,.has-error.radio-inline label,.has-error.checkbox-inline label{color:#e51c23}.has-error .form-control{border-color:#e51c23;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075);box-shadow:inset 0 1px 1px rgba(0,0,0,0.075)}.has-error .form-control:focus{border-color:#b9151b;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ef787c;box-shadow:inset 0 1px 1px rgba(0,0,0,0.075),0 0 6px #ef787c}.has-error .input-group-addon{color:#e51c23;border-color:#e51c23;background-color:#f9bdbb}.has-error .form-control-feedback{color:#e51c23}.has-feedback label~.form-control-feedback{top:28px}.has-feedback label.sr-only~.form-control-feedback{top:0}.help-block{display:block;margin-top:5px;margin-bottom:10px;color:#a6a6a6}@media (min-width:768px){.form-inline .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.form-inline .form-control{display:inline-block;width:auto;vertical-align:middle}.form-inline .form-control-static{display:inline-block}.form-inline .input-group{display:inline-table;vertical-align:middle}.form-inline .input-group .input-group-addon,.form-inline .input-group .input-group-btn,.form-inline .input-group .form-control{width:auto}.form-inline .input-group>.form-control{width:100%}.form-inline .control-label{margin-bottom:0;vertical-align:middle}.form-inline .radio,.form-inline .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.form-inline .radio label,.form-inline .checkbox label{padding-left:0}.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{position:relative;margin-left:0}.form-inline .has-feedback .form-control-feedback{top:0}}.form-horizontal .radio,.form-horizontal .checkbox,.form-horizontal .radio-inline,.form-horizontal .checkbox-inline{margin-top:0;margin-bottom:0;padding-top:7px}.form-horizontal .radio,.form-horizontal .checkbox{min-height:30px}.form-horizontal .form-group{margin-left:-15px;margin-right:-15px}@media (min-width:768px){.form-horizontal .control-label{text-align:right;margin-bottom:0;padding-top:7px}}.form-horizontal .has-feedback .form-control-feedback{right:15px}@media (min-width:768px){.form-horizontal .form-group-lg .control-label{padding-top:14.3px}}@media (min-width:768px){.form-horizontal .form-group-sm .control-label{padding-top:6px}}.btn{display:inline-block;margin-bottom:0;font-weight:normal;text-align:center;vertical-align:middle;-ms-touch-action:manipulation;touch-action:manipulation;cursor:pointer;background-image:none;border:1px solid transparent;white-space:nowrap;padding:6px 16px;font-size:13px;line-height:1.846;border-radius:3px;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.btn:focus,.btn:active:focus,.btn.active:focus,.btn.focus,.btn:active.focus,.btn.active.focus{outline:thin dotted;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px}.btn:hover,.btn:focus,.btn.focus{color:#666666;text-decoration:none}.btn:active,.btn.active{outline:0;background-image:none;-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn.disabled,.btn[disabled],fieldset[disabled] .btn{cursor:not-allowed;pointer-events:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;box-shadow:none}.btn-default{color:#666666;background-color:#ffffff;border-color:#eeeeee}.btn-default:hover,.btn-default:focus,.btn-default.focus,.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{color:#666666;background-color:#e6e6e6;border-color:#cfcfcf}.btn-default:active,.btn-default.active,.open>.dropdown-toggle.btn-default{background-image:none}.btn-default.disabled,.btn-default[disabled],fieldset[disabled] .btn-default,.btn-default.disabled:hover,.btn-default[disabled]:hover,fieldset[disabled] .btn-default:hover,.btn-default.disabled:focus,.btn-default[disabled]:focus,fieldset[disabled] .btn-default:focus,.btn-default.disabled.focus,.btn-default[disabled].focus,fieldset[disabled] .btn-default.focus,.btn-default.disabled:active,.btn-default[disabled]:active,fieldset[disabled] .btn-default:active,.btn-default.disabled.active,.btn-default[disabled].active,fieldset[disabled] .btn-default.active{background-color:#ffffff;border-color:#eeeeee}.btn-default .badge{color:#ffffff;background-color:#666666}.btn-primary{color:#ffffff;background-color:#2196f3;border-color:transparent}.btn-primary:hover,.btn-primary:focus,.btn-primary.focus,.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{color:#ffffff;background-color:#0c7cd5;border-color:rgba(0,0,0,0)}.btn-primary:active,.btn-primary.active,.open>.dropdown-toggle.btn-primary{background-image:none}.btn-primary.disabled,.btn-primary[disabled],fieldset[disabled] .btn-primary,.btn-primary.disabled:hover,.btn-primary[disabled]:hover,fieldset[disabled] .btn-primary:hover,.btn-primary.disabled:focus,.btn-primary[disabled]:focus,fieldset[disabled] .btn-primary:focus,.btn-primary.disabled.focus,.btn-primary[disabled].focus,fieldset[disabled] .btn-primary.focus,.btn-primary.disabled:active,.btn-primary[disabled]:active,fieldset[disabled] .btn-primary:active,.btn-primary.disabled.active,.btn-primary[disabled].active,fieldset[disabled] .btn-primary.active{background-color:#2196f3;border-color:transparent}.btn-primary .badge{color:#2196f3;background-color:#ffffff}.btn-success{color:#ffffff;background-color:#4caf50;border-color:transparent}.btn-success:hover,.btn-success:focus,.btn-success.focus,.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{color:#ffffff;background-color:#3d8b40;border-color:rgba(0,0,0,0)}.btn-success:active,.btn-success.active,.open>.dropdown-toggle.btn-success{background-image:none}.btn-success.disabled,.btn-success[disabled],fieldset[disabled] .btn-success,.btn-success.disabled:hover,.btn-success[disabled]:hover,fieldset[disabled] .btn-success:hover,.btn-success.disabled:focus,.btn-success[disabled]:focus,fieldset[disabled] .btn-success:focus,.btn-success.disabled.focus,.btn-success[disabled].focus,fieldset[disabled] .btn-success.focus,.btn-success.disabled:active,.btn-success[disabled]:active,fieldset[disabled] .btn-success:active,.btn-success.disabled.active,.btn-success[disabled].active,fieldset[disabled] .btn-success.active{background-color:#4caf50;border-color:transparent}.btn-success .badge{color:#4caf50;background-color:#ffffff}.btn-info{color:#ffffff;background-color:#9c27b0;border-color:transparent}.btn-info:hover,.btn-info:focus,.btn-info.focus,.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{color:#ffffff;background-color:#771e86;border-color:rgba(0,0,0,0)}.btn-info:active,.btn-info.active,.open>.dropdown-toggle.btn-info{background-image:none}.btn-info.disabled,.btn-info[disabled],fieldset[disabled] .btn-info,.btn-info.disabled:hover,.btn-info[disabled]:hover,fieldset[disabled] .btn-info:hover,.btn-info.disabled:focus,.btn-info[disabled]:focus,fieldset[disabled] .btn-info:focus,.btn-info.disabled.focus,.btn-info[disabled].focus,fieldset[disabled] .btn-info.focus,.btn-info.disabled:active,.btn-info[disabled]:active,fieldset[disabled] .btn-info:active,.btn-info.disabled.active,.btn-info[disabled].active,fieldset[disabled] .btn-info.active{background-color:#9c27b0;border-color:transparent}.btn-info .badge{color:#9c27b0;background-color:#ffffff}.btn-warning{color:#ffffff;background-color:#ff9800;border-color:transparent}.btn-warning:hover,.btn-warning:focus,.btn-warning.focus,.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{color:#ffffff;background-color:#cc7a00;border-color:rgba(0,0,0,0)}.btn-warning:active,.btn-warning.active,.open>.dropdown-toggle.btn-warning{background-image:none}.btn-warning.disabled,.btn-warning[disabled],fieldset[disabled] .btn-warning,.btn-warning.disabled:hover,.btn-warning[disabled]:hover,fieldset[disabled] .btn-warning:hover,.btn-warning.disabled:focus,.btn-warning[disabled]:focus,fieldset[disabled] .btn-warning:focus,.btn-warning.disabled.focus,.btn-warning[disabled].focus,fieldset[disabled] .btn-warning.focus,.btn-warning.disabled:active,.btn-warning[disabled]:active,fieldset[disabled] .btn-warning:active,.btn-warning.disabled.active,.btn-warning[disabled].active,fieldset[disabled] .btn-warning.active{background-color:#ff9800;border-color:transparent}.btn-warning .badge{color:#ff9800;background-color:#ffffff}.btn-danger{color:#ffffff;background-color:#e51c23;border-color:transparent}.btn-danger:hover,.btn-danger:focus,.btn-danger.focus,.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{color:#ffffff;background-color:#b9151b;border-color:rgba(0,0,0,0)}.btn-danger:active,.btn-danger.active,.open>.dropdown-toggle.btn-danger{background-image:none}.btn-danger.disabled,.btn-danger[disabled],fieldset[disabled] .btn-danger,.btn-danger.disabled:hover,.btn-danger[disabled]:hover,fieldset[disabled] .btn-danger:hover,.btn-danger.disabled:focus,.btn-danger[disabled]:focus,fieldset[disabled] .btn-danger:focus,.btn-danger.disabled.focus,.btn-danger[disabled].focus,fieldset[disabled] .btn-danger.focus,.btn-danger.disabled:active,.btn-danger[disabled]:active,fieldset[disabled] .btn-danger:active,.btn-danger.disabled.active,.btn-danger[disabled].active,fieldset[disabled] .btn-danger.active{background-color:#e51c23;border-color:transparent}.btn-danger .badge{color:#e51c23;background-color:#ffffff}.btn-link{color:#2196f3;font-weight:normal;border-radius:0}.btn-link,.btn-link:active,.btn-link.active,.btn-link[disabled],fieldset[disabled] .btn-link{background-color:transparent;-webkit-box-shadow:none;box-shadow:none}.btn-link,.btn-link:hover,.btn-link:focus,.btn-link:active{border-color:transparent}.btn-link:hover,.btn-link:focus{color:#0a6ebd;text-decoration:underline;background-color:transparent}.btn-link[disabled]:hover,fieldset[disabled] .btn-link:hover,.btn-link[disabled]:focus,fieldset[disabled] .btn-link:focus{color:#bbbbbb;text-decoration:none}.btn-lg,.btn-group-lg>.btn{padding:10px 16px;font-size:17px;line-height:1.33;border-radius:3px}.btn-sm,.btn-group-sm>.btn{padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}.btn-xs,.btn-group-xs>.btn{padding:1px 5px;font-size:12px;line-height:1.5;border-radius:3px}.btn-block{display:block;width:100%}.btn-block+.btn-block{margin-top:5px}input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%}.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear}.fade.in{opacity:1}.collapse{display:none;visibility:hidden}.collapse.in{display:block;visibility:visible}tr.collapse.in{display:table-row}tbody.collapse.in{display:table-row-group}.collapsing{position:relative;height:0;overflow:hidden;-webkit-transition-property:height, visibility;-o-transition-property:height, visibility;transition-property:height, visibility;-webkit-transition-duration:0.35s;-o-transition-duration:0.35s;transition-duration:0.35s;-webkit-transition-timing-function:ease;-o-transition-timing-function:ease;transition-timing-function:ease}.caret{display:inline-block;width:0;height:0;margin-left:2px;vertical-align:middle;border-top:4px solid;border-right:4px solid transparent;border-left:4px solid transparent}.dropdown{position:relative}.dropdown-toggle:focus{outline:0}.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;font-size:13px;text-align:left;background-color:#ffffff;border:1px solid #cccccc;border:1px solid rgba(0,0,0,0.15);border-radius:3px;-webkit-box-shadow:0 6px 12px rgba(0,0,0,0.175);box-shadow:0 6px 12px rgba(0,0,0,0.175);-webkit-background-clip:padding-box;background-clip:padding-box}.dropdown-menu.pull-right{right:0;left:auto}.dropdown-menu .divider{height:1px;margin:10.5px 0;overflow:hidden;background-color:#e5e5e5}.dropdown-menu>li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:1.846;color:#666666;white-space:nowrap}.dropdown-menu>li>a:hover,.dropdown-menu>li>a:focus{text-decoration:none;color:#141414;background-color:#eeeeee}.dropdown-menu>.active>a,.dropdown-menu>.active>a:hover,.dropdown-menu>.active>a:focus{color:#ffffff;text-decoration:none;outline:0;background-color:#2196f3}.dropdown-menu>.disabled>a,.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{color:#bbbbbb}.dropdown-menu>.disabled>a:hover,.dropdown-menu>.disabled>a:focus{text-decoration:none;background-color:transparent;background-image:none;filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);cursor:not-allowed}.open>.dropdown-menu{display:block}.open>a{outline:0}.dropdown-menu-right{left:auto;right:0}.dropdown-menu-left{left:0;right:auto}.dropdown-header{display:block;padding:3px 20px;font-size:12px;line-height:1.846;color:#bbbbbb;white-space:nowrap}.dropdown-backdrop{position:fixed;left:0;right:0;bottom:0;top:0;z-index:990}.pull-right>.dropdown-menu{right:0;left:auto}.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid;content:""}.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px}@media (min-width:768px){.navbar-right .dropdown-menu{left:auto;right:0}.navbar-right .dropdown-menu-left{left:0;right:auto}}.btn-group,.btn-group-vertical{position:relative;display:inline-block;vertical-align:middle}.btn-group>.btn,.btn-group-vertical>.btn{position:relative;float:left}.btn-group>.btn:hover,.btn-group-vertical>.btn:hover,.btn-group>.btn:focus,.btn-group-vertical>.btn:focus,.btn-group>.btn:active,.btn-group-vertical>.btn:active,.btn-group>.btn.active,.btn-group-vertical>.btn.active{z-index:2}.btn-group .btn+.btn,.btn-group .btn+.btn-group,.btn-group .btn-group+.btn,.btn-group .btn-group+.btn-group{margin-left:-1px}.btn-toolbar{margin-left:-5px}.btn-toolbar .btn-group,.btn-toolbar .input-group{float:left}.btn-toolbar>.btn,.btn-toolbar>.btn-group,.btn-toolbar>.input-group{margin-left:5px}.btn-group>.btn:not(:first-child):not(:last-child):not(.dropdown-toggle){border-radius:0}.btn-group>.btn:first-child{margin-left:0}.btn-group>.btn:first-child:not(:last-child):not(.dropdown-toggle){border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn:last-child:not(:first-child),.btn-group>.dropdown-toggle:not(:first-child){border-bottom-left-radius:0;border-top-left-radius:0}.btn-group>.btn-group{float:left}.btn-group>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group>.btn-group:first-child>.btn:last-child,.btn-group>.btn-group:first-child>.dropdown-toggle{border-bottom-right-radius:0;border-top-right-radius:0}.btn-group>.btn-group:last-child>.btn:first-child{border-bottom-left-radius:0;border-top-left-radius:0}.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0}.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px}.btn-group>.btn-lg+.dropdown-toggle{padding-left:12px;padding-right:12px}.btn-group.open .dropdown-toggle{-webkit-box-shadow:inset 0 3px 5px rgba(0,0,0,0.125);box-shadow:inset 0 3px 5px rgba(0,0,0,0.125)}.btn-group.open .dropdown-toggle.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn .caret{margin-left:0}.btn-lg .caret{border-width:5px 5px 0;border-bottom-width:0}.dropup .btn-lg .caret{border-width:0 5px 5px}.btn-group-vertical>.btn,.btn-group-vertical>.btn-group,.btn-group-vertical>.btn-group>.btn{display:block;float:none;width:100%;max-width:100%}.btn-group-vertical>.btn-group>.btn{float:none}.btn-group-vertical>.btn+.btn,.btn-group-vertical>.btn+.btn-group,.btn-group-vertical>.btn-group+.btn,.btn-group-vertical>.btn-group+.btn-group{margin-top:-1px;margin-left:0}.btn-group-vertical>.btn:not(:first-child):not(:last-child){border-radius:0}.btn-group-vertical>.btn:first-child:not(:last-child){border-top-right-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn:last-child:not(:first-child){border-bottom-left-radius:3px;border-top-right-radius:0;border-top-left-radius:0}.btn-group-vertical>.btn-group:not(:first-child):not(:last-child)>.btn{border-radius:0}.btn-group-vertical>.btn-group:first-child:not(:last-child)>.btn:last-child,.btn-group-vertical>.btn-group:first-child:not(:last-child)>.dropdown-toggle{border-bottom-right-radius:0;border-bottom-left-radius:0}.btn-group-vertical>.btn-group:last-child:not(:first-child)>.btn:first-child{border-top-right-radius:0;border-top-left-radius:0}.btn-group-justified{display:table;width:100%;table-layout:fixed;border-collapse:separate}.btn-group-justified>.btn,.btn-group-justified>.btn-group{float:none;display:table-cell;width:1%}.btn-group-justified>.btn-group .btn{width:100%}.btn-group-justified>.btn-group .dropdown-menu{left:auto}[data-toggle="buttons"]>.btn input[type="radio"],[data-toggle="buttons"]>.btn-group>.btn input[type="radio"],[data-toggle="buttons"]>.btn input[type="checkbox"],[data-toggle="buttons"]>.btn-group>.btn input[type="checkbox"]{position:absolute;clip:rect(0, 0, 0, 0);pointer-events:none}.input-group{position:relative;display:table;border-collapse:separate}.input-group[class*="col-"]{float:none;padding-left:0;padding-right:0}.input-group .form-control{position:relative;z-index:2;float:left;width:100%;margin-bottom:0}.input-group-lg>.form-control,.input-group-lg>.input-group-addon,.input-group-lg>.input-group-btn>.btn{height:45px;padding:10px 16px;font-size:17px;line-height:1.33;border-radius:3px}select.input-group-lg>.form-control,select.input-group-lg>.input-group-addon,select.input-group-lg>.input-group-btn>.btn{height:45px;line-height:45px}textarea.input-group-lg>.form-control,textarea.input-group-lg>.input-group-addon,textarea.input-group-lg>.input-group-btn>.btn,select[multiple].input-group-lg>.form-control,select[multiple].input-group-lg>.input-group-addon,select[multiple].input-group-lg>.input-group-btn>.btn{height:auto}.input-group-sm>.form-control,.input-group-sm>.input-group-addon,.input-group-sm>.input-group-btn>.btn{height:30px;padding:5px 10px;font-size:12px;line-height:1.5;border-radius:3px}select.input-group-sm>.form-control,select.input-group-sm>.input-group-addon,select.input-group-sm>.input-group-btn>.btn{height:30px;line-height:30px}textarea.input-group-sm>.form-control,textarea.input-group-sm>.input-group-addon,textarea.input-group-sm>.input-group-btn>.btn,select[multiple].input-group-sm>.form-control,select[multiple].input-group-sm>.input-group-addon,select[multiple].input-group-sm>.input-group-btn>.btn{height:auto}.input-group-addon,.input-group-btn,.input-group .form-control{display:table-cell}.input-group-addon:not(:first-child):not(:last-child),.input-group-btn:not(:first-child):not(:last-child),.input-group .form-control:not(:first-child):not(:last-child){border-radius:0}.input-group-addon,.input-group-btn{width:1%;white-space:nowrap;vertical-align:middle}.input-group-addon{padding:6px 16px;font-size:13px;font-weight:normal;line-height:1;color:#666666;text-align:center;background-color:transparent;border:1px solid transparent;border-radius:3px}.input-group-addon.input-sm{padding:5px 10px;font-size:12px;border-radius:3px}.input-group-addon.input-lg{padding:10px 16px;font-size:17px;border-radius:3px}.input-group-addon input[type="radio"],.input-group-addon input[type="checkbox"]{margin-top:0}.input-group .form-control:first-child,.input-group-addon:first-child,.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group>.btn,.input-group-btn:first-child>.dropdown-toggle,.input-group-btn:last-child>.btn:not(:last-child):not(.dropdown-toggle),.input-group-btn:last-child>.btn-group:not(:last-child)>.btn{border-bottom-right-radius:0;border-top-right-radius:0}.input-group-addon:first-child{border-right:0}.input-group .form-control:last-child,.input-group-addon:last-child,.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group>.btn,.input-group-btn:last-child>.dropdown-toggle,.input-group-btn:first-child>.btn:not(:first-child),.input-group-btn:first-child>.btn-group:not(:first-child)>.btn{border-bottom-left-radius:0;border-top-left-radius:0}.input-group-addon:last-child{border-left:0}.input-group-btn{position:relative;font-size:0;white-space:nowrap}.input-group-btn>.btn{position:relative}.input-group-btn>.btn+.btn{margin-left:-1px}.input-group-btn>.btn:hover,.input-group-btn>.btn:focus,.input-group-btn>.btn:active{z-index:2}.input-group-btn:first-child>.btn,.input-group-btn:first-child>.btn-group{margin-right:-1px}.input-group-btn:last-child>.btn,.input-group-btn:last-child>.btn-group{margin-left:-1px}.nav{margin-bottom:0;padding-left:0;list-style:none}.nav>li{position:relative;display:block}.nav>li>a{position:relative;display:block;padding:10px 15px}.nav>li>a:hover,.nav>li>a:focus{text-decoration:none;background-color:#eeeeee}.nav>li.disabled>a{color:#bbbbbb}.nav>li.disabled>a:hover,.nav>li.disabled>a:focus{color:#bbbbbb;text-decoration:none;background-color:transparent;cursor:not-allowed}.nav .open>a,.nav .open>a:hover,.nav .open>a:focus{background-color:#eeeeee;border-color:#2196f3}.nav .nav-divider{height:1px;margin:10.5px 0;overflow:hidden;background-color:#e5e5e5}.nav>li>a>img{max-width:none}.nav-tabs{border-bottom:1px solid transparent}.nav-tabs>li{float:left;margin-bottom:-1px}.nav-tabs>li>a{margin-right:2px;line-height:1.846;border:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee transparent}.nav-tabs>li.active>a,.nav-tabs>li.active>a:hover,.nav-tabs>li.active>a:focus{color:#666666;background-color:transparent;border:1px solid transparent;border-bottom-color:transparent;cursor:default}.nav-tabs.nav-justified{width:100%;border-bottom:0}.nav-tabs.nav-justified>li{float:none}.nav-tabs.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-tabs.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-tabs.nav-justified>li{display:table-cell;width:1%}.nav-tabs.nav-justified>li>a{margin-bottom:0}}.nav-tabs.nav-justified>li>a{margin-right:0;border-radius:3px}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border:1px solid transparent}@media (min-width:768px){.nav-tabs.nav-justified>li>a{border-bottom:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover,.nav-tabs.nav-justified>.active>a:focus{border-bottom-color:#ffffff}}.nav-pills>li{float:left}.nav-pills>li>a{border-radius:3px}.nav-pills>li+li{margin-left:2px}.nav-pills>li.active>a,.nav-pills>li.active>a:hover,.nav-pills>li.active>a:focus{color:#ffffff;background-color:#2196f3}.nav-stacked>li{float:none}.nav-stacked>li+li{margin-top:2px;margin-left:0}.nav-justified{width:100%}.nav-justified>li{float:none}.nav-justified>li>a{text-align:center;margin-bottom:5px}.nav-justified>.dropdown .dropdown-menu{top:auto;left:auto}@media (min-width:768px){.nav-justified>li{display:table-cell;width:1%}.nav-justified>li>a{margin-bottom:0}}.nav-tabs-justified{border-bottom:0}.nav-tabs-justified>li>a{margin-right:0;border-radius:3px}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border:1px solid transparent}@media (min-width:768px){.nav-tabs-justified>li>a{border-bottom:1px solid transparent;border-radius:3px 3px 0 0}.nav-tabs-justified>.active>a,.nav-tabs-justified>.active>a:hover,.nav-tabs-justified>.active>a:focus{border-bottom-color:#ffffff}}.tab-content>.tab-pane{display:none;visibility:hidden}.tab-content>.active{display:block;visibility:visible}.nav-tabs .dropdown-menu{margin-top:-1px;border-top-right-radius:0;border-top-left-radius:0}.navbar{position:relative;min-height:64px;margin-bottom:23px;border:1px solid transparent}@media (min-width:768px){.navbar{border-radius:3px}}@media (min-width:768px){.navbar-header{float:left}}.navbar-collapse{overflow-x:visible;padding-right:15px;padding-left:15px;border-top:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1);-webkit-overflow-scrolling:touch}.navbar-collapse.in{overflow-y:auto}@media (min-width:768px){.navbar-collapse{width:auto;border-top:0;-webkit-box-shadow:none;box-shadow:none}.navbar-collapse.collapse{display:block !important;visibility:visible !important;height:auto !important;padding-bottom:0;overflow:visible !important}.navbar-collapse.in{overflow-y:visible}.navbar-fixed-top .navbar-collapse,.navbar-static-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{padding-left:0;padding-right:0}}.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:340px}@media (max-device-width:480px) and (orientation:landscape){.navbar-fixed-top .navbar-collapse,.navbar-fixed-bottom .navbar-collapse{max-height:200px}}.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:-15px;margin-left:-15px}@media (min-width:768px){.container>.navbar-header,.container-fluid>.navbar-header,.container>.navbar-collapse,.container-fluid>.navbar-collapse{margin-right:0;margin-left:0}}.navbar-static-top{z-index:1000;border-width:0 0 1px}@media (min-width:768px){.navbar-static-top{border-radius:0}}.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030}@media (min-width:768px){.navbar-fixed-top,.navbar-fixed-bottom{border-radius:0}}.navbar-fixed-top{top:0;border-width:0 0 1px}.navbar-fixed-bottom{bottom:0;margin-bottom:0;border-width:1px 0 0}.navbar-brand{float:left;padding:20.5px 15px;font-size:17px;line-height:23px;height:64px}.navbar-brand:hover,.navbar-brand:focus{text-decoration:none}.navbar-brand>img{display:block}@media (min-width:768px){.navbar>.container .navbar-brand,.navbar>.container-fluid .navbar-brand{margin-left:-15px}}.navbar-toggle{position:relative;float:right;margin-right:15px;padding:9px 10px;margin-top:15px;margin-bottom:15px;background-color:transparent;background-image:none;border:1px solid transparent;border-radius:3px}.navbar-toggle:focus{outline:0}.navbar-toggle .icon-bar{display:block;width:22px;height:2px;border-radius:1px}.navbar-toggle .icon-bar+.icon-bar{margin-top:4px}@media (min-width:768px){.navbar-toggle{display:none}}.navbar-nav{margin:10.25px -15px}.navbar-nav>li>a{padding-top:10px;padding-bottom:10px;line-height:23px}@media (max-width:767px){.navbar-nav .open .dropdown-menu{position:static;float:none;width:auto;margin-top:0;background-color:transparent;border:0;-webkit-box-shadow:none;box-shadow:none}.navbar-nav .open .dropdown-menu>li>a,.navbar-nav .open .dropdown-menu .dropdown-header{padding:5px 15px 5px 25px}.navbar-nav .open .dropdown-menu>li>a{line-height:23px}.navbar-nav .open .dropdown-menu>li>a:hover,.navbar-nav .open .dropdown-menu>li>a:focus{background-image:none}}@media (min-width:768px){.navbar-nav{float:left;margin:0}.navbar-nav>li{float:left}.navbar-nav>li>a{padding-top:20.5px;padding-bottom:20.5px}}.navbar-form{margin-left:-15px;margin-right:-15px;padding:10px 15px;border-top:1px solid transparent;border-bottom:1px solid transparent;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);box-shadow:inset 0 1px 0 rgba(255,255,255,0.1),0 1px 0 rgba(255,255,255,0.1);margin-top:13.5px;margin-bottom:13.5px}@media (min-width:768px){.navbar-form .form-group{display:inline-block;margin-bottom:0;vertical-align:middle}.navbar-form .form-control{display:inline-block;width:auto;vertical-align:middle}.navbar-form .form-control-static{display:inline-block}.navbar-form .input-group{display:inline-table;vertical-align:middle}.navbar-form .input-group .input-group-addon,.navbar-form .input-group .input-group-btn,.navbar-form .input-group .form-control{width:auto}.navbar-form .input-group>.form-control{width:100%}.navbar-form .control-label{margin-bottom:0;vertical-align:middle}.navbar-form .radio,.navbar-form .checkbox{display:inline-block;margin-top:0;margin-bottom:0;vertical-align:middle}.navbar-form .radio label,.navbar-form .checkbox label{padding-left:0}.navbar-form .radio input[type="radio"],.navbar-form .checkbox input[type="checkbox"]{position:relative;margin-left:0}.navbar-form .has-feedback .form-control-feedback{top:0}}@media (max-width:767px){.navbar-form .form-group{margin-bottom:5px}.navbar-form .form-group:last-child{margin-bottom:0}}@media (min-width:768px){.navbar-form{width:auto;border:0;margin-left:0;margin-right:0;padding-top:0;padding-bottom:0;-webkit-box-shadow:none;box-shadow:none}}.navbar-nav>li>.dropdown-menu{margin-top:0;border-top-right-radius:0;border-top-left-radius:0}.navbar-fixed-bottom .navbar-nav>li>.dropdown-menu{border-top-right-radius:3px;border-top-left-radius:3px;border-bottom-right-radius:0;border-bottom-left-radius:0}.navbar-btn{margin-top:13.5px;margin-bottom:13.5px}.navbar-btn.btn-sm{margin-top:17px;margin-bottom:17px}.navbar-btn.btn-xs{margin-top:21px;margin-bottom:21px}.navbar-text{margin-top:20.5px;margin-bottom:20.5px}@media (min-width:768px){.navbar-text{float:left;margin-left:15px;margin-right:15px}}@media (min-width:768px){.navbar-left{float:left !important}.navbar-right{float:right !important;margin-right:-15px}.navbar-right~.navbar-right{margin-right:0}}.navbar-default{background-color:#ffffff;border-color:transparent}.navbar-default .navbar-brand{color:#666666}.navbar-default .navbar-brand:hover,.navbar-default .navbar-brand:focus{color:#212121;background-color:transparent}.navbar-default .navbar-text{color:#bbbbbb}.navbar-default .navbar-nav>li>a{color:#666666}.navbar-default .navbar-nav>li>a:hover,.navbar-default .navbar-nav>li>a:focus{color:#212121;background-color:transparent}.navbar-default .navbar-nav>.active>a,.navbar-default .navbar-nav>.active>a:hover,.navbar-default .navbar-nav>.active>a:focus{color:#212121;background-color:#eeeeee}.navbar-default .navbar-nav>.disabled>a,.navbar-default .navbar-nav>.disabled>a:hover,.navbar-default .navbar-nav>.disabled>a:focus{color:#cccccc;background-color:transparent}.navbar-default .navbar-toggle{border-color:transparent}.navbar-default .navbar-toggle:hover,.navbar-default .navbar-toggle:focus{background-color:transparent}.navbar-default .navbar-toggle .icon-bar{background-color:rgba(0,0,0,0.5)}.navbar-default .navbar-collapse,.navbar-default .navbar-form{border-color:transparent}.navbar-default .navbar-nav>.open>a,.navbar-default .navbar-nav>.open>a:hover,.navbar-default .navbar-nav>.open>a:focus{background-color:#eeeeee;color:#212121}@media (max-width:767px){.navbar-default .navbar-nav .open .dropdown-menu>li>a{color:#666666}.navbar-default .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>li>a:focus{color:#212121;background-color:transparent}.navbar-default .navbar-nav .open .dropdown-menu>.active>a,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.active>a:focus{color:#212121;background-color:#eeeeee}.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-default .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#cccccc;background-color:transparent}}.navbar-default .navbar-link{color:#666666}.navbar-default .navbar-link:hover{color:#212121}.navbar-default .btn-link{color:#666666}.navbar-default .btn-link:hover,.navbar-default .btn-link:focus{color:#212121}.navbar-default .btn-link[disabled]:hover,fieldset[disabled] .navbar-default .btn-link:hover,.navbar-default .btn-link[disabled]:focus,fieldset[disabled] .navbar-default .btn-link:focus{color:#cccccc}.navbar-inverse{background-color:#2196f3;border-color:transparent}.navbar-inverse .navbar-brand{color:#b2dbfb}.navbar-inverse .navbar-brand:hover,.navbar-inverse .navbar-brand:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-text{color:#bbbbbb}.navbar-inverse .navbar-nav>li>a{color:#b2dbfb}.navbar-inverse .navbar-nav>li>a:hover,.navbar-inverse .navbar-nav>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav>.active>a,.navbar-inverse .navbar-nav>.active>a:hover,.navbar-inverse .navbar-nav>.active>a:focus{color:#ffffff;background-color:#0c7cd5}.navbar-inverse .navbar-nav>.disabled>a,.navbar-inverse .navbar-nav>.disabled>a:hover,.navbar-inverse .navbar-nav>.disabled>a:focus{color:#444444;background-color:transparent}.navbar-inverse .navbar-toggle{border-color:transparent}.navbar-inverse .navbar-toggle:hover,.navbar-inverse .navbar-toggle:focus{background-color:transparent}.navbar-inverse .navbar-toggle .icon-bar{background-color:rgba(0,0,0,0.5)}.navbar-inverse .navbar-collapse,.navbar-inverse .navbar-form{border-color:#0c84e4}.navbar-inverse .navbar-nav>.open>a,.navbar-inverse .navbar-nav>.open>a:hover,.navbar-inverse .navbar-nav>.open>a:focus{background-color:#0c7cd5;color:#ffffff}@media (max-width:767px){.navbar-inverse .navbar-nav .open .dropdown-menu>.dropdown-header{border-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu .divider{background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a{color:#b2dbfb}.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>li>a:focus{color:#ffffff;background-color:transparent}.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.active>a:focus{color:#ffffff;background-color:#0c7cd5}.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:hover,.navbar-inverse .navbar-nav .open .dropdown-menu>.disabled>a:focus{color:#444444;background-color:transparent}}.navbar-inverse .navbar-link{color:#b2dbfb}.navbar-inverse .navbar-link:hover{color:#ffffff}.navbar-inverse .btn-link{color:#b2dbfb}.navbar-inverse .btn-link:hover,.navbar-inverse .btn-link:focus{color:#ffffff}.navbar-inverse .btn-link[disabled]:hover,fieldset[disabled] .navbar-inverse .btn-link:hover,.navbar-inverse .btn-link[disabled]:focus,fieldset[disabled] .navbar-inverse .btn-link:focus{color:#444444}.breadcrumb{padding:8px 15px;margin-bottom:23px;list-style:none;background-color:#f5f5f5;border-radius:3px}.breadcrumb>li{display:inline-block}.breadcrumb>li+li:before{content:"/\00a0";padding:0 5px;color:#cccccc}.breadcrumb>.active{color:#bbbbbb}.pagination{display:inline-block;padding-left:0;margin:23px 0;border-radius:3px}.pagination>li{display:inline}.pagination>li>a,.pagination>li>span{position:relative;float:left;padding:6px 16px;line-height:1.846;text-decoration:none;color:#2196f3;background-color:#ffffff;border:1px solid #dddddd;margin-left:-1px}.pagination>li:first-child>a,.pagination>li:first-child>span{margin-left:0;border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination>li:last-child>a,.pagination>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination>li>a:hover,.pagination>li>span:hover,.pagination>li>a:focus,.pagination>li>span:focus{color:#0a6ebd;background-color:#eeeeee;border-color:#dddddd}.pagination>.active>a,.pagination>.active>span,.pagination>.active>a:hover,.pagination>.active>span:hover,.pagination>.active>a:focus,.pagination>.active>span:focus{z-index:2;color:#ffffff;background-color:#2196f3;border-color:#2196f3;cursor:default}.pagination>.disabled>span,.pagination>.disabled>span:hover,.pagination>.disabled>span:focus,.pagination>.disabled>a,.pagination>.disabled>a:hover,.pagination>.disabled>a:focus{color:#bbbbbb;background-color:#ffffff;border-color:#dddddd;cursor:not-allowed}.pagination-lg>li>a,.pagination-lg>li>span{padding:10px 16px;font-size:17px}.pagination-lg>li:first-child>a,.pagination-lg>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-lg>li:last-child>a,.pagination-lg>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pagination-sm>li>a,.pagination-sm>li>span{padding:5px 10px;font-size:12px}.pagination-sm>li:first-child>a,.pagination-sm>li:first-child>span{border-bottom-left-radius:3px;border-top-left-radius:3px}.pagination-sm>li:last-child>a,.pagination-sm>li:last-child>span{border-bottom-right-radius:3px;border-top-right-radius:3px}.pager{padding-left:0;margin:23px 0;list-style:none;text-align:center}.pager li{display:inline}.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#ffffff;border:1px solid #dddddd;border-radius:15px}.pager li>a:hover,.pager li>a:focus{text-decoration:none;background-color:#eeeeee}.pager .next>a,.pager .next>span{float:right}.pager .previous>a,.pager .previous>span{float:left}.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>a:focus,.pager .disabled>span{color:#bbbbbb;background-color:#ffffff;cursor:not-allowed}.label{display:inline;padding:.2em .6em .3em;font-size:75%;font-weight:bold;line-height:1;color:#ffffff;text-align:center;white-space:nowrap;vertical-align:baseline;border-radius:.25em}a.label:hover,a.label:focus{color:#ffffff;text-decoration:none;cursor:pointer}.label:empty{display:none}.btn .label{position:relative;top:-1px}.label-default{background-color:#bbbbbb}.label-default[href]:hover,.label-default[href]:focus{background-color:#a2a2a2}.label-primary{background-color:#2196f3}.label-primary[href]:hover,.label-primary[href]:focus{background-color:#0c7cd5}.label-success{background-color:#4caf50}.label-success[href]:hover,.label-success[href]:focus{background-color:#3d8b40}.label-info{background-color:#9c27b0}.label-info[href]:hover,.label-info[href]:focus{background-color:#771e86}.label-warning{background-color:#ff9800}.label-warning[href]:hover,.label-warning[href]:focus{background-color:#cc7a00}.label-danger{background-color:#e51c23}.label-danger[href]:hover,.label-danger[href]:focus{background-color:#b9151b}.badge{display:inline-block;min-width:10px;padding:3px 7px;font-size:12px;font-weight:normal;color:#ffffff;line-height:1;vertical-align:baseline;white-space:nowrap;text-align:center;background-color:#bbbbbb;border-radius:10px}.badge:empty{display:none}.btn .badge{position:relative;top:-1px}.btn-xs .badge{top:0;padding:1px 5px}a.badge:hover,a.badge:focus{color:#ffffff;text-decoration:none;cursor:pointer}.list-group-item.active>.badge,.nav-pills>.active>a>.badge{color:#2196f3;background-color:#ffffff}.list-group-item>.badge{float:right}.list-group-item>.badge+.badge{margin-right:5px}.nav-pills>li>a>.badge{margin-left:3px}.jumbotron{padding:30px 15px;margin-bottom:30px;color:inherit;background-color:#f9f9f9}.jumbotron h1,.jumbotron .h1{color:#444444}.jumbotron p{margin-bottom:15px;font-size:20px;font-weight:200}.jumbotron>hr{border-top-color:#e0e0e0}.container .jumbotron,.container-fluid .jumbotron{border-radius:3px}.jumbotron .container{max-width:100%}@media screen and (min-width:768px){.jumbotron{padding:48px 0}.container .jumbotron,.container-fluid .jumbotron{padding-left:60px;padding-right:60px}.jumbotron h1,.jumbotron .h1{font-size:58.5px}}.thumbnail{display:block;padding:4px;margin-bottom:23px;line-height:1.846;background-color:#ffffff;border:1px solid #dddddd;border-radius:3px;-webkit-transition:border .2s ease-in-out;-o-transition:border .2s ease-in-out;transition:border .2s ease-in-out}.thumbnail>img,.thumbnail a>img{margin-left:auto;margin-right:auto}a.thumbnail:hover,a.thumbnail:focus,a.thumbnail.active{border-color:#2196f3}.thumbnail .caption{padding:9px;color:#666666}.alert{padding:15px;margin-bottom:23px;border:1px solid transparent;border-radius:3px}.alert h4{margin-top:0;color:inherit}.alert .alert-link{font-weight:bold}.alert>p,.alert>ul{margin-bottom:0}.alert>p+p{margin-top:5px}.alert-dismissable,.alert-dismissible{padding-right:35px}.alert-dismissable .close,.alert-dismissible .close{position:relative;top:-2px;right:-21px;color:inherit}.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#4caf50}.alert-success hr{border-top-color:#c9e2b3}.alert-success .alert-link{color:#3d8b40}.alert-info{background-color:#e1bee7;border-color:#cba4dd;color:#9c27b0}.alert-info hr{border-top-color:#c191d6}.alert-info .alert-link{color:#771e86}.alert-warning{background-color:#ffe0b2;border-color:#ffc599;color:#ff9800}.alert-warning hr{border-top-color:#ffb67f}.alert-warning .alert-link{color:#cc7a00}.alert-danger{background-color:#f9bdbb;border-color:#f7a4af;color:#e51c23}.alert-danger hr{border-top-color:#f58c9a}.alert-danger .alert-link{color:#b9151b}@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@-o-keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}@keyframes progress-bar-stripes{from{background-position:40px 0}to{background-position:0 0}}.progress{overflow:hidden;height:23px;margin-bottom:23px;background-color:#f5f5f5;border-radius:3px;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1);box-shadow:inset 0 1px 2px rgba(0,0,0,0.1)}.progress-bar{float:left;width:0%;height:100%;font-size:12px;line-height:23px;color:#ffffff;text-align:center;background-color:#2196f3;-webkit-box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);box-shadow:inset 0 -1px 0 rgba(0,0,0,0.15);-webkit-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease}.progress-striped .progress-bar,.progress-bar-striped{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;background-size:40px 40px}.progress.active .progress-bar,.progress-bar.active{-webkit-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite}.progress-bar-success{background-color:#4caf50}.progress-striped .progress-bar-success{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-info{background-color:#9c27b0}.progress-striped .progress-bar-info{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-warning{background-color:#ff9800}.progress-striped .progress-bar-warning{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.progress-bar-danger{background-color:#e51c23}.progress-striped .progress-bar-danger{background-image:-webkit-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255,255,255,0.15) 25%, transparent 25%, transparent 50%, rgba(255,255,255,0.15) 50%, rgba(255,255,255,0.15) 75%, transparent 75%, transparent)}.media{margin-top:15px}.media:first-child{margin-top:0}.media-right,.media>.pull-right{padding-left:10px}.media-left,.media>.pull-left{padding-right:10px}.media-left,.media-right,.media-body{display:table-cell;vertical-align:top}.media-middle{vertical-align:middle}.media-bottom{vertical-align:bottom}.media-heading{margin-top:0;margin-bottom:5px}.media-list{padding-left:0;list-style:none}.list-group{margin-bottom:20px;padding-left:0}.list-group-item{position:relative;display:block;padding:10px 15px;margin-bottom:-1px;background-color:#ffffff;border:1px solid #dddddd}.list-group-item:first-child{border-top-right-radius:3px;border-top-left-radius:3px}.list-group-item:last-child{margin-bottom:0;border-bottom-right-radius:3px;border-bottom-left-radius:3px}a.list-group-item{color:#555555}a.list-group-item .list-group-item-heading{color:#333333}a.list-group-item:hover,a.list-group-item:focus{text-decoration:none;color:#555555;background-color:#f5f5f5}.list-group-item.disabled,.list-group-item.disabled:hover,.list-group-item.disabled:focus{background-color:#eeeeee;color:#bbbbbb;cursor:not-allowed}.list-group-item.disabled .list-group-item-heading,.list-group-item.disabled:hover .list-group-item-heading,.list-group-item.disabled:focus .list-group-item-heading{color:inherit}.list-group-item.disabled .list-group-item-text,.list-group-item.disabled:hover .list-group-item-text,.list-group-item.disabled:focus .list-group-item-text{color:#bbbbbb}.list-group-item.active,.list-group-item.active:hover,.list-group-item.active:focus{z-index:2;color:#ffffff;background-color:#2196f3;border-color:#2196f3}.list-group-item.active .list-group-item-heading,.list-group-item.active:hover .list-group-item-heading,.list-group-item.active:focus .list-group-item-heading,.list-group-item.active .list-group-item-heading>small,.list-group-item.active:hover .list-group-item-heading>small,.list-group-item.active:focus .list-group-item-heading>small,.list-group-item.active .list-group-item-heading>.small,.list-group-item.active:hover .list-group-item-heading>.small,.list-group-item.active:focus .list-group-item-heading>.small{color:inherit}.list-group-item.active .list-group-item-text,.list-group-item.active:hover .list-group-item-text,.list-group-item.active:focus .list-group-item-text{color:#e3f2fd}.list-group-item-success{color:#4caf50;background-color:#dff0d8}a.list-group-item-success{color:#4caf50}a.list-group-item-success .list-group-item-heading{color:inherit}a.list-group-item-success:hover,a.list-group-item-success:focus{color:#4caf50;background-color:#d0e9c6}a.list-group-item-success.active,a.list-group-item-success.active:hover,a.list-group-item-success.active:focus{color:#fff;background-color:#4caf50;border-color:#4caf50}.list-group-item-info{color:#9c27b0;background-color:#e1bee7}a.list-group-item-info{color:#9c27b0}a.list-group-item-info .list-group-item-heading{color:inherit}a.list-group-item-info:hover,a.list-group-item-info:focus{color:#9c27b0;background-color:#d8abe0}a.list-group-item-info.active,a.list-group-item-info.active:hover,a.list-group-item-info.active:focus{color:#fff;background-color:#9c27b0;border-color:#9c27b0}.list-group-item-warning{color:#ff9800;background-color:#ffe0b2}a.list-group-item-warning{color:#ff9800}a.list-group-item-warning .list-group-item-heading{color:inherit}a.list-group-item-warning:hover,a.list-group-item-warning:focus{color:#ff9800;background-color:#ffd699}a.list-group-item-warning.active,a.list-group-item-warning.active:hover,a.list-group-item-warning.active:focus{color:#fff;background-color:#ff9800;border-color:#ff9800}.list-group-item-danger{color:#e51c23;background-color:#f9bdbb}a.list-group-item-danger{color:#e51c23}a.list-group-item-danger .list-group-item-heading{color:inherit}a.list-group-item-danger:hover,a.list-group-item-danger:focus{color:#e51c23;background-color:#f7a6a4}a.list-group-item-danger.active,a.list-group-item-danger.active:hover,a.list-group-item-danger.active:focus{color:#fff;background-color:#e51c23;border-color:#e51c23}.list-group-item-heading{margin-top:0;margin-bottom:5px}.list-group-item-text{margin-bottom:0;line-height:1.3}.panel{margin-bottom:23px;background-color:#ffffff;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 1px 1px rgba(0,0,0,0.05);box-shadow:0 1px 1px rgba(0,0,0,0.05)}.panel-body{padding:15px}.panel-heading{padding:10px 15px;border-bottom:1px solid transparent;border-top-right-radius:2px;border-top-left-radius:2px}.panel-heading>.dropdown .dropdown-toggle{color:inherit}.panel-title{margin-top:0;margin-bottom:0;font-size:15px;color:inherit}.panel-title>a{color:inherit}.panel-footer{padding:10px 15px;background-color:#f5f5f5;border-top:1px solid #dddddd;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.panel>.list-group,.panel>.panel-collapse>.list-group{margin-bottom:0}.panel>.list-group .list-group-item,.panel>.panel-collapse>.list-group .list-group-item{border-width:1px 0;border-radius:0}.panel>.list-group:first-child .list-group-item:first-child,.panel>.panel-collapse>.list-group:first-child .list-group-item:first-child{border-top:0;border-top-right-radius:2px;border-top-left-radius:2px}.panel>.list-group:last-child .list-group-item:last-child,.panel>.panel-collapse>.list-group:last-child .list-group-item:last-child{border-bottom:0;border-bottom-right-radius:2px;border-bottom-left-radius:2px}.panel-heading+.list-group .list-group-item:first-child{border-top-width:0}.list-group+.panel-footer{border-top-width:0}.panel>.table,.panel>.table-responsive>.table,.panel>.panel-collapse>.table{margin-bottom:0}.panel>.table caption,.panel>.table-responsive>.table caption,.panel>.panel-collapse>.table caption{padding-left:15px;padding-right:15px}.panel>.table:first-child,.panel>.table-responsive:first-child>.table:first-child{border-top-right-radius:2px;border-top-left-radius:2px}.panel>.table:first-child>thead:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child{border-top-left-radius:2px;border-top-right-radius:2px}.panel>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:first-child,.panel>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:first-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:first-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:first-child{border-top-left-radius:2px}.panel>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child td:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child td:last-child,.panel>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>thead:first-child>tr:first-child th:last-child,.panel>.table:first-child>tbody:first-child>tr:first-child th:last-child,.panel>.table-responsive:first-child>.table:first-child>tbody:first-child>tr:first-child th:last-child{border-top-right-radius:2px}.panel>.table:last-child,.panel>.table-responsive:last-child>.table:last-child{border-bottom-right-radius:2px;border-bottom-left-radius:2px}.panel>.table:last-child>tbody:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child{border-bottom-left-radius:2px;border-bottom-right-radius:2px}.panel>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:first-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:first-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:first-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:first-child{border-bottom-left-radius:2px}.panel>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child td:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child td:last-child,.panel>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tbody:last-child>tr:last-child th:last-child,.panel>.table:last-child>tfoot:last-child>tr:last-child th:last-child,.panel>.table-responsive:last-child>.table:last-child>tfoot:last-child>tr:last-child th:last-child{border-bottom-right-radius:2px}.panel>.panel-body+.table,.panel>.panel-body+.table-responsive,.panel>.table+.panel-body,.panel>.table-responsive+.panel-body{border-top:1px solid #dddddd}.panel>.table>tbody:first-child>tr:first-child th,.panel>.table>tbody:first-child>tr:first-child td{border-top:0}.panel>.table-bordered,.panel>.table-responsive>.table-bordered{border:0}.panel>.table-bordered>thead>tr>th:first-child,.panel>.table-responsive>.table-bordered>thead>tr>th:first-child,.panel>.table-bordered>tbody>tr>th:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:first-child,.panel>.table-bordered>tfoot>tr>th:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:first-child,.panel>.table-bordered>thead>tr>td:first-child,.panel>.table-responsive>.table-bordered>thead>tr>td:first-child,.panel>.table-bordered>tbody>tr>td:first-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:first-child,.panel>.table-bordered>tfoot>tr>td:first-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:first-child{border-left:0}.panel>.table-bordered>thead>tr>th:last-child,.panel>.table-responsive>.table-bordered>thead>tr>th:last-child,.panel>.table-bordered>tbody>tr>th:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>th:last-child,.panel>.table-bordered>tfoot>tr>th:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>th:last-child,.panel>.table-bordered>thead>tr>td:last-child,.panel>.table-responsive>.table-bordered>thead>tr>td:last-child,.panel>.table-bordered>tbody>tr>td:last-child,.panel>.table-responsive>.table-bordered>tbody>tr>td:last-child,.panel>.table-bordered>tfoot>tr>td:last-child,.panel>.table-responsive>.table-bordered>tfoot>tr>td:last-child{border-right:0}.panel>.table-bordered>thead>tr:first-child>td,.panel>.table-responsive>.table-bordered>thead>tr:first-child>td,.panel>.table-bordered>tbody>tr:first-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>td,.panel>.table-bordered>thead>tr:first-child>th,.panel>.table-responsive>.table-bordered>thead>tr:first-child>th,.panel>.table-bordered>tbody>tr:first-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:first-child>th{border-bottom:0}.panel>.table-bordered>tbody>tr:last-child>td,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>td,.panel>.table-bordered>tfoot>tr:last-child>td,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>td,.panel>.table-bordered>tbody>tr:last-child>th,.panel>.table-responsive>.table-bordered>tbody>tr:last-child>th,.panel>.table-bordered>tfoot>tr:last-child>th,.panel>.table-responsive>.table-bordered>tfoot>tr:last-child>th{border-bottom:0}.panel>.table-responsive{border:0;margin-bottom:0}.panel-group{margin-bottom:23px}.panel-group .panel{margin-bottom:0;border-radius:3px}.panel-group .panel+.panel{margin-top:5px}.panel-group .panel-heading{border-bottom:0}.panel-group .panel-heading+.panel-collapse>.panel-body,.panel-group .panel-heading+.panel-collapse>.list-group{border-top:1px solid #dddddd}.panel-group .panel-footer{border-top:0}.panel-group .panel-footer+.panel-collapse .panel-body{border-bottom:1px solid #dddddd}.panel-default{border-color:#dddddd}.panel-default>.panel-heading{color:#212121;background-color:#f5f5f5;border-color:#dddddd}.panel-default>.panel-heading+.panel-collapse>.panel-body{border-top-color:#dddddd}.panel-default>.panel-heading .badge{color:#f5f5f5;background-color:#212121}.panel-default>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#dddddd}.panel-primary{border-color:#2196f3}.panel-primary>.panel-heading{color:#ffffff;background-color:#2196f3;border-color:#2196f3}.panel-primary>.panel-heading+.panel-collapse>.panel-body{border-top-color:#2196f3}.panel-primary>.panel-heading .badge{color:#2196f3;background-color:#ffffff}.panel-primary>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#2196f3}.panel-success{border-color:#d6e9c6}.panel-success>.panel-heading{color:#4caf50;background-color:#dff0d8;border-color:#d6e9c6}.panel-success>.panel-heading+.panel-collapse>.panel-body{border-top-color:#d6e9c6}.panel-success>.panel-heading .badge{color:#dff0d8;background-color:#4caf50}.panel-success>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#d6e9c6}.panel-info{border-color:#cba4dd}.panel-info>.panel-heading{color:#9c27b0;background-color:#e1bee7;border-color:#cba4dd}.panel-info>.panel-heading+.panel-collapse>.panel-body{border-top-color:#cba4dd}.panel-info>.panel-heading .badge{color:#e1bee7;background-color:#9c27b0}.panel-info>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#cba4dd}.panel-warning{border-color:#ffc599}.panel-warning>.panel-heading{color:#ff9800;background-color:#ffe0b2;border-color:#ffc599}.panel-warning>.panel-heading+.panel-collapse>.panel-body{border-top-color:#ffc599}.panel-warning>.panel-heading .badge{color:#ffe0b2;background-color:#ff9800}.panel-warning>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#ffc599}.panel-danger{border-color:#f7a4af}.panel-danger>.panel-heading{color:#e51c23;background-color:#f9bdbb;border-color:#f7a4af}.panel-danger>.panel-heading+.panel-collapse>.panel-body{border-top-color:#f7a4af}.panel-danger>.panel-heading .badge{color:#f9bdbb;background-color:#e51c23}.panel-danger>.panel-footer+.panel-collapse>.panel-body{border-bottom-color:#f7a4af}.embed-responsive{position:relative;display:block;height:0;padding:0;overflow:hidden}.embed-responsive .embed-responsive-item,.embed-responsive iframe,.embed-responsive embed,.embed-responsive object,.embed-responsive video{position:absolute;top:0;left:0;bottom:0;height:100%;width:100%;border:0}.embed-responsive.embed-responsive-16by9{padding-bottom:56.25%}.embed-responsive.embed-responsive-4by3{padding-bottom:75%}.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f9f9f9;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,0.05);box-shadow:inset 0 1px 1px rgba(0,0,0,0.05)}.well blockquote{border-color:#ddd;border-color:rgba(0,0,0,0.15)}.well-lg{padding:24px;border-radius:3px}.well-sm{padding:9px;border-radius:3px}.close{float:right;font-size:19.5px;font-weight:normal;line-height:1;color:#000000;text-shadow:none;opacity:0.2;filter:alpha(opacity=20)}.close:hover,.close:focus{color:#000000;text-decoration:none;cursor:pointer;opacity:0.5;filter:alpha(opacity=50)}button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none}.modal-open{overflow:hidden}.modal{display:none;overflow:hidden;position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;-webkit-overflow-scrolling:touch;outline:0}.modal.fade .modal-dialog{-webkit-transform:translate(0, -25%);-ms-transform:translate(0, -25%);-o-transform:translate(0, -25%);transform:translate(0, -25%);-webkit-transition:-webkit-transform .3s ease-out;-o-transition:-o-transform .3s ease-out;transition:transform .3s ease-out}.modal.in .modal-dialog{-webkit-transform:translate(0, 0);-ms-transform:translate(0, 0);-o-transform:translate(0, 0);transform:translate(0, 0)}.modal-open .modal{overflow-x:hidden;overflow-y:auto}.modal-dialog{position:relative;width:auto;margin:10px}.modal-content{position:relative;background-color:#ffffff;border:1px solid #999999;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 3px 9px rgba(0,0,0,0.5);box-shadow:0 3px 9px rgba(0,0,0,0.5);-webkit-background-clip:padding-box;background-clip:padding-box;outline:0}.modal-backdrop{position:absolute;top:0;right:0;left:0;background-color:#000000}.modal-backdrop.fade{opacity:0;filter:alpha(opacity=0)}.modal-backdrop.in{opacity:0.5;filter:alpha(opacity=50)}.modal-header{padding:15px;border-bottom:1px solid transparent;min-height:16.846px}.modal-header .close{margin-top:-2px}.modal-title{margin:0;line-height:1.846}.modal-body{position:relative;padding:15px}.modal-footer{padding:15px;text-align:right;border-top:1px solid transparent}.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0}.modal-footer .btn-group .btn+.btn{margin-left:-1px}.modal-footer .btn-block+.btn-block{margin-left:0}.modal-scrollbar-measure{position:absolute;top:-9999px;width:50px;height:50px;overflow:scroll}@media (min-width:768px){.modal-dialog{width:600px;margin:30px auto}.modal-content{-webkit-box-shadow:0 5px 15px rgba(0,0,0,0.5);box-shadow:0 5px 15px rgba(0,0,0,0.5)}.modal-sm{width:300px}}@media (min-width:992px){.modal-lg{width:900px}}.tooltip{position:absolute;z-index:1070;display:block;visibility:visible;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:12px;font-weight:normal;line-height:1.4;opacity:0;filter:alpha(opacity=0)}.tooltip.in{opacity:0.9;filter:alpha(opacity=90)}.tooltip.top{margin-top:-3px;padding:5px 0}.tooltip.right{margin-left:3px;padding:0 5px}.tooltip.bottom{margin-top:3px;padding:5px 0}.tooltip.left{margin-left:-3px;padding:0 5px}.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#727272;border-radius:3px}.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid}.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.top-left .tooltip-arrow{bottom:0;right:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.top-right .tooltip-arrow{bottom:0;left:5px;margin-bottom:-5px;border-width:5px 5px 0;border-top-color:#727272}.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#727272}.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#727272}.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.tooltip.bottom-left .tooltip-arrow{top:0;right:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.tooltip.bottom-right .tooltip-arrow{top:0;left:5px;margin-top:-5px;border-width:0 5px 5px;border-bottom-color:#727272}.popover{position:absolute;top:0;left:0;z-index:1060;display:none;max-width:276px;padding:1px;font-family:"Roboto","Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1.846;text-align:left;background-color:#ffffff;-webkit-background-clip:padding-box;background-clip:padding-box;border:1px solid transparent;border-radius:3px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,0.2);box-shadow:0 5px 10px rgba(0,0,0,0.2);white-space:normal}.popover.top{margin-top:-10px}.popover.right{margin-left:10px}.popover.bottom{margin-top:10px}.popover.left{margin-left:-10px}.popover-title{margin:0;padding:8px 14px;font-size:13px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;border-radius:2px 2px 0 0}.popover-content{padding:9px 14px}.popover>.arrow,.popover>.arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.popover>.arrow{border-width:11px}.popover>.arrow:after{border-width:10px;content:""}.popover.top>.arrow{left:50%;margin-left:-11px;border-bottom-width:0;border-top-color:rgba(0,0,0,0);border-top-color:rgba(0,0,0,0.075);bottom:-11px}.popover.top>.arrow:after{content:" ";bottom:1px;margin-left:-10px;border-bottom-width:0;border-top-color:#ffffff}.popover.right>.arrow{top:50%;left:-11px;margin-top:-11px;border-left-width:0;border-right-color:rgba(0,0,0,0);border-right-color:rgba(0,0,0,0.075)}.popover.right>.arrow:after{content:" ";left:1px;bottom:-10px;border-left-width:0;border-right-color:#ffffff}.popover.bottom>.arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:rgba(0,0,0,0);border-bottom-color:rgba(0,0,0,0.075);top:-11px}.popover.bottom>.arrow:after{content:" ";top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#ffffff}.popover.left>.arrow{top:50%;right:-11px;margin-top:-11px;border-right-width:0;border-left-color:rgba(0,0,0,0);border-left-color:rgba(0,0,0,0.075)}.popover.left>.arrow:after{content:" ";right:1px;border-right-width:0;border-left-color:#ffffff;bottom:-10px}.carousel{position:relative}.carousel-inner{position:relative;overflow:hidden;width:100%}.carousel-inner>.item{display:none;position:relative;-webkit-transition:.6s ease-in-out left;-o-transition:.6s ease-in-out left;transition:.6s ease-in-out left}.carousel-inner>.item>img,.carousel-inner>.item>a>img{line-height:1}@media all and (transform-3d),(-webkit-transform-3d){.carousel-inner>.item{-webkit-transition:-webkit-transform .6s ease-in-out;-o-transition:-o-transform .6s ease-in-out;transition:transform .6s ease-in-out;-webkit-backface-visibility:hidden;backface-visibility:hidden;-webkit-perspective:1000;perspective:1000}.carousel-inner>.item.next,.carousel-inner>.item.active.right{-webkit-transform:translate3d(100%, 0, 0);transform:translate3d(100%, 0, 0);left:0}.carousel-inner>.item.prev,.carousel-inner>.item.active.left{-webkit-transform:translate3d(-100%, 0, 0);transform:translate3d(-100%, 0, 0);left:0}.carousel-inner>.item.next.left,.carousel-inner>.item.prev.right,.carousel-inner>.item.active{-webkit-transform:translate3d(0, 0, 0);transform:translate3d(0, 0, 0);left:0}}.carousel-inner>.active,.carousel-inner>.next,.carousel-inner>.prev{display:block}.carousel-inner>.active{left:0}.carousel-inner>.next,.carousel-inner>.prev{position:absolute;top:0;width:100%}.carousel-inner>.next{left:100%}.carousel-inner>.prev{left:-100%}.carousel-inner>.next.left,.carousel-inner>.prev.right{left:0}.carousel-inner>.active.left{left:-100%}.carousel-inner>.active.right{left:100%}.carousel-control{position:absolute;top:0;left:0;bottom:0;width:15%;opacity:0.5;filter:alpha(opacity=50);font-size:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-control.left{background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.5)), to(rgba(0,0,0,0.0001)));background-image:linear-gradient(to right, rgba(0,0,0,0.5) 0, rgba(0,0,0,0.0001) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#80000000', endColorstr='#00000000', GradientType=1)}.carousel-control.right{left:auto;right:0;background-image:-webkit-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-o-linear-gradient(left, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-image:-webkit-gradient(linear, left top, right top, from(rgba(0,0,0,0.0001)), to(rgba(0,0,0,0.5)));background-image:linear-gradient(to right, rgba(0,0,0,0.0001) 0, rgba(0,0,0,0.5) 100%);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#00000000', endColorstr='#80000000', GradientType=1)}.carousel-control:hover,.carousel-control:focus{outline:0;color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90)}.carousel-control .icon-prev,.carousel-control .icon-next,.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right{position:absolute;top:50%;z-index:5;display:inline-block}.carousel-control .icon-prev,.carousel-control .glyphicon-chevron-left{left:50%;margin-left:-10px}.carousel-control .icon-next,.carousel-control .glyphicon-chevron-right{right:50%;margin-right:-10px}.carousel-control .icon-prev,.carousel-control .icon-next{width:20px;height:20px;margin-top:-10px;font-family:serif}.carousel-control .icon-prev:before{content:'\2039'}.carousel-control .icon-next:before{content:'\203a'}.carousel-indicators{position:absolute;bottom:10px;left:50%;z-index:15;width:60%;margin-left:-30%;padding-left:0;list-style:none;text-align:center}.carousel-indicators li{display:inline-block;width:10px;height:10px;margin:1px;text-indent:-999px;border:1px solid #ffffff;border-radius:10px;cursor:pointer;background-color:#000 \9;background-color:rgba(0,0,0,0)}.carousel-indicators .active{margin:0;width:12px;height:12px;background-color:#ffffff}.carousel-caption{position:absolute;left:15%;right:15%;bottom:20px;z-index:10;padding-top:20px;padding-bottom:20px;color:#ffffff;text-align:center;text-shadow:0 1px 2px rgba(0,0,0,0.6)}.carousel-caption .btn{text-shadow:none}@media screen and (min-width:768px){.carousel-control .glyphicon-chevron-left,.carousel-control .glyphicon-chevron-right,.carousel-control .icon-prev,.carousel-control .icon-next{width:30px;height:30px;margin-top:-15px;font-size:30px}.carousel-control .glyphicon-chevron-left,.carousel-control .icon-prev{margin-left:-15px}.carousel-control .glyphicon-chevron-right,.carousel-control .icon-next{margin-right:-15px}.carousel-caption{left:20%;right:20%;padding-bottom:30px}.carousel-indicators{bottom:20px}}.clearfix:before,.clearfix:after,.dl-horizontal dd:before,.dl-horizontal dd:after,.container:before,.container:after,.container-fluid:before,.container-fluid:after,.row:before,.row:after,.form-horizontal .form-group:before,.form-horizontal .form-group:after,.btn-toolbar:before,.btn-toolbar:after,.btn-group-vertical>.btn-group:before,.btn-group-vertical>.btn-group:after,.nav:before,.nav:after,.navbar:before,.navbar:after,.navbar-header:before,.navbar-header:after,.navbar-collapse:before,.navbar-collapse:after,.pager:before,.pager:after,.panel-body:before,.panel-body:after,.modal-footer:before,.modal-footer:after{content:" ";display:table}.clearfix:after,.dl-horizontal dd:after,.container:after,.container-fluid:after,.row:after,.form-horizontal .form-group:after,.btn-toolbar:after,.btn-group-vertical>.btn-group:after,.nav:after,.navbar:after,.navbar-header:after,.navbar-collapse:after,.pager:after,.panel-body:after,.modal-footer:after{clear:both}.center-block{display:block;margin-left:auto;margin-right:auto}.pull-right{float:right !important}.pull-left{float:left !important}.hide{display:none !important}.show{display:block !important}.invisible{visibility:hidden}.text-hide{font:0/0 a;color:transparent;text-shadow:none;background-color:transparent;border:0}.hidden{display:none !important;visibility:hidden !important}.affix{position:fixed}@-ms-viewport{width:device-width}.visible-xs,.visible-sm,.visible-md,.visible-lg{display:none !important}.visible-xs-block,.visible-xs-inline,.visible-xs-inline-block,.visible-sm-block,.visible-sm-inline,.visible-sm-inline-block,.visible-md-block,.visible-md-inline,.visible-md-inline-block,.visible-lg-block,.visible-lg-inline,.visible-lg-inline-block{display:none !important}@media (max-width:767px){.visible-xs{display:block !important}table.visible-xs{display:table}tr.visible-xs{display:table-row !important}th.visible-xs,td.visible-xs{display:table-cell !important}}@media (max-width:767px){.visible-xs-block{display:block !important}}@media (max-width:767px){.visible-xs-inline{display:inline !important}}@media (max-width:767px){.visible-xs-inline-block{display:inline-block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm{display:block !important}table.visible-sm{display:table}tr.visible-sm{display:table-row !important}th.visible-sm,td.visible-sm{display:table-cell !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-block{display:block !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline{display:inline !important}}@media (min-width:768px) and (max-width:991px){.visible-sm-inline-block{display:inline-block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md{display:block !important}table.visible-md{display:table}tr.visible-md{display:table-row !important}th.visible-md,td.visible-md{display:table-cell !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-block{display:block !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline{display:inline !important}}@media (min-width:992px) and (max-width:1199px){.visible-md-inline-block{display:inline-block !important}}@media (min-width:1200px){.visible-lg{display:block !important}table.visible-lg{display:table}tr.visible-lg{display:table-row !important}th.visible-lg,td.visible-lg{display:table-cell !important}}@media (min-width:1200px){.visible-lg-block{display:block !important}}@media (min-width:1200px){.visible-lg-inline{display:inline !important}}@media (min-width:1200px){.visible-lg-inline-block{display:inline-block !important}}@media (max-width:767px){.hidden-xs{display:none !important}}@media (min-width:768px) and (max-width:991px){.hidden-sm{display:none !important}}@media (min-width:992px) and (max-width:1199px){.hidden-md{display:none !important}}@media (min-width:1200px){.hidden-lg{display:none !important}}.visible-print{display:none !important}@media print{.visible-print{display:block !important}table.visible-print{display:table}tr.visible-print{display:table-row !important}th.visible-print,td.visible-print{display:table-cell !important}}.visible-print-block{display:none !important}@media print{.visible-print-block{display:block !important}}.visible-print-inline{display:none !important}@media print{.visible-print-inline{display:inline !important}}.visible-print-inline-block{display:none !important}@media print{.visible-print-inline-block{display:inline-block !important}}@media print{.hidden-print{display:none !important}}.navbar{border:none;-webkit-box-shadow:0 1px 2px rgba(0,0,0,0.3);box-shadow:0 1px 2px rgba(0,0,0,0.3)}.navbar-brand{font-size:24px}.navbar-inverse .form-control{color:#fff}.navbar-inverse .form-control::-moz-placeholder{color:#b2dbfb;opacity:1}.navbar-inverse .form-control:-ms-input-placeholder{color:#b2dbfb}.navbar-inverse .form-control::-webkit-input-placeholder{color:#b2dbfb}.navbar-inverse .form-control[type=text]{-webkit-box-shadow:inset 0 -1px 0 #b2dbfb;box-shadow:inset 0 -1px 0 #b2dbfb}.navbar-inverse .form-control[type=text]:focus{-webkit-box-shadow:inset 0 -2px 0 #fff;box-shadow:inset 0 -2px 0 #fff}.navbar-nav>li>.dropdown-menu{margin-top:2px}.btn-default{background-image:-webkit-radial-gradient(circle, #fff 80%, #f0f0f0 81%);background-image:-o-radial-gradient(circle, #fff 80%, #f0f0f0 81%);background-image:radial-gradient(circle, #fff 80%, #f0f0f0 81%);background-repeat:no-repeat;-webkit-background-size:200% 200%;background-size:200%;background-position:50%;-webkit-transition:background-size 2s;-o-transition:background-size 2s;transition:background-size 2s}.btn-default:hover{-webkit-background-size:100% 100%;background-size:100%;border-color:#f0f0f0}.btn-default:active{background-color:#f0f0f0;background-image:-webkit-radial-gradient(circle, #f0f0f0 10%, #fff 11%);background-image:-o-radial-gradient(circle, #f0f0f0 10%, #fff 11%);background-image:radial-gradient(circle, #f0f0f0 10%, #fff 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-primary{background-image:-webkit-radial-gradient(circle, #2196f3 80%, #0d87e9 81%);background-image:-o-radial-gradient(circle, #2196f3 80%, #0d87e9 81%);background-image:radial-gradient(circle, #2196f3 80%, #0d87e9 81%);background-repeat:no-repeat;-webkit-background-size:200% 200%;background-size:200%;background-position:50%;-webkit-transition:background-size 2s;-o-transition:background-size 2s;transition:background-size 2s}.btn-primary:hover{-webkit-background-size:100% 100%;background-size:100%;border-color:#0d87e9}.btn-primary:active{background-color:#0d87e9;background-image:-webkit-radial-gradient(circle, #0d87e9 10%, #2196f3 11%);background-image:-o-radial-gradient(circle, #0d87e9 10%, #2196f3 11%);background-image:radial-gradient(circle, #0d87e9 10%, #2196f3 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-success{background-image:-webkit-radial-gradient(circle, #4caf50 80%, #439a46 81%);background-image:-o-radial-gradient(circle, #4caf50 80%, #439a46 81%);background-image:radial-gradient(circle, #4caf50 80%, #439a46 81%);background-repeat:no-repeat;-webkit-background-size:200% 200%;background-size:200%;background-position:50%;-webkit-transition:background-size 2s;-o-transition:background-size 2s;transition:background-size 2s}.btn-success:hover{-webkit-background-size:100% 100%;background-size:100%;border-color:#439a46}.btn-success:active{background-color:#439a46;background-image:-webkit-radial-gradient(circle, #439a46 10%, #4caf50 11%);background-image:-o-radial-gradient(circle, #439a46 10%, #4caf50 11%);background-image:radial-gradient(circle, #439a46 10%, #4caf50 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-info{background-image:-webkit-radial-gradient(circle, #9c27b0 80%, #862197 81%);background-image:-o-radial-gradient(circle, #9c27b0 80%, #862197 81%);background-image:radial-gradient(circle, #9c27b0 80%, #862197 81%);background-repeat:no-repeat;-webkit-background-size:200% 200%;background-size:200%;background-position:50%;-webkit-transition:background-size 2s;-o-transition:background-size 2s;transition:background-size 2s}.btn-info:hover{-webkit-background-size:100% 100%;background-size:100%;border-color:#862197}.btn-info:active{background-color:#862197;background-image:-webkit-radial-gradient(circle, #862197 10%, #9c27b0 11%);background-image:-o-radial-gradient(circle, #862197 10%, #9c27b0 11%);background-image:radial-gradient(circle, #862197 10%, #9c27b0 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-warning{background-image:-webkit-radial-gradient(circle, #ff9800 80%, #e08600 81%);background-image:-o-radial-gradient(circle, #ff9800 80%, #e08600 81%);background-image:radial-gradient(circle, #ff9800 80%, #e08600 81%);background-repeat:no-repeat;-webkit-background-size:200% 200%;background-size:200%;background-position:50%;-webkit-transition:background-size 2s;-o-transition:background-size 2s;transition:background-size 2s}.btn-warning:hover{-webkit-background-size:100% 100%;background-size:100%;border-color:#e08600}.btn-warning:active{background-color:#e08600;background-image:-webkit-radial-gradient(circle, #e08600 10%, #ff9800 11%);background-image:-o-radial-gradient(circle, #e08600 10%, #ff9800 11%);background-image:radial-gradient(circle, #e08600 10%, #ff9800 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn-danger{background-image:-webkit-radial-gradient(circle, #e51c23 80%, #cb171e 81%);background-image:-o-radial-gradient(circle, #e51c23 80%, #cb171e 81%);background-image:radial-gradient(circle, #e51c23 80%, #cb171e 81%);background-repeat:no-repeat;-webkit-background-size:200% 200%;background-size:200%;background-position:50%;-webkit-transition:background-size 2s;-o-transition:background-size 2s;transition:background-size 2s}.btn-danger:hover{-webkit-background-size:100% 100%;background-size:100%;border-color:#cb171e}.btn-danger:active{background-color:#cb171e;background-image:-webkit-radial-gradient(circle, #cb171e 10%, #e51c23 11%);background-image:-o-radial-gradient(circle, #cb171e 10%, #e51c23 11%);background-image:radial-gradient(circle, #cb171e 10%, #e51c23 11%);background-repeat:no-repeat;-webkit-background-size:1000% 1000%;background-size:1000%;-webkit-box-shadow:2px 2px 2px rgba(0,0,0,0.3);box-shadow:2px 2px 2px rgba(0,0,0,0.3)}.btn{text-transform:uppercase;border-right:none;border-bottom:none;-webkit-box-shadow:1px 1px 2px rgba(0,0,0,0.3);box-shadow:1px 1px 2px rgba(0,0,0,0.3);-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.btn-link{-webkit-box-shadow:none;box-shadow:none}.btn-link:hover,.btn-link:focus{color:#2196f3;text-decoration:none}.btn-default.disabled{border:1px solid #eeeeee}body{-webkit-font-smoothing:antialiased;letter-spacing:.1px;text-rendering:optimizeLegibility}p{margin:0 0 1em}input,button{-webkit-font-smoothing:antialiased;letter-spacing:.1px;text-rendering:optimizeLegibility}a{-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}textarea,textarea.form-control,input.form-control,input[type=text],input[type=password],input[type=email],input[type=number],[type=text].form-control,[type=password].form-control,[type=email].form-control,[type=tel].form-control{padding:0;border:none;border-radius:0;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;font-size:16px}textarea:focus,textarea.form-control:focus,input.form-control:focus,input[type=text]:focus,input[type=password]:focus,input[type=email]:focus,input[type=number]:focus,[type=text].form-control:focus,[type=password].form-control:focus,[type=email].form-control:focus,[type=tel].form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3}textarea[disabled],textarea.form-control[disabled],input.form-control[disabled],input[type=text][disabled],input[type=password][disabled],input[type=email][disabled],input[type=number][disabled],[type=text].form-control[disabled],[type=password].form-control[disabled],[type=email].form-control[disabled],[type=tel].form-control[disabled],textarea[readonly],textarea.form-control[readonly],input.form-control[readonly],input[type=text][readonly],input[type=password][readonly],input[type=email][readonly],input[type=number][readonly],[type=text].form-control[readonly],[type=password].form-control[readonly],[type=email].form-control[readonly],[type=tel].form-control[readonly]{-webkit-box-shadow:none;box-shadow:none;border-bottom:1px dotted #ddd}select,select.form-control{border:0;border-radius:0;-webkit-appearance:none;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;font-size:16px;padding-left:0px}select:focus,select.form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3}.has-warning input,.has-warning .form-control,.has-warning input:focus,.has-warning .form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #ff9800;box-shadow:inset 0 -2px 0 #ff9800}.has-error input,.has-error .form-control,.has-error input:focus,.has-error .form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #e51c23;box-shadow:inset 0 -2px 0 #e51c23}.has-success input,.has-success .form-control,.has-success input:focus,.has-success .form-control:focus{-webkit-box-shadow:inset 0 -2px 0 #4caf50;box-shadow:inset 0 -2px 0 #4caf50}.nav-tabs>li>a{border:none;margin-right:0;color:#666666;-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd;-webkit-transition:all 0.2s;-o-transition:all 0.2s;transition:all 0.2s}.nav-tabs>li>a:hover{background-color:transparent;-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;color:#2196f3}.nav-tabs>li.active>a{border:none;-webkit-box-shadow:inset 0 -2px 0 #2196f3;box-shadow:inset 0 -2px 0 #2196f3;color:#2196f3}.nav-tabs>li.active>a:hover{border:none;color:#2196f3}.nav-tabs>li.disabled>a{-webkit-box-shadow:inset 0 -1px 0 #ddd;box-shadow:inset 0 -1px 0 #ddd}.nav-tabs.nav-justified>li>a,.nav-tabs.nav-justified>li>a:hover,.nav-tabs.nav-justified>.active>a,.nav-tabs.nav-justified>.active>a:hover{border:none}.nav-tabs .dropdown-menu{margin-top:0}.dropdown-menu{border:none;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.alert{border:none;color:#fff}.alert-success{background-color:#4caf50}.alert-info{background-color:#9c27b0}.alert-warning{background-color:#ff9800}.alert-danger{background-color:#e51c23}.alert a:not(.close),.alert .alert-link{color:#fff;font-weight:bold}.alert .close{color:#fff}.badge{padding:3px 6px 5px}.progress{position:relative;z-index:1;height:6px;border-radius:0;-webkit-box-shadow:none;box-shadow:none}.progress-bar{-webkit-box-shadow:none;box-shadow:none}.progress-bar:last-child{border-radius:0 3px 3px 0}.progress-bar:last-child:before{display:block;content:'div::before';position:absolute;width:100%;height:100%;left:0;right:0;z-index:-1;background-color:#cae6fc}.progress-bar-success:last-child.progress-bar:before{background-color:#c7e7c8}.progress-bar-info:last-child.progress-bar:before{background-color:#edc9f3}.progress-bar-warning:last-child.progress-bar:before{background-color:#ffe0b3}.progress-bar-danger:last-child.progress-bar:before{background-color:#f28e92}.close{font-size:34px;font-weight:300;line-height:24px;opacity:0.6}.close:hover{opacity:1}.list-group-item{padding:15px}.list-group-item-text{color:#bbbbbb}.well{border-radius:0;-webkit-box-shadow:none;box-shadow:none}.panel{border:none;border-radius:2px;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)}.panel-heading{border-bottom:none}.panel-footer{border-top:none}.panel-success .panel-heading{background-color:#4caf50}.panel-success .panel-title{color:#fff}.panel-info .panel-heading{background-color:#9c27b0}.panel-info .panel-title{color:#fff}.panel-warning .panel-heading{background-color:#ff9800}.panel-warning .panel-title{color:#fff}.panel-danger .panel-heading{background-color:#e51c23}.panel-danger .panel-title{color:#fff}.popover{border:none;-webkit-box-shadow:0 1px 4px rgba(0,0,0,0.3);box-shadow:0 1px 4px rgba(0,0,0,0.3)} \ No newline at end of file diff --git a/website/css/highlight.dark.css b/website/css/highlight.dark.css deleted file mode 100644 index 50d57f4f..00000000 --- a/website/css/highlight.dark.css +++ /dev/null @@ -1,104 +0,0 @@ -/* - -Dark style from softwaremaniacs.org (c) Ivan Sagalaev - -*/ - -.hljs { - display: block; - overflow-x: auto; - padding: 0.5em; - background: #444; - -webkit-text-size-adjust: none; -} - -.hljs-keyword, -.hljs-literal, -.hljs-change, -.hljs-winutils, -.hljs-flow, -.nginx .hljs-title, -.tex .hljs-special { - color: white; -} - -.hljs, -.hljs-subst { - color: #ddd; -} - -.hljs-string, -.hljs-title, -.hljs-type, -.ini .hljs-title, -.hljs-tag .hljs-value, -.css .hljs-rules .hljs-value, -.hljs-preprocessor, -.hljs-pragma, -.ruby .hljs-symbol, -.ruby .hljs-symbol .hljs-string, -.ruby .hljs-class .hljs-parent, -.hljs-built_in, -.django .hljs-template_tag, -.django .hljs-variable, -.smalltalk .hljs-class, -.hljs-javadoc, -.ruby .hljs-string, -.django .hljs-filter .hljs-argument, -.smalltalk .hljs-localvars, -.smalltalk .hljs-array, -.hljs-attr_selector, -.hljs-pseudo, -.hljs-addition, -.hljs-stream, -.hljs-envvar, -.apache .hljs-tag, -.apache .hljs-cbracket, -.tex .hljs-command, -.hljs-prompt, -.coffeescript .hljs-attribute { - color: #d88; -} - -.hljs-comment, -.hljs-annotation, -.hljs-decorator, -.hljs-pi, -.hljs-doctype, -.hljs-deletion, -.hljs-shebang, -.apache .hljs-sqbracket, -.tex .hljs-formula { - color: #777; -} - -.hljs-keyword, -.hljs-literal, -.hljs-title, -.css .hljs-id, -.hljs-phpdoc, -.hljs-dartdoc, -.hljs-type, -.vbscript .hljs-built_in, -.rsl .hljs-built_in, -.smalltalk .hljs-class, -.diff .hljs-header, -.hljs-chunk, -.hljs-winutils, -.bash .hljs-variable, -.apache .hljs-tag, -.tex .hljs-special, -.hljs-request, -.hljs-status { - font-weight: bold; -} - -.coffeescript .javascript, -.javascript .xml, -.tex .hljs-formula, -.xml .javascript, -.xml .vbscript, -.xml .css, -.xml .hljs-cdata { - opacity: 0.5; -} diff --git a/website/css/main.css b/website/css/main.css deleted file mode 100644 index f1e0f7d4..00000000 --- a/website/css/main.css +++ /dev/null @@ -1,105 +0,0 @@ -html { - position: relative; - min-height: 100%; -} -body { - font-size: 19px; -} - -@media (min-width: 1200px) { - .container { - width: 970px; - } -} - -main { - margin-top: 90px; -} - -section { - margin-bottom: 120px; -} - -footer { - position: absolute; - bottom: 0; - width: 100%; - background-color: #f5f5f5; - padding: 25px 0; - font-size: 15px; - text-align: center; - text-transform: uppercase; - opacity: 0.6; - transition: opacity .2s ease; -} -footer:hover { - opacity: 1.0; - transition: opacity .2s ease; -} -footer p { - margin: 0; -} - -h3 { - font-size: 23px; -} - -li { - margin-bottom: 3px; -} - -#content img { - max-width: 100%; - padding: 4px; - background-color: #fff; - border: 1px solid #ddd; - border-radius: 4px; -} - -header.navbar { - opacity: 0.9; -} -.navbar .navbar-brand { - font-size: 28px; - height: auto; - line-height: 40px; - margin-left: 20px; -} -.navbar .navbar-brand small { - font-size: 18px; - font-weight: 300; - margin-left: 10px; -} - -@media (min-width: 768px) { - #sidebar { - position:fixed; - margin-top: 30px; - } -} -@media (max-width: 960px) { - body { - font-size: 17px; - } - pre { - font-size: 12px; - } -} - -.page-header { - margin-top: 0; -} - -#sidebar .text-muted { - color: #bbbbbb; -} - -pre { - padding: 0; - border-radius: 4px; - margin: 15px; - font-size: 15px; -} -pre code { - border: none; -} diff --git a/website/default.twig b/website/default.twig deleted file mode 100644 index 752d9455..00000000 --- a/website/default.twig +++ /dev/null @@ -1,91 +0,0 @@ - - - - - - - {{ title }} - - - - - - - - - - -
-
- - {% if menu is defined %} - - - - {% endif %} - - - -
-
- - - - - - - - - - - - From f961555e69a4fb8e8f83c272eb86ec9783e141e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 17 Sep 2015 12:17:07 +0200 Subject: [PATCH 017/258] Fix quality issues. Switch to PHP League markdown library. --- composer.json | 2 +- composer.lock | 46 ++++++++++++++++++++++++++++++---------------- 2 files changed, 31 insertions(+), 17 deletions(-) diff --git a/composer.json b/composer.json index c5eecfd6..f5803c1f 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "twig/twig": "~1.0", "psr/log": "~1.0", "easyrdf/easyrdf": "~0.9.0", - "nickcernis/html-to-markdown": "~2.1", + "league/html-to-markdown": "~4.0", "fabpot/php-cs-fixer": "~1.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 48197c94..40c06e2e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "b2730cf76318a1d8c4c04837c4e3a54b", + "hash": "096a8471cec7fd85d1645e1f389a52e5", "packages": [ { "name": "easyrdf/easyrdf", @@ -123,50 +123,64 @@ "time": "2015-07-27 20:56:10" }, { - "name": "nickcernis/html-to-markdown", - "version": "2.2.2", + "name": "league/html-to-markdown", + "version": "4.0.1", "source": { "type": "git", - "url": "https://github.com/nickcernis/html-to-markdown.git", - "reference": "08491df8e9475b219659400edf68416d8044a9db" + "url": "https://github.com/thephpleague/html-to-markdown.git", + "reference": "c496c27e01b9dce310e03afbcdf783347738f67b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nickcernis/html-to-markdown/zipball/08491df8e9475b219659400edf68416d8044a9db", - "reference": "08491df8e9475b219659400edf68416d8044a9db", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/c496c27e01b9dce310e03afbcdf783347738f67b", + "reference": "c496c27e01b9dce310e03afbcdf783347738f67b", "shasum": "" }, "require": { - "php": ">=5.3" + "ext-dom": "*", + "ext-xml": "*", + "php": ">=5.3.3" }, "require-dev": { - "php": ">=5.3.3", - "phpunit/phpunit": "4.*" + "phpunit/phpunit": "4.*", + "scrutinizer/ocular": "~1.1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.1-dev" + } + }, "autoload": { - "classmap": [ - "HTML_To_Markdown.php" - ] + "psr-4": { + "League\\HTMLToMarkdown\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Colin O'Dell", + "email": "colinodell@gmail.com", + "homepage": "http://www.colinodell.com/", + "role": "Lead Developer" + }, { "name": "Nick Cernis", "email": "nick@cern.is", - "homepage": "http://modernnerd.net/" + "homepage": "http://modernnerd.net/", + "role": "Original Author" } ], "description": "An HTML-to-markdown conversion helper for PHP", - "homepage": "https://github.com/nickcernis/html-to-markdown", + "homepage": "https://github.com/thephpleague/html-to-markdown", "keywords": [ "html", "markdown" ], - "time": "2015-05-29 13:27:02" + "time": "2015-09-01 22:39:54" }, { "name": "psr/log", From df9a203a04f3024ce0d46cbae4ffdd36ab219e80 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 17 Sep 2015 12:17:56 +0200 Subject: [PATCH 018/258] Add missing files. --- .../AbstractAnnotationGenerator.php | 200 +++++ .../AnnotationGeneratorInterface.php | 122 +++ .../ConstraintAnnotationGenerator.php | 107 +++ .../DoctrineOrmAnnotationGenerator.php | 204 +++++ .../DunglasApiAnnotationGenerator.php | 53 ++ .../PhpDocAnnotationGenerator.php | 211 +++++ src/CardinalitiesExtractor.php | 106 +++ src/Command/DumpConfigurationCommand.php | 45 + src/Command/ExtractCardinalitiesCommand.php | 55 ++ src/Command/GenerateTypesCommand.php | 100 +++ src/GoodRelationsBridge.php | 154 ++++ src/TypesGenerator.php | 813 ++++++++++++++++++ src/TypesGeneratorConfiguration.php | 131 +++ 13 files changed, 2301 insertions(+) create mode 100644 src/AnnotationGenerator/AbstractAnnotationGenerator.php create mode 100644 src/AnnotationGenerator/AnnotationGeneratorInterface.php create mode 100644 src/AnnotationGenerator/ConstraintAnnotationGenerator.php create mode 100644 src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php create mode 100644 src/AnnotationGenerator/DunglasApiAnnotationGenerator.php create mode 100644 src/AnnotationGenerator/PhpDocAnnotationGenerator.php create mode 100644 src/CardinalitiesExtractor.php create mode 100644 src/Command/DumpConfigurationCommand.php create mode 100644 src/Command/ExtractCardinalitiesCommand.php create mode 100644 src/Command/GenerateTypesCommand.php create mode 100644 src/GoodRelationsBridge.php create mode 100644 src/TypesGenerator.php create mode 100644 src/TypesGeneratorConfiguration.php diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php new file mode 100644 index 00000000..81b6bcf3 --- /dev/null +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -0,0 +1,200 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use Psr\Log\LoggerInterface; + +/** + * Abstract annotation generator. + * + * @author Kévin Dunglas + */ +abstract class AbstractAnnotationGenerator implements AnnotationGeneratorInterface +{ + /** + * @var LoggerInterface + */ + protected $logger; + /** + * @var \EasyRdf_Graph[] + */ + protected $graphs; + /** + * @var array + */ + protected $cardinalities; + /** + * @var array + */ + protected $config; + /** + * @var array + */ + protected $classes; + + /** + * {@inheritdoc} + */ + public function __construct( + LoggerInterface $logger, + array $graphs, + array $cardinalities, + array $config, + array $classes + ) { + $this->logger = $logger; + $this->graphs = $graphs; + $this->cardinalities = $cardinalities; + $this->config = $config; + $this->classes = $classes; + } + + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateInterfaceAnnotations($className) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateConstantAnnotations($className, $constantName) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateGetterAnnotations($className, $fieldName) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateSetterAnnotations($className, $fieldName) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateAdderAnnotations($className, $fieldName) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateRemoverAnnotations($className, $fieldName) + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + return []; + } + + /** + * Converts a Schema.org range to a PHP type. + * + * @param array $field + * @param bool $adderOrRemover + * + * @return string + */ + protected function toPhpType(array $field, $adderOrRemover = false) + { + $range = $field['range']; + + if ($field['isEnum']) { + if ($field['isArray']) { + return 'string[]'; + } else { + return 'string'; + } + } + + $data = false; + switch ($range) { + case 'Boolean': + $data = 'boolean'; + break; + case 'Date': + // No break + case 'DateTime': + // No break + case 'Time': + $data = '\DateTime'; + break; + case 'Number': + // No break + case 'Float': + $data = 'float'; + break; + case 'Integer': + $data = 'integer'; + break; + case 'Text': + // No break + case 'URL': + $data = 'string'; + break; + } + + if ($data) { + if ($field['isArray']) { + return sprintf('%s[]', $data); + } + + return $data; + } + + if (isset($this->classes[$field['range']]['interfaceName'])) { + $range = $this->classes[$field['range']]['interfaceName']; + } + + if ($field['isArray'] && !$adderOrRemover) { + if ($this->config['doctrine']['useCollection']) { + return sprintf('ArrayCollection<%s>', $range); + } + + return sprintf('%s[]', $range); + } + + return $range; + } +} diff --git a/src/AnnotationGenerator/AnnotationGeneratorInterface.php b/src/AnnotationGenerator/AnnotationGeneratorInterface.php new file mode 100644 index 00000000..abb45954 --- /dev/null +++ b/src/AnnotationGenerator/AnnotationGeneratorInterface.php @@ -0,0 +1,122 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use Psr\Log\LoggerInterface; + +/** + * Annotation Generator Interface. + * + * @author Kévin Dunglas + */ +interface AnnotationGeneratorInterface +{ + /** + * @param LoggerInterface $logger + * @param \EasyRdf_Graph[] $graphs + * @param array $cardinalities + * @param array $config + * @param array $classes + */ + public function __construct( + LoggerInterface $logger, + array $graphs, + array $cardinalities, + array $config, + array $classes + ); + + /** + * Generates class' annotations. + * + * @param string $className + * + * @return array + */ + public function generateClassAnnotations($className); + + /** + * Generates interface's annotations. + * + * @param string $className + * + * @return array + */ + public function generateInterfaceAnnotations($className); + + /** + * Generates constant's annotations. + * + * @param string $className + * @param string $constantName + * + * @return array + */ + public function generateConstantAnnotations($className, $constantName); + + /** + * Generates field's annotation. + * + * @param string $className + * @param string $fieldName + * + * @return array + */ + public function generateFieldAnnotations($className, $fieldName); + + /** + * Generates getter's annotation. + * + * @param string $className + * @param string $fieldName + * + * @return array + */ + public function generateGetterAnnotations($className, $fieldName); + + /** + * Generates setter's annotation. + * + * @param string $className + * @param string $fieldName + * + * @return array + */ + public function generateSetterAnnotations($className, $fieldName); + + /** + * Generates adder's annotation. + * + * @param string $className + * @param string $fieldName + * + * @return array + */ + public function generateAdderAnnotations($className, $fieldName); + + /** + * Generates remover's annotation. + * + * @param string $className + * @param string $fieldName + * + * @return array + */ + public function generateRemoverAnnotations($className, $fieldName); + + /** + * Generates uses. + * + * @param string $className + * + * @return array + */ + public function generateUses($className); +} diff --git a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php new file mode 100644 index 00000000..44229429 --- /dev/null +++ b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php @@ -0,0 +1,107 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +/** + * Constraint annotation generator. + * + * @author Kévin Dunglas + */ +class ConstraintAnnotationGenerator extends AbstractAnnotationGenerator +{ + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + $field = $this->classes[$className]['fields'][$fieldName]; + + if ($field['isId']) { + return []; + } + + $asserts = []; + if (!$field['isArray']) { + switch ($field['range']) { + case 'URL': + $asserts[] = '@Assert\Url'; + break; + + case 'Date': + $asserts[] = '@Assert\Date'; + break; + + case 'DateTime': + $asserts[] = '@Assert\DateTime'; + break; + + case 'Time': + $asserts[] = '@Assert\Time'; + break; + } + + if (isset($field['resource']) && 'email' === $field['resource']->localName()) { + $asserts[] = '@Assert\Email'; + } + + if (!$asserts) { + $phpType = $this->toPhpType($field); + if (in_array($phpType, ['boolean', 'float', 'integer', 'string'])) { + $asserts[] = sprintf('@Assert\Type(type="%s")', $phpType); + } + } + } + + if (!$field['isNullable']) { + $asserts[] = '@Assert\NotNull'; + } + + if ($field['isEnum']) { + $assert = sprintf('@Assert\Choice(callback={"%s", "toArray"}', $field['range']); + + if ($field['isArray']) { + $assert .= ', multiple=true'; + } + + $assert .= ')'; + + $asserts[] = $assert; + } + + return $asserts; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + if ($this->classes[$className]['isEnum']) { + return []; + } + + $uses = []; + $uses[] = 'Symfony\Component\Validator\Constraints as Assert'; + + foreach ($this->classes[$className]['fields'] as $field) { + if ($field['isEnum']) { + $enumClass = $this->classes[$field['range']]; + $enumNamespace = isset($enumClass['namespaces']['class']) && $enumClass['namespaces']['class'] ? $enumClass['namespaces']['class'] : $this->config['namespaces']['enum']; + $use = sprintf('%s\%s', $enumNamespace, $field['range']); + + if (!in_array($use, $uses)) { + $uses[] = $use; + } + } + } + + return $uses; + } +} diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php new file mode 100644 index 00000000..c73dda1a --- /dev/null +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -0,0 +1,204 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\TypesGenerator; + +/** + * Doctrine annotation generator. + * + * @author Kévin Dunglas + */ +class DoctrineOrmAnnotationGenerator extends AbstractAnnotationGenerator +{ + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + $class = $this->classes[$className]; + + if ($class['isEnum']) { + return []; + } + + if (isset($this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping'])) { + $inheritanceMapping = $this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping']; + } else { + $inheritanceMapping = $class['abstract'] ? '@ORM\MappedSuperclass' : '@ORM\Entity'; + } + + return [ + '', + $inheritanceMapping, + ]; + } + + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + $this->classes[$className]; + $field = $this->classes[$className]['fields'][$fieldName]; + + $field['relationTableName'] = null; + if (!$field['isId'] && isset($this->config['types'][$className]['properties'][$fieldName])) { + $field['relationTableName'] = $this->config['types'][$className]['properties'][$fieldName]['relationTableName']; + } + $annotations = []; + + if ($field['isEnum']) { + if ($field['isArray']) { + $type = 'simple_array'; + } else { + $type = 'string'; + } + } else { + switch ($field['range']) { + case 'Boolean': + $type = 'boolean'; + break; + case 'Date': + $type = 'date'; + break; + case 'DateTime': + $type = 'datetime'; + break; + case 'Time': + $type = 'time'; + break; + case 'Number': + // No break + case 'Float': + $type = 'float'; + break; + case 'Integer': + $type = 'integer'; + break; + case 'Text': + // No break + case 'URL': + $type = 'string'; + break; + } + } + + if (isset($type)) { + $annotation = '@ORM\Column'; + + if ($field['isArray']) { + $type = 'simple_array'; + } + + if ($type !== 'string' || $field['isNullable']) { + $annotation .= '('; + } + + if ($type !== 'string') { + $annotation .= sprintf('type="%s"', $type); + } + + if ($type !== 'string' && $field['isNullable']) { + $annotation .= ', '; + } + + if ($field['isNullable']) { + $annotation .= 'nullable=true'; + } + + if ($type !== 'string' || $field['isNullable']) { + $annotation .= ')'; + } + + $annotations[] = $annotation; + } else { + switch ($field['cardinality']) { + case CardinalitiesExtractor::CARDINALITY_0_1: + $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $this->getRelationName($field['range'])); + break; + + case CardinalitiesExtractor::CARDINALITY_1_1: + $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $this->getRelationName($field['range'])); + $annotations[] = '@ORM\JoinColumn(nullable=false)'; + break; + + case CardinalitiesExtractor::CARDINALITY_UNKNOWN: + // No break + case CardinalitiesExtractor::CARDINALITY_N_0: + $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $this->getRelationName($field['range'])); + break; + + case CardinalitiesExtractor::CARDINALITY_N_1: + $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $this->getRelationName($field['range'])); + $annotations[] = '@ORM\JoinColumn(nullable=false)'; + break; + + case CardinalitiesExtractor::CARDINALITY_0_N: + $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); + $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; + $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; + break; + + case CardinalitiesExtractor::CARDINALITY_1_N: + $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); + $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; + $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; + break; + + case CardinalitiesExtractor::CARDINALITY_N_N: + $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); + if ($field['relationTableName']) { + $annotations[] = sprintf('@ORM\JoinTable(name="%s")', $field['relationTableName']); + } + break; + } + } + + if ($field['isId']) { + $annotations[] = '@ORM\Id'; + $annotations[] = '@ORM\GeneratedValue(strategy="AUTO")'; + } + + return $annotations; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + $resource = $this->classes[$className]['resource']; + + $subClassOf = $resource->get('rdfs:subClassOf'); + $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; + + return $typeIsEnum ? [] : ['Doctrine\ORM\Mapping as ORM']; + } + + /** + * Gets class or interface name to use in relations. + * + * @param string $range + * + * @return string + */ + private function getRelationName($range) + { + $class = $this->classes[$range]; + + if (isset($class['interfaceName'])) { + return $class['interfaceName']; + } + + return $class['name']; + } +} diff --git a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php new file mode 100644 index 00000000..c2f8c366 --- /dev/null +++ b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -0,0 +1,53 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use ApiPlatform\SchemaGenerator\TypesGenerator; + +/** + * Generates Iri annotations provided by DunglasApiBundle. + * + * @author Kévin Dunglas + * + * @link https://github.com/dunglas/DunglasApiBundle + */ +class DunglasApiAnnotationGenerator extends AbstractAnnotationGenerator +{ + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + $resource = $this->classes[$className]['resource']; + + return [sprintf('@Iri("%s")', $resource->getUri())]; + } + + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + $resource = $this->classes[$className]['resource']; + + $subClassOf = $resource->get('rdfs:subClassOf'); + $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; + + return $typeIsEnum ? [] : ['Dunglas\ApiBundle\Annotation\Iri']; + } +} diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php new file mode 100644 index 00000000..0d648360 --- /dev/null +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -0,0 +1,211 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use League\HTMLToMarkdown\HtmlConverter; +use Psr\Log\LoggerInterface; + +/** + * PHPDoc annotation generator. + * + * @author Kévin Dunglas + */ +class PhpDocAnnotationGenerator extends AbstractAnnotationGenerator +{ + const INDENT = ' '; + + /** + * @var HtmlConverter + */ + private $htmlToMarkdown; + + /** + * {@inheritdoc} + */ + public function __construct( + LoggerInterface $logger, + array $graphs, + array $cardinalities, + array $config, + array $classes + ) { + parent::__construct($logger, $graphs, $cardinalities, $config, $classes); + + $this->htmlToMarkdown = new HtmlConverter(); + } + + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + return $this->generateDoc($className); + } + + /** + * {@inheritdoc} + */ + public function generateInterfaceAnnotations($className) + { + return $this->generateDoc($className, true); + } + + /** + * {@inheritdoc} + */ + public function generateConstantAnnotations($className, $constantName) + { + $resource = $this->classes[$className]['constants'][$constantName]['resource']; + + $annotations = $this->formatDoc($resource->get('rdfs:comment'), true); + $annotations[0] = sprintf( + '@var string %s', + $annotations[0] + ); + + return $annotations; + } + + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + $field = $this->classes[$className]['fields'][$fieldName]; + $comment = $field['resource'] ? $field['resource']->get('rdfs:comment') : ''; + + $annotations = $this->formatDoc($comment, true); + $annotations[0] = sprintf( + '@var %s %s', + $this->toPhpType($field), + $annotations[0] + ); + $annotations[] = ''; + + return $annotations; + } + + /** + * {@inheritdoc} + */ + public function generateGetterAnnotations($className, $fieldName) + { + return [ + sprintf('Gets %s.', $fieldName), + '', + sprintf('@return %s', $this->toPhpType($this->classes[$className]['fields'][$fieldName])), + ]; + } + + /** + * {@inheritdoc} + */ + public function generateSetterAnnotations($className, $fieldName) + { + return [ + sprintf('Sets %s.', $fieldName), + '', + sprintf( + '@param %s $%s', + $this->toPhpType($this->classes[$className]['fields'][$fieldName]), + $fieldName + ), + '', + '@return $this', + ]; + } + + /** + * {@inheritdoc} + */ + public function generateAdderAnnotations($className, $fieldName) + { + return [ + sprintf('Adds %s.', $fieldName), + '', + sprintf( + '@param %s $%s', + $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), + $fieldName + ), + '', + '@return $this', + ]; + } + + /** + * {@inheritdoc} + */ + public function generateRemoverAnnotations($className, $fieldName) + { + return [ + sprintf('Removes %s.', $fieldName), + '', + sprintf( + '@param %s $%s', + $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), + $fieldName + ), + '', + '@return $this', + ]; + } + + /** + * Generates class or interface PHPDoc. + * + * @param string $className + * @param bool $interface + * + * @return array + */ + private function generateDoc($className, $interface = false) + { + $resource = $this->classes[$className]['resource']; + $annotations = []; + + if (!$interface && isset($this->classes[$className]['interfaceName'])) { + $annotations[] = '{@inheritdoc}'; + $annotations[] = ''; + } else { + $annotations = $this->formatDoc($resource->get('rdfs:comment')); + $annotations[] = ''; + $annotations[] = sprintf('@see %s %s', $resource->getUri(), 'Documentation on Schema.org'); + } + + if ($this->config['author']) { + $annotations[] = sprintf('@author %s', $this->config['author']); + } + + return $annotations; + } + + /** + * Converts HTML to Markdown and explode. + * + * @param string $doc + * @param bool $indent + * + * @return array + */ + private function formatDoc($doc, $indent = false) + { + $doc = explode("\n", $this->htmlToMarkdown->convert($doc)); + + if ($indent) { + $count = count($doc); + for ($i = 1; $i < $count; ++$i) { + $doc[$i] = self::INDENT.$doc[$i]; + } + } + + return $doc; + } +} diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php new file mode 100644 index 00000000..2b064b44 --- /dev/null +++ b/src/CardinalitiesExtractor.php @@ -0,0 +1,106 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator; + +/** + * Cardinality extractor. + * + * @author Kévin Dunglas + */ +class CardinalitiesExtractor +{ + const CARDINALITY_0_1 = '(0..1)'; + const CARDINALITY_0_N = '(0..*)'; + const CARDINALITY_1_1 = '(1..1)'; + const CARDINALITY_1_N = '(1..*)'; + const CARDINALITY_N_0 = '(*..0)'; + const CARDINALITY_N_1 = '(*..1)'; + const CARDINALITY_N_N = '(*..*)'; + const CARDINALITY_UNKNOWN = 'unknown'; + + /** + * @var \EasyRdf_Graph[] + */ + private $graphs; + /** + * @var GoodRelationsBridge + */ + private $goodRelationsBridge; + + /** + * @param \EasyRdf_Graph[] $graphs + * @param GoodRelationsBridge $goodRelationsBridge + */ + public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBridge) + { + $this->graphs = $graphs; + $this->goodRelationsBridge = $goodRelationsBridge; + } + + /** + * Extracts cardinality of properties. + * + * @return array + */ + public function extract() + { + $properties = []; + + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType('rdf:Property') as $property) { + $properties[$property->localName()] = $this->extractForProperty($property); + } + } + + return $properties; + } + + /** + * Extracts the cardinality of a property. + * + * Based on [Geraint Luff work](https://github.com/geraintluff/schema-org-gen). + * + * @param \EasyRdf_Resource $property + * + * @return string The cardinality + */ + private function extractForProperty(\EasyRdf_Resource $property) + { + $localName = $property->localName(); + $fromGoodRelations = $this->goodRelationsBridge->extractCardinality($localName); + if ($fromGoodRelations) { + return $fromGoodRelations; + } + + $comment = $property->get('rdfs:comment')->getValue(); + + if ( + // http://schema.org/acceptedOffer, http://schema.org/acceptedPaymentMethod, http://schema.org/exerciseType + preg_match('/\(s\)/', $comment) + || + // http://schema.org/follows + preg_match('/^The most generic uni-directional social relation./', $comment) + || + preg_match('/one or more/i', $comment) + ) { + return self::CARDINALITY_0_N; + } + + if ( + preg_match('/^is/', $localName) + || + preg_match('/^The /', $comment) + ) { + return self::CARDINALITY_0_1; + } + + return self::CARDINALITY_UNKNOWN; + } +} diff --git a/src/Command/DumpConfigurationCommand.php b/src/Command/DumpConfigurationCommand.php new file mode 100644 index 00000000..55dfa9a0 --- /dev/null +++ b/src/Command/DumpConfigurationCommand.php @@ -0,0 +1,45 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\Command; + +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Dump configuration command. + * + * @author Kévin Dunglas + */ +class DumpConfigurationCommand extends Command +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('dump-configuration') + ->setDescription('Dump configuration') + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $configuration = new TypesGeneratorConfiguration(); + $dumper = new YamlReferenceDumper(); + $output->writeln($dumper->dump($configuration)); + } +} diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php new file mode 100644 index 00000000..1fed5f81 --- /dev/null +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -0,0 +1,55 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\Command; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Output\OutputInterface; + +/** + * Extract cardinality command. + * + * @author Kévin Dunglas + */ +class ExtractCardinalitiesCommand extends Command +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('extract-cardinalities') + ->setDescription('Extract properties\' cardinality') + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $relations = []; + $schemaOrg = new \EasyRdf_Graph(); + $schemaOrg->load(TypesGeneratorConfiguration::SCHEMA_ORG_RDFA_URL, 'rdfa'); + $relations[] = $schemaOrg; + + $goodRelations = [new \SimpleXMLElement(TypesGeneratorConfiguration::GOOD_RELATIONS_OWL_URL, 0, true)]; + + $goodRelationsBridge = new GoodRelationsBridge($goodRelations); + $cardinalitiesExtractor = new CardinalitiesExtractor($relations, $goodRelationsBridge); + $result = $cardinalitiesExtractor->extract(); + + $output->writeln(json_encode($result, JSON_PRETTY_PRINT)); + } +} diff --git a/src/Command/GenerateTypesCommand.php b/src/Command/GenerateTypesCommand.php new file mode 100644 index 00000000..bd0e358a --- /dev/null +++ b/src/Command/GenerateTypesCommand.php @@ -0,0 +1,100 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\Command; + +use ApiPlatform\SchemaGenerator\TypesGenerator; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Input\InputArgument; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Logger\ConsoleLogger; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Yaml\Parser; + +/** + * Generate entities command. + * + * @author Kévin Dunglas + */ +class GenerateTypesCommand extends Command +{ + /** + * {@inheritdoc} + */ + protected function configure() + { + $this + ->setName('generate-types') + ->setDescription('Generate types') + ->addArgument('output', InputArgument::REQUIRED, 'The output directory') + ->addArgument('config', InputArgument::OPTIONAL, 'The config file to use') + ; + } + + /** + * {@inheritdoc} + */ + protected function execute(InputInterface $input, OutputInterface $output) + { + $configArgument = $input->getArgument('config'); + if ($configArgument) { + $parser = new Parser(); + $config = $parser->parse(file_get_contents($configArgument)); + unset($parser); + } else { + $config = []; + } + + $processor = new Processor(); + $configuration = new TypesGeneratorConfiguration(); + $processedConfiguration = $processor->processConfiguration($configuration, [$config]); + $processedConfiguration['output'] = realpath($input->getArgument('output')); + if (!$processedConfiguration['output']) { + throw new \RuntimeException('The specified output is invalid'); + } + + $graphs = []; + foreach ($processedConfiguration['rdfa'] as $rdfa) { + $graph = new \EasyRdf_Graph(); + if ('http://' === substr($rdfa, 0, 7) || 'https://' === substr($rdfa, 0, 8)) { + $graph->load($rdfa, 'rdfa'); + } else { + $graph->parseFile($rdfa); + } + + $graphs[] = $graph; + } + + $relations = []; + foreach ($processedConfiguration['relations'] as $relation) { + $relations[] = new \SimpleXMLElement($relation, 0, true); + } + + $goodRelationsBridge = new GoodRelationsBridge($relations); + $cardinalitiesExtractor = new CardinalitiesExtractor($graphs, $goodRelationsBridge); + + $ucfirstFilter = new \Twig_SimpleFilter('ucfirst', 'ucfirst'); + $loader = new \Twig_Loader_Filesystem(__DIR__.'/../../templates/'); + $twig = new \Twig_Environment($loader, ['autoescape' => false, 'debug' => $processedConfiguration['debug']]); + $twig->addFilter($ucfirstFilter); + + if ($processedConfiguration['debug']) { + $twig->addExtension(new \Twig_Extension_Debug()); + } + + $logger = new ConsoleLogger($output); + + $entitiesGenerator = new TypesGenerator($twig, $logger, $graphs, $cardinalitiesExtractor, $goodRelationsBridge); + $entitiesGenerator->generate($processedConfiguration); + } +} diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php new file mode 100644 index 00000000..f71e8c53 --- /dev/null +++ b/src/GoodRelationsBridge.php @@ -0,0 +1,154 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator; + +/** + * Schema.org to GoodRelations bridge. + * + * @author Kévin Dunglas + */ +class GoodRelationsBridge +{ + const GOOD_RELATIONS_NAMESPACE = 'http://purl.org/goodrelations/v1#'; + const RDF_SCHEMA_NAMESPACE = 'http://www.w3.org/2000/01/rdf-schema#'; + + /** + * @var \SimpleXMLElement[] + */ + protected $relations; + + /** + * @var array + */ + protected static $objectPropertiesTable = [ + 'priceSpecification' => 'hasPriceSpecification', + 'businessFunction' => 'hasBusinessFunction', + 'eligibleCustomerType' => 'eligibleCustomerTypes', + 'manufacturer' => 'hasManufacturer', + 'warrantyScope' => 'hasWarrantyScope', + 'inventoryLevel' => 'hasInventoryLevel', + 'dayOfWeek' => 'hasOpeningHoursDayOfWeek', + 'brand' => 'hasBrand', + 'itemOffered' => 'includes', + 'makesOffer' => 'offers', + 'availableDeliveryMethod' => 'availableDeliveryMethods', + 'openingHoursSpecification' => 'hasOpeningHoursSpecification', + 'eligibleQuantity' => 'hasEligibleQuantity', + 'warranty' => 'hasWarrantyPromise', + 'acceptedPaymentMethod' => 'acceptedPaymentMethods', + ]; + /** + * @var array + */ + protected static $datatypePropertiesTable = [ + 'minPrice' => 'hasMinCurrencyValue', + 'unitCode' => 'hasUnitOfMeasurement', + 'isicV4' => 'hasISICv4', + 'gtin8' => 'hasGTIN-8', + 'maxPrice' => 'hasMaxCurrencyValue', + 'gtin14' => 'hasGTIN-14', + 'maxValue' => 'hasMaxValue', + 'mpn' => 'hasMPN', + 'value' => 'hasValue', + 'model' => 'hasMakeAndModel', + 'gtin13' => 'hasEAN_UCC-13', + 'globalLocationNumber' => 'hasGlobalLocationNumber', + 'naics' => 'hasNAICS', + 'priceCurrency' => 'hasCurrency', + 'sku' => 'hasStockKeepingUnit', + 'duns' => 'hasDUNS', + 'minValue' => 'hasMinValue', + 'eligibleRegion' => 'eligibleRegions', + ]; + + /** + * @param \SimpleXMLElement[] $relations + */ + public function __construct(array $relations) + { + $this->relations = $relations; + + foreach ($this->relations as $relation) { + $relation->registerXPathNamespace('rdfs', static::RDF_SCHEMA_NAMESPACE); + } + } + + /** + * Checks if a property exists in GoodRelations. + * + * @param string $id + * + * @return bool + */ + public function exist($id) + { + foreach ($this->relations as $relation) { + $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]', static::getPropertyUrl($id))); + if (!empty($result)) { + return true; + } + } + + return false; + } + + /** + * Extracts cardinality from the Good Relations OWL. + * + * @param string $id + * + * @return string|bool + */ + public function extractCardinality($id) + { + foreach ($this->relations as $relation) { + $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', static::getPropertyUrl($id))); + if (count($result)) { + preg_match('/\(.\.\..\)/', $result[0]->asXML(), $matches); + + return $matches[0]; + } + } + + return false; + } + + /** + * Converts Schema.org's id to Good Relations id. + * + * @param string $id + * + * @return string + */ + private static function convertPropertyId($id) + { + if (isset(static::$datatypePropertiesTable[$id])) { + return static::$datatypePropertiesTable[$id]; + } + + if (isset(static::$objectPropertiesTable[$id])) { + return static::$objectPropertiesTable[$id]; + } + + return $id; + } + + /** + * Gets a property URL. + * + * @param string $id + * + * @return string + */ + private static function getPropertyUrl($id) + { + return sprintf('%s%s', static::GOOD_RELATIONS_NAMESPACE, static::convertPropertyId($id)); + } +} diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php new file mode 100644 index 00000000..16f92bdf --- /dev/null +++ b/src/TypesGenerator.php @@ -0,0 +1,813 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator; + +use ApiPlatform\SchemaGenerator\AnnotationGenerator\AnnotationGeneratorInterface; +use Psr\Log\LoggerInterface; +use Symfony\CS\Config\Config; +use Symfony\CS\ConfigurationResolver; +use Symfony\CS\Fixer; + +/** + * Entities generator. + * + * @author Kévin Dunglas + */ +class TypesGenerator +{ + /** + * @var string + * + * @see https://github.com/myclabs/php-enum Used enum implementation + */ + const ENUM_USE = 'MyCLabs\Enum\Enum'; + /** + * @var string + * + * @see https://github.com/doctrine/collections + */ + const DOCTRINE_COLLECTION_USE = 'Doctrine\Common\Collections\ArrayCollection'; + /** + * @var string + * + * @see https://github.com/myclabs/php-enum Used enum implementation + */ + const ENUM_EXTENDS = 'Enum'; + /** + * @var string + */ + const SCHEMA_ORG_NAMESPACE = 'http://schema.org/'; + /** + * @var string + */ + const SCHEMA_ORG_ENUMERATION = 'http://schema.org/Enumeration'; + /** + * @var string + */ + const SCHEMA_ORG_DOMAIN = 'schema:domainIncludes'; + /** + * @var string + */ + const SCHEMA_ORG_RANGE = 'schema:rangeIncludes'; + + /** + * @var \Twig_Environment + */ + private $twig; + /** + * @var LoggerInterface + */ + private $logger; + /** + * @var \EasyRdf_Graph[] + */ + private $graphs; + /** + * @var CardinalitiesExtractor + */ + private $cardinalitiesExtractor; + /** + * @var GoodRelationsBridge + */ + private $goodRelationsBridge; + /** + * @var array + */ + private $cardinalities; + + /** + * @param \Twig_Environment $twig + * @param LoggerInterface $logger + * @param \EasyRdf_Graph[] $graphs + * @param CardinalitiesExtractor $cardinalitiesExtractor + * @param GoodRelationsBridge $goodRelationsBridge + */ + public function __construct( + \Twig_Environment $twig, + LoggerInterface $logger, + array $graphs, + CardinalitiesExtractor $cardinalitiesExtractor, + GoodRelationsBridge $goodRelationsBridge + ) { + $this->twig = $twig; + $this->logger = $logger; + $this->graphs = $graphs; + $this->cardinalitiesExtractor = $cardinalitiesExtractor; + $this->goodRelationsBridge = $goodRelationsBridge; + + $this->cardinalities = $this->cardinalitiesExtractor->extract(); + } + + /** + * Generates files. + */ + public function generate($config) + { + $baseClass = [ + 'constants' => [], + 'fields' => [], + 'uses' => [], + 'hasConstructor' => false, + 'parentHasConstructor' => false, + 'hasChild' => false, + 'abstract' => false, + ]; + + $typesToGenerate = []; + + if (empty($config['types'])) { + foreach ($this->graphs as $graph) { + $typesToGenerate = $graph->allOfType('rdfs:Class'); + } + } else { + foreach ($config['types'] as $key => $value) { + $resource = null; + foreach ($this->graphs as $graph) { + $resources = $graph->resources(); + + if (isset($resources[self::SCHEMA_ORG_NAMESPACE.$key])) { + $resource = $graph->resource(self::SCHEMA_ORG_NAMESPACE.$key, 'rdfs:Class'); + break; + } + } + + if ($resource) { + $typesToGenerate[] = $resource; + } else { + $this->logger->critical('Type "{key}" cannot be found.', ['key' => $key]); + } + } + } + + $classes = []; + $propertiesMap = $this->createPropertiesMap($typesToGenerate); + + foreach ($typesToGenerate as $type) { + $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; + $class = $baseClass; + + $class['name'] = $type->localName(); + $class['label'] = $type->get('rdfs:comment')->getValue(); + $class['resource'] = $type; + $class['config'] = $typeConfig; + + $class['isEnum'] = $this->isEnum($type); + if ($class['isEnum']) { + $class['namespace'] = isset($typeConfig['namespace']) ? $typeConfig['namespace'] : $config['namespaces']['enum']; + $class['parent'] = self::ENUM_EXTENDS; + $class['uses'][] = self::ENUM_USE; + + // Constants + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType($type->getUri()) as $instance) { + $class['constants'][$instance->localName()] = [ + 'name' => strtoupper(substr(preg_replace('/([A-Z])/', '_$1', $instance->localName()), 1)), + 'resource' => $instance, + 'value' => $instance->getUri(), + ]; + } + } + } else { + // Entities + $class['namespace'] = isset($typeConfig['namespaces']['class']) ? $typeConfig['namespaces']['class'] : $config['namespaces']['entity']; + + // Parent + $class['parent'] = isset($typeConfig['parent']) ? $typeConfig['parent'] : null; + if (null === $class['parent']) { + $numberOfSupertypes = count($type->all('rdfs:subClassOf')); + + if ($numberOfSupertypes > 1) { + $this->logger->error(sprintf('The type "%s" has several supertypes. Using the first one.', $type->localName())); + } + + $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; + } + + if (!empty($config['types']) && $class['parent'] && !isset($config['types'][$class['parent']])) { + $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class['parent'], $type->localName())); + } + + // Interfaces + if ($config['useInterface']) { + $class['interfaceNamespace'] = isset($typeConfig['namespaces']['interface']) && $typeConfig['namespaces']['interface'] ? $typeConfig['namespaces']['interface'] : $config['namespaces']['interface']; + $class['interfaceName'] = sprintf('%sInterface', $type->localName()); + } + } + + // Fields + foreach ($propertiesMap[$type->getUri()] as $property) { + // Ignore properties not set if using a config file + if (is_array($typeConfig['properties']) && !isset($typeConfig['properties'][$property->localName()])) { + continue; + } + + $class = $this->generateField($config, $class, $type, $property->localName(), $property); + } + + // Add custom fields (non schema.org) + if (is_array($typeConfig['properties'])) { + foreach (array_diff_key($typeConfig['properties'], $class['fields']) as $propertyName => $property) { + $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->localName())); + + $class = $this->generateField($config, $class, $type, $propertyName); + } + } + + $classes[$type->localName()] = $class; + } + + // Second pass + foreach ($classes as &$class) { + if ($class['parent'] && isset($classes[$class['parent']])) { + $classes[$class['parent']]['hasChild'] = true; + $class['parentHasConstructor'] = $classes[$class['parent']]['hasConstructor']; + } + + foreach ($class['fields'] as &$field) { + $field['isEnum'] = isset($classes[$field['range']]) && $classes[$field['range']]['isEnum']; + } + } + + // Third pass + foreach ($classes as &$class) { + if (isset($config['types'][$class['name']]['abstract']) && null !== $config['types'][$class['name']]['abstract']) { + $class['abstract'] = $config['types'][$class['name']]['abstract']; + } else { + $class['abstract'] = $class['hasChild']; + } + } + + // Generate ID + if ($config['generateId']) { + foreach ($classes as &$class) { + if (!$class['hasChild'] && !$class['isEnum']) { + $class['fields'] = [ + 'id' => [ + 'name' => 'id', + 'resource' => null, + 'range' => 'Integer', + 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, + 'isArray' => false, + 'isNullable' => false, + 'isCustom' => true, + 'isEnum' => false, + 'isId' => true, + ], + ] + $class['fields']; + } + } + } + + // Initialize annotation generators + $annotationGenerators = []; + foreach ($config['annotationGenerators'] as $annotationGenerator) { + $generator = new $annotationGenerator($this->logger, $this->graphs, $this->cardinalities, $config, $classes); + + $annotationGenerators[] = $generator; + } + + if (isset($class['interfaceNamespace']) && $config['doctrine']['resolveTargetEntityConfigPath']) { + $interfaceMappings = []; + } + + $generatedFiles = []; + foreach ($classes as $className => &$class) { + $class['uses'] = $this->generateClassUses($annotationGenerators, $classes, $className); + $class['annotations'] = $this->generateClassAnnotations($annotationGenerators, $className); + $class['interfaceAnnotations'] = $this->generateInterfaceAnnotations($annotationGenerators, $className); + + foreach ($class['constants'] as $constantName => $constant) { + $class['constants'][$constantName]['annotations'] = $this->generateConstantAnnotations($annotationGenerators, $className, $constantName); + } + + foreach ($class['fields'] as $fieldName => &$field) { + $typeHint = false; + if ($this->isDateTime($field['range'])) { + $typeHint = '\\DateTime'; + } elseif (!($this->isDatatype($field['range']) || $field['isEnum'])) { + if (isset($classes[$field['range']]['interfaceName'])) { + $typeHint = $classes[$field['range']]['interfaceName']; + } else { + $typeHint = $classes[$field['range']]['name']; + } + } + + $field['typeHint'] = $typeHint; + $field['annotations'] = $this->generateFieldAnnotations($annotationGenerators, $className, $fieldName); + $field['getterAnnotations'] = $this->generateGetterAnnotations($annotationGenerators, $className, $fieldName); + + if ($field['isArray']) { + $field['adderAnnotations'] = $this->generateAdderAnnotations($annotationGenerators, $className, $fieldName); + $field['removerAnnotations'] = $this->generateRemoverAnnotations($annotationGenerators, $className, $fieldName); + } else { + $field['setterAnnotations'] = $this->generateSetterAnnotations($annotationGenerators, $className, $fieldName); + } + } + + $classDir = $this->namespaceToDir($config, $class['namespace']); + + if (!file_exists($classDir)) { + mkdir($classDir, 0777, true); + } + + $path = sprintf('%s%s.php', $classDir, $className); + $generatedFiles[] = $path; + + file_put_contents( + $path, + $this->twig->render('class.php.twig', [ + 'config' => $config, + 'class' => $class, + ]) + ); + + if (isset($class['interfaceNamespace'])) { + $interfaceDir = $this->namespaceToDir($config, $class['interfaceNamespace']); + + if (!file_exists($interfaceDir)) { + mkdir($interfaceDir, 0777, true); + } + + $path = sprintf('%s%s.php', $interfaceDir, $class['interfaceName']); + $generatedFiles[] = $path; + file_put_contents( + $path, + $this->twig->render('interface.php.twig', [ + 'config' => $config, + 'class' => $class, + ]) + ); + + if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class['abstract']) { + $interfaceMappings[$class['interfaceNamespace'].'\\'.$class['interfaceName']] = $class['namespace'].'\\'.$className; + } + } + } + + if (isset($interfaceMappings) && $config['doctrine']['resolveTargetEntityConfigPath']) { + $file = $config['output'].'/'.$config['doctrine']['resolveTargetEntityConfigPath']; + $dir = dirname($file); + if (!file_exists($dir)) { + mkdir($dir, 0777, true); + } + + file_put_contents( + $file, + $this->twig->render('doctrine.xml.twig', ['mappings' => $interfaceMappings]) + ); + + $generatedFiles[] = $file; + } + + $this->fixCs($generatedFiles); + } + + /** + * Tests if a type is an enum. + * + * @param \EasyRdf_Resource $type + * + * @return bool + */ + private function isEnum(\EasyRdf_Resource $type) + { + $subClassOf = $type->get('rdfs:subClassOf'); + + return $subClassOf && $subClassOf->getUri() === self::SCHEMA_ORG_ENUMERATION; + } + + /** + * Gets the parent classes of the current one and add them to $parentClasses array. + * + * @param \EasyRdf_Resource $resource + * @param string[] $parentClasses + * + * @return array + */ + private function getParentClasses(\EasyRdf_Resource $resource, array $parentClasses = []) + { + if ([] === $parentClasses) { + return $this->getParentClasses($resource, [$resource->getUri()]); + } + + $subclasses = $resource->all('rdfs:subClassOf'); + + if (!$subclasses) { + return $parentClasses; + } + + $parentClass = $subclasses[0]; + $parentClasses[] = $parentClass->getUri(); + + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType('rdfs:Class') as $type) { + if ($type->getUri() === $parentClass->getUri()) { + $parentClasses = $this->getParentClasses($type, $parentClasses); + + break 2; + } + } + } + + return $parentClasses; + } + + /** + * Create a maps between class an properties. + * + * @param array $types + * + * @return array + */ + private function createPropertiesMap(array $types) + { + $typesAsString = []; + $map = []; + foreach ($types as $type) { + // get all parent classes until the root + $parentClasses = $this->getParentClasses($type); + $typesAsString[] = $parentClasses; + $map[$type->getUri()] = []; + } + + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType('rdf:Property') as $property) { + foreach ($property->all(self::SCHEMA_ORG_DOMAIN) as $domain) { + foreach ($typesAsString as $typesAsStringItem) { + if (in_array($domain->getUri(), $typesAsStringItem)) { + $map[$typesAsStringItem[0]][] = $property; + } + } + } + } + } + + return $map; + } + + /** + * Is this type a datatype? + * + * @param string $type + * + * @return bool + */ + private function isDatatype($type) + { + return in_array($type, ['Boolean', 'DataType', 'Date', 'DateTime', 'Float', 'Integer', 'Number', 'Text', 'Time', 'URL']); + } + + /** + * Is this type a \DateTime? + * + * @param $type + * + * @return bool + */ + private function isDateTime($type) + { + return in_array($type, ['Date', 'DateTime', 'Time']); + } + + /** + * Updates generated $class with given field config. + * + * @param array $config + * @param array $class + * @param \EasyRdf_Resource $type + * @param string $propertyName + * @param \EasyRdf_Resource|null $property + * + * @return array $class + */ + private function generateField(array $config, array $class, \EasyRdf_Resource $type, $propertyName, \EasyRdf_Resource $property = null) + { + $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; + $typesDefined = !empty($config['types']); + + // Warn when property are not part of GoodRelations + if ($config['checkIsGoodRelations']) { + if (!$this->goodRelationsBridge->exist($propertyName)) { + $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyName, $type->localName())); + } + } + + // Ignore or warn when properties are legacy + if (!empty($property) && preg_match('/legacy spelling/', $property->get('rdfs:comment'))) { + if (isset($typeConfig['properties'])) { + $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyName, $type->localName())); + } else { + $this->logger->info(sprintf('The property "%s" (type "%s") is legacy. Ignoring.', $propertyName, $type->localName())); + + return $class; + } + } + + $ranges = []; + if (isset($typeConfig['properties'][$propertyName]['range']) && $typeConfig['properties'][$propertyName]['range']) { + $ranges[] = $typeConfig['properties'][$propertyName]['range']; + } elseif (!empty($property)) { + foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { + if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { + $ranges[] = $range->localName(); + } + } + } + + $numberOfRanges = count($ranges); + if (0 === $numberOfRanges) { + $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyName, $type->localName())); + } else { + if ($numberOfRanges > 1) { + $this->logger->error(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); + } + + $cardinality = isset($typeConfig['properties'][$propertyName]['cardinality']) ? $typeConfig['properties'][$propertyName]['cardinality'] : false; + if (!$cardinality || $cardinality === CardinalitiesExtractor::CARDINALITY_UNKNOWN) { + $cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1; + } + + $isArray = in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_1_N, + CardinalitiesExtractor::CARDINALITY_N_N, + ]); + $isNullable = !in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_1_1, + CardinalitiesExtractor::CARDINALITY_1_N, + ]); + + $class['fields'][$propertyName] = [ + 'name' => $propertyName, + 'resource' => $property, + 'range' => $ranges[0], + 'cardinality' => $cardinality, + 'isArray' => $isArray, + 'isNullable' => $isNullable, + 'isCustom' => empty($property), + 'isId' => false, + ]; + if ($isArray) { + $class['hasConstructor'] = true; + + if ($config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { + $class['uses'][] = self::DOCTRINE_COLLECTION_USE; + } + } + } + + return $class; + } + + /** + * Generates field's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * @param string $fieldName + * + * @return array + */ + private function generateFieldAnnotations($annotationGenerators, $className, $fieldName) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateFieldAnnotations($className, $fieldName)); + } + + return $annotations; + } + + /** + * Generates constant's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * @param string $constantName + * + * @return array + */ + private function generateConstantAnnotations(array $annotationGenerators, $className, $constantName) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateConstantAnnotations($className, $constantName)); + } + + return $annotations; + } + + /** + * Generates class' annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * + * @return array + */ + private function generateClassAnnotations(array $annotationGenerators, $className) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateClassAnnotations($className)); + } + + return $annotations; + } + + /** + * Generates interface's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * + * @return array + */ + private function generateInterfaceAnnotations(array $annotationGenerators, $className) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateInterfaceAnnotations($className)); + } + + return $annotations; + } + + /** + * Generates getter's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * @param string $fieldName + * + * @return array + */ + private function generateGetterAnnotations(array $annotationGenerators, $className, $fieldName) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateGetterAnnotations($className, $fieldName)); + } + + return $annotations; + } + + /** + * Generates adder's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * @param string $fieldName + * + * @return array + */ + private function generateAdderAnnotations(array $annotationGenerators, $className, $fieldName) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateAdderAnnotations($className, $fieldName)); + } + + return $annotations; + } + + /** + * Generates remover's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * @param string $fieldName + * + * @return array + */ + private function generateRemoverAnnotations(array $annotationGenerators, $className, $fieldName) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateRemoverAnnotations($className, $fieldName)); + } + + return $annotations; + } + + /** + * Generates getter's annotations. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param string $className + * @param string $fieldName + * + * @return array + */ + private function generateSetterAnnotations(array $annotationGenerators, $className, $fieldName) + { + $annotations = []; + foreach ($annotationGenerators as $generator) { + $annotations = array_merge($annotations, $generator->generateSetterAnnotations($className, $fieldName)); + } + + return $annotations; + } + + /** + * Generates uses. + * + * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param array $classes + * @param string $className + * + * @return array + */ + private function generateClassUses($annotationGenerators, $classes, $className) + { + $uses = $classes[$className]['uses']; + + if ( + isset($classes[$className]['interfaceNamespace']) + && $classes[$className]['interfaceNamespace'] !== $classes[$className]['namespace'] + ) { + $uses[] = sprintf( + '%s\\%s', + $classes[$className]['interfaceNamespace'], + $classes[$className]['interfaceName'] + ); + } + + foreach ($classes[$className]['fields'] as $field) { + if (isset($classes[$field['range']]['interfaceName'])) { + $use = sprintf( + '%s\\%s', + $classes[$field['range']]['interfaceNamespace'], + $classes[$field['range']]['interfaceName'] + ); + + if (!in_array($use, $uses)) { + $uses[] = $use; + } + } + } + + foreach ($annotationGenerators as $generator) { + $uses = array_merge($uses, $generator->generateUses($className)); + } + + // Order alphabetically + sort($uses); + + return $uses; + } + + /** + * Converts a namespace to a directory path according to PSR-4. + * + * @param array $config + * @param string $namespace + * + * @return string + */ + private function namespaceToDir($config, $namespace) + { + return sprintf('%s/%s/', $config['output'], strtr($namespace, '\\', '/')); + } + + /** + * Uses PHP CS Fixer to make generated files following PSR and Symfony Coding Standards. + * + * @param array $files + */ + private function fixCs(array $files) + { + $config = new Config(); + $fixer = new Fixer(); + $fixer->registerBuiltInConfigs(); + $fixer->registerBuiltInFixers(); + + $resolver = new ConfigurationResolver(); + $resolver + ->setAllFixers($fixer->getFixers()) + ->setConfig($config) + ->setOptions(array( + 'level' => 'symfony', + 'fixers' => null, + 'progress' => false, + )) + ->resolve() + ; + + $config->fixers($resolver->getFixers()); + + $finder = []; + foreach ($files as $file) { + $finder[] = new \SplFileInfo($file); + } + + $config->finder(new \ArrayIterator($finder)); + $fixer->fix($config); + } +} diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php new file mode 100644 index 00000000..469e6eb6 --- /dev/null +++ b/src/TypesGeneratorConfiguration.php @@ -0,0 +1,131 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator; + +use Symfony\Component\Config\Definition\Builder\TreeBuilder; +use Symfony\Component\Config\Definition\ConfigurationInterface; + +/** + * Types Generator Configuration. + * + * @author Kévin Dunglas + */ +class TypesGeneratorConfiguration implements ConfigurationInterface +{ + const SCHEMA_ORG_RDFA_URL = 'http://schema.org/docs/schema_org_rdfa.html'; + const GOOD_RELATIONS_OWL_URL = 'http://purl.org/goodrelations/v1.owl'; + + /** + * {@inheritdoc} + */ + public function getConfigTreeBuilder() + { + $treeBuilder = new TreeBuilder(); + $rootNode = $treeBuilder->root('config'); + $rootNode + ->children() + ->arrayNode('rdfa') + ->info('RDFa files to use') + ->defaultValue([ + self::SCHEMA_ORG_RDFA_URL, + ]) + ->prototype('scalar')->end() + ->end() + ->arrayNode('relations') + ->info('OWL relation files to use') + ->defaultValue([ + self::GOOD_RELATIONS_OWL_URL, + ]) + ->prototype('scalar')->end() + ->end() + ->booleanNode('debug')->defaultFalse()->info('Debug mode')->end() + ->booleanNode('generateId')->defaultTrue()->info('Automatically add an id field to entities')->end() + ->booleanNode('useInterface')->defaultFalse()->info('Generate interfaces and use Doctrine\'s Resolve Target Entity feature')->end() + ->booleanNode('checkIsGoodRelations')->defaultFalse()->info('Emit a warning if a property is not derived from GoodRelations')->end() + ->scalarNode('header')->defaultFalse()->info('A license or any text to use as header of generated files')->example('// (c) Kévin Dunglas ')->end() + ->arrayNode('namespaces') + ->addDefaultsIfNotSet() + ->info('PHP namespaces') + ->children() + ->scalarNode('entity')->defaultValue('SchemaOrg\Entity')->info('The namespace of the generated entities')->example('Acme\Entity')->end() + ->scalarNode('enum')->defaultValue('SchemaOrg\Enum')->info('The namespace of the generated enumerations')->example('Acme\Enum')->end() + ->scalarNode('interface')->defaultValue('SchemaOrg\Model')->info('The namespace of the generated interfaces')->example('Acme\Model')->end() + ->end() + ->end() + ->arrayNode('doctrine') + ->addDefaultsIfNotSet() + ->info('Doctrine') + ->children() + ->booleanNode('useCollection')->defaultTrue()->info('Use Doctrine\'s ArrayCollection instead of standard arrays')->end() + ->scalarNode('resolveTargetEntityConfigPath')->defaultNull()->info('The Resolve Target Entity Listener config file pass')->end() + ->end() + ->end() + ->scalarNode('author')->defaultFalse()->info('The value of the phpDoc\'s @author annotation')->example('Kévin Dunglas ')->end() + ->enumNode('fieldVisibility')->values(['private', 'protected', 'public'])->defaultValue('private')->cannotBeEmpty()->info('Visibility of entities fields')->end() + ->arrayNode('types') + ->info('Schema.org\'s types to use') + ->useAttributeAsKey('id') + ->prototype('array') + ->children() + ->booleanNode('abstract')->defaultNull()->info('Is the class abstract? (null to guess)')->end() + ->arrayNode('namespaces') + ->addDefaultsIfNotSet() + ->info('Type namespaces') + ->children() + ->scalarNode('class')->defaultNull()->info('The namespace for the generated class (override any other defined namespace)')->end() + ->scalarNode('interface')->defaultNull()->info('The namespace for the generated interface (override any other defined namespace)')->end() + ->end() + ->end() + ->arrayNode('doctrine') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('inheritanceMapping')->defaultNull()->info('The Doctrine inheritance mapping type (override the guessed one)')->end() + ->end() + ->end() + ->scalarNode('parent')->defaultNull()->info('The parent class, set to false for a top level class')->end() + ->arrayNode('properties') + ->info('Properties of this type to use') + ->useAttributeAsKey('id') + ->prototype('array') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('range')->defaultNull()->info('The property range')->example('Offer')->end() + ->scalarNode('relationTableName')->defaultNull()->info('The relation table name')->example('organization_member')->end() + ->enumNode('cardinality')->defaultValue(CardinalitiesExtractor::CARDINALITY_UNKNOWN)->values([ + CardinalitiesExtractor::CARDINALITY_0_1, + CardinalitiesExtractor::CARDINALITY_0_N, + CardinalitiesExtractor::CARDINALITY_1_1, + CardinalitiesExtractor::CARDINALITY_1_N, + CardinalitiesExtractor::CARDINALITY_N_0, + CardinalitiesExtractor::CARDINALITY_N_1, + CardinalitiesExtractor::CARDINALITY_N_N, + CardinalitiesExtractor::CARDINALITY_UNKNOWN, + ])->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->end() + ->arrayNode('annotationGenerators') + ->info('Annotation generators to use') + ->defaultValue([ + 'ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator', + 'ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator', + 'ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator', + ]) + ->prototype('scalar')->end() + ->end() + ->end() + ; + + return $treeBuilder; + } +} From 5b3f51c9c0b9641842e6b29ec866b4f0f23fbabb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 17 Sep 2015 12:20:24 +0200 Subject: [PATCH 019/258] Updated README.md --- README.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index 6b13e72a..8b3c5f7b 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ -# PHP Schema.org Model Scaffolding +# API Platform Model Generator -The [PHP Schema](http://php-schema.dunglas.com/) command line tool part of [the API Platform framework](http://api-platform.com) that instantly generates a PHP data model from the [Schema.org](http://schema.org) +This Schema.org based model generator is part of [the API Platform framework](http://api-platform.com) that instantly generates a PHP data model from the [Schema.org](http://schema.org) vocabulary. Browse Schema.org, choose the types and properties you need, run our code generator and you're done! You get a fully featured PHP data model including: * A set of PHP entities with properties, constants (enum values), getters, setters, adders and removers. The class @@ -9,7 +9,7 @@ code complies with [PSR](http://www.php-fig.org/) coding standards. * Full high-quality PHPDoc for classes, properties, constants and methods extracted from Schema.org. * 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](http://symfony.com/doc/current/book/validation.html) annotations including +* Data validation through [Symfony Validator](https://symfony.com/doc/current/book/validation.html) annotations including data type validation, enum support (choices) and check for required properties. * Interfaces and [Doctrine `ResolveTargetEntityListener`](http://doctrine-orm.readthedocs.org/en/latest/cookbook/resolve-target-entity-listener.html) support. @@ -27,7 +27,7 @@ or any other framework including [Laravel](http://laravel.com) and [Zend Framewo ## What is Schema.org? Schema.org is a vocabulary representing common data structures and their relations. Schema.org can be exposed as [JSON-LD](http://en.wikipedia.org/wiki/JSON-LD), -[microdata](http://en.wikipedia.org/wiki/Microdata_(HTML)) and [RDFa](http://en.wikipedia.org/wiki/RDFa). +[microdata](http://en.wikipedia.org/wiki/Microdata_(HTML)) and [RDFa](https://en.wikipedia.org/wiki/RDFa). 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. @@ -59,9 +59,9 @@ It opens the way to generic web API clients able to extract and process data fro ## Documentation -* [Getting Started](doc/getting-started.md) -* [Configuration](doc/configuration.md) +* [Getting Started](https://api-platform.com/doc/1.0/schema-generator/getting-started) +* [Configuration](https://api-platform.com/doc/1.0/schema-generator/configuration) ## Credits -This project has been created by [Kévin Dunglas](http://dunglas.fr) and is sponsored by [Les-Tilleuls.coop](http://les-tilleuls.coop). +This project has been created by [Kévin Dunglas](https://dunglas.fr) and is sponsored by [Les-Tilleuls.coop](https://les-tilleuls.coop). From 636c2e58fff84e4106277048a1c72f8b4a2fc1fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 17 Sep 2015 12:23:50 +0200 Subject: [PATCH 020/258] Fix Markdown in README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 8b3c5f7b..f077225f 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,7 @@ support. * List of values provided by Schema.org with [PHP Enum](https://github.com/myclabs/php-enum) classes. Bonus: + * The code generator is fully configurable and extensible: all features can be deactivated (e.g.: the Doctrine mapping generator) and custom generator can be added (e.g.: a Doctrine ODM mapping generator). * The generated code can be used as is in a [Symfony](http://symfony.com) app (but it will work too in a raw PHP project From af3ef880d80c84d492b5318c6a85a608ec899f4b Mon Sep 17 00:00:00 2001 From: Pascal Schneider Date: Mon, 21 Sep 2015 22:15:16 +0200 Subject: [PATCH 021/258] Removed vocabulary namespace restrictions and added new config option for vocabulary namespaces on types https://github.com/api-platform/schema-generator/issues/22 --- src/Command/GenerateTypesCommand.php | 2 +- src/TypesGenerator.php | 4 ++-- src/TypesGeneratorConfiguration.php | 1 + 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/Command/GenerateTypesCommand.php b/src/Command/GenerateTypesCommand.php index bd0e358a..c3906c5d 100644 --- a/src/Command/GenerateTypesCommand.php +++ b/src/Command/GenerateTypesCommand.php @@ -67,7 +67,7 @@ protected function execute(InputInterface $input, OutputInterface $output) foreach ($processedConfiguration['rdfa'] as $rdfa) { $graph = new \EasyRdf_Graph(); if ('http://' === substr($rdfa, 0, 7) || 'https://' === substr($rdfa, 0, 8)) { - $graph->load($rdfa, 'rdfa'); + $graph->load($rdfa); } else { $graph->parseFile($rdfa); } diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 16f92bdf..d3e35c8e 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -132,8 +132,8 @@ public function generate($config) foreach ($this->graphs as $graph) { $resources = $graph->resources(); - if (isset($resources[self::SCHEMA_ORG_NAMESPACE.$key])) { - $resource = $graph->resource(self::SCHEMA_ORG_NAMESPACE.$key, 'rdfs:Class'); + if (isset($resources[$value['vocabularyNamespace'].$key])) { + $resource = $graph->resource($value['vocabularyNamespace'].$key, 'rdfs:Class'); break; } } diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 469e6eb6..aa6affef 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -74,6 +74,7 @@ public function getConfigTreeBuilder() ->useAttributeAsKey('id') ->prototype('array') ->children() + ->scalarNode('vocabularyNamespace')->defaultValue(TypesGenerator::SCHEMA_ORG_NAMESPACE)->info('Namespace of the vocabulary the type belongs to.')->end() ->booleanNode('abstract')->defaultNull()->info('Is the class abstract? (null to guess)')->end() ->arrayNode('namespaces') ->addDefaultsIfNotSet() From 68318ff155423993919fd4cdfd54370d131ea350 Mon Sep 17 00:00:00 2001 From: Pascal Schneider Date: Tue, 22 Sep 2015 23:13:40 +0200 Subject: [PATCH 022/258] added test for non-schema.org namespace type generation https://github.com/api-platform/schema-generator/issues/22 --- tests/config/vgo.yml | 16 + tests/data/vgo.rdf | 911 +++++++++++++++++++++++++++++++++++++++++++ tests/run-tests.sh | 3 +- 3 files changed, 929 insertions(+), 1 deletion(-) create mode 100644 tests/config/vgo.yml create mode 100644 tests/data/vgo.rdf diff --git a/tests/config/vgo.yml b/tests/config/vgo.yml new file mode 100644 index 00000000..f31af863 --- /dev/null +++ b/tests/config/vgo.yml @@ -0,0 +1,16 @@ + +annotationGenerators: + - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator +namespaces: + entity: AppBundle\Entity +types: + Session: + vocabularyNamespace: http://purl.org/net/VideoGameOntology# + Thing: ~ +debug: true +rdfa: + - tests/data/vgo.rdf + - tests/data/schema.rdfa diff --git a/tests/data/vgo.rdf b/tests/data/vgo.rdf new file mode 100644 index 00000000..100c409a --- /dev/null +++ b/tests/data/vgo.rdf @@ -0,0 +1,911 @@ + + + + + + + + + + + + + + + + + + +]> + + + + + 2013-10-22 + 2014-12-19 + http://delicias.dia.fi.upm.es/members/DGarijo/#me + http://filip.milstan.net/ + http://purl.org/net/mpoveda + http://www.mendeley.com/profiles/janne-parkkila/ + vgo + http://purl.org/net/VideoGameOntology# + http://creativecommons.org/licenses/by-nc-sa/2.0/ + 1.0 + An ontology for describing video games and game plays. Created by Janne Parkkila, Filip Radulovic, Daniel Garijo and María Poveda. + The Video Game Ontology + The Video Game Ontology is an ontology designed for describing video games and all the resources related to their game plays. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + has achievement + The vgo:hasAchievement property specifies that a game has a specific achievement. A game often contains more than one achievement that can be awarded to the players. + optional + + + + + + + + + + has character + The vgo:hasCharacter property specifies that a game has a specific character. A game can have more than one characters involved. + optional + + + + + + + + + + has feature + The vgo:hasFeature property indicates what is a vgo:Feature (or ability) of a particular vgo:Item. For example, a fire sword, a healing staff or boots of flight connects item to a feature it can have. An item with connection to potable feature would make the item potable. + + + + + + + + + + has game genre + The vgo:hasGameGenre property specifies that a game belongs to a certain game genre. For example, Pong would be an arcade game and Mario a platformer. + + + + + + + + + + has item + The vgo:hasItem property specifies that a game has a specific item. A game often contains more than one items. + optional + + + + + + + + + + has leaderboard + The vgo:hasLeaderboard specifies that a leaderboard belongs to a particular game. A game can have one or more leaderboards that keep track of ranking of the players. For example a leaderboard could be ranking of who has the most soccer game victories or who has the fastest lap in a Formula 1 game. + + + + + + + + + + + has playing area + The vgo:hasPlayingArea property asserts a gaming area to a specific game. In every game, the gameplay takes place in some playing area. + + + + + + + + + + involves achievement + The vgo:involvesPlayer property specifies that a session involves a specific player. A session may involve more than one player. + optional + + + + + + + + + + involves character + The vgo:involvesCharacter property specifies that a session involves a specific character. + optional + + + + + + + + + + involves player + The vgo:involvesPlayer property specifies that a session involves a specific player. A session may involve more than one player. + optional + + + + + + + + + + is achieved in session + The property vgo:isAchievedInSession asserts the receiving of an achievement to a certain gameplay session. This enables to keep track of what achievements a player has gained during one gameplay session. + + + + + + + + + + + is achievement in game + The property vgo:isAchievementInGame asserts that a specific vgo:Achievement can be earned in a particular vgo:Game. An achievement must belong to a certain game. + + + + + + + + + + + is character in game + vgo:isCharacterInGame property describes the relation between a vgo:Character and a vgo:Game. a vgo:Character always belongs to a certain game. + + + + + + + + + + + is character in session + The vgo:isCharacterInSession property connects the vgo:Character to a vgo:Session. A character participates in a game session (e.g., a football match or a counter strike round) during a period of time. As players can have multiple characters, a character needs to be connected to the session, in order to know which of those characters participated in the certain session. + + + + + + + + + + + is event associated to player + The vgo:isEventAssociatedToPlayer property asserts an event to a specific vgo:Player. A player may have caused an event to happen through the actions of his/her character and this property is used to connect the real person to the event. + + + + + + + + + + is event in game + The vgo:isEventInGame property asserts an event to a specific game. An event always happens inside a specific a game. + + + + + + + + + + is event in session + The vgo:isEventInSession property links an event to a specific gameplay session. An event always happens during a certain session and this property enables to link the events to that session. For example, an event of moving the queen in game of chess should be connected to a session of chess. + + + + + + + + + + is event related to item + The vgo:isEventRelatedToItem property asserts an event to a specific item. This property is used to describe an event that includes an item in one way or another. For example, an event where character gains a new sword can be described with this relation. + + + + + + + + + + is event triggered by character + The vgo:isEventTriggeredByCharacter connects the vgo:InstantaneousEvent to specific vgo:Character. This describes that an event is often caused by a character. The character in question can be either a character controlled by a player or a computer. For example, both player and non-player characters can trigger a character death event. + + + + + + + + + + + is friend with player + The vgo:isFriendWithPlayer describes a connection between players. The property is used to model the friends a player has and with whom he might be playing games with. The friends of a player are not bound necessarily to particular game, but can be describe the friendly playing relationship in overall. + + + + + + + + + + + is item in game + The vgo:isItemInGame is used to specify which item belongs to a particular game. An item cannot exist alone and thus should always be associated to a certain game. + + + + + + + + + + + is leaderboard in game + The vgo:isLeaderboardInGame property specifies that a leaderboard is from a specific game. + optional + + + + + + + + + + is player in session + The vgo:isPlayerInSession property connects vgo:Player to a specific vgo:Session. This property is used to keep track of the gameplay sessions the player has played and what has happened in those sessions. For example vgo:Player may have participated in a this can be a one round of Counter-Strike or played one hour session of mario. + + + + + + + + + + + is session in game + The vgo:isSessionInGame property links a vgo:Session to a certain vgo:Game. Each gameplay session must belong to a certain game. + + + + + + + + + + lives in + The vgo:livesIn describes the connection between a player and his place of existence in the real-world. A vgo:Player is connected to wgs84:SpatialThing as that has descriptions for places where people live and contains more detailed information of them, such as continents and regions. + + + + + + + + + + owns achievement + The vgo:ownsAchievement links the vgo:Player to the particular vgo:Achievement earned in a game. + + + + + + + + + + owns character + The vgo:ownsCharacter property asserts which characters are owned by a specific player. A player can have multiple characters in one game and this connection is used to define all the different characters a player could be playing. Even though a player deletes, trades or loses his/her character in any way, the connection can be kept to contain the player’s history of owned characters. + + + + + + + + + + owns item + The vgo:ownsItem describes ownership of an item. A vgo:Item is always owned by a certain vgo:Character. A vgo:Character can own multiple vgo:Items and this relationship is used to keep track of the character’s owned items. Even though players may lose items, the vgo:ownsItem connection is still held with the item. This approach allows to keep track of character’s history of owned items. + + + + + + + + + + plays game + the vgo:playsGame property asserts which games has the vgo:Player played at any point of time. + + + + + + + + + + purchases game offering + The vgo:purchasesGameOffering property aseerts a vgo:InAppPurchaseEvent to a specific vgo:GameProduct. This property describes what is purchased by the in-app purchase event that the player has done. + + + + + + + + + + unlocks achievement + The vgo:unlocksAchievement property asserts an event to a certain achievement. An achievement is always unlocked as a consequence of some event. For example, eating the 100th piece of cake unlocks the “Cake Eater” achievement. + + + + + + + + + + + + + + + + + + + + + end time + endTime describes the ending moment in time of a single Session. endTime connects the session to a DateTime value which holds the moment when the session ended. + + + + + + + + + + event name + name connects InstantaneousEvent a text string. This allows the event to have a name to recognize it for. + + + + + + + + + + event time + time describes the connection of InstantaneousEvent happening at a certain moment of time. time Conncets the event to a DateTime value that describes the moment when the event happened. + + + + + + + + + + release date + releaseDate connects a game to a time which describes the release date of the game. + + + + + + + + + + start time + startTime describes the starting moment in time of a single Session. startTime connects the session to a DateTime value which holds the moment when the session started. + + + + + + + + + + username + The username connects player to a text string which describes the username a player has. + + + + + + + + + + + + + + + + + + + + + + + + + + + Achievement + The vgo:Achievement is a reward gained in a game due to some event accomplished in the game. Achievements are commonly used in game industry to reward players for having accomplished tasks in the game. +This ontology defines various subclasses of vgo:Achievement, which are all based on the classification presented by Markus Montola et al. [Markus Montola, Timo Nummenmaa, Andrés Lucero, Marion Boberg, and Hannu Korhonen, 2009, “Applying game achievement systems to enhance user experience in a photo sharing service”, In Proceedings of the 13th International MindTrek Conference: Everyday Life in the Ubiquitous Era (MindTrek '09)] http://dl.acm.org/citation.cfm?id=1621859 + + + + + + + + Character + A vgo:Character is any actor that can exists in a game. A character can be a human-like creature as seen traditionally in video games. However, a character could also be a car, a paddle in game of Pong or spaceship of a space shooter game. This is often contextually related to the gameplay of a certain game. A character can be either controller by a player or by a computer. + + + + + + + + Collection + + The vgo:Collection type of achievement is typically rewarded from collecting an amount of certain items in a game. An example of vgo:Collection would be obtaining a full set of christmas clothes for a character to wear or collecting every possible flower in the game. + + + + + + + + Completion + + The vgo:Completion type of achievement is usually rewarded from successfully completing a certain goal or subgoal in a game. An example of vgo:Completion would be to save a princess from a burning tower or completing all side-quests in a game. + + + + + + + + Curiosity + + The vgo:Curiosity describes funny random things that can happen or be found in the game. An example could be jumping from the Eiffel tower without dying or following a comupter controlled character’s activities for one hour. + + + + + + + + Fandom + + The vgo:Fandom achievement is related to doing some true fan activities. An example of vgo:Fandom could be purchasing a collectors edition of the game or attending a fan gathering. + + + + + + + + Feature + vgo:Feature describes an ability or characteristic. For example, a sword could have “damage dealing” ability and a bottle of water could be “potable”. + + + + + + + + gain event + + The vgo:GainEvent describes an event that is related to character/player gaining something in a game. This is a subclass of vgo:GameEvent as gaining something is related to a specific game. For example, a player can gain a new character, achievement or item. + + + + + + + + Game + The vgo:Game class describes a game product that can be played by a player. +Examples of games are Pong, Grand Theft Auto, Pokemon and Need for Speed. + + + + + + + + game event + + The vgo:GameEvent describes an event that takes place in a game without straight player interaction. GameEvents are often very specific for each game. Examples of vgo:GameEvent could be an enemy dying, connecting to a multiplayer server, loading a new level or playing an animation. + + + + + + + + game product + + + + + + + + + + + + + + A vgo:GameProduct is anything that is for sale inside a game. These can be either normal game items purchased with in-game currency or with real world money. An example of vgo:GameProduct could be a consumable health potion bought with real money, a better weapon or some visual improvement (e.g. Hats in Steam). Basically a game product can be anything, a character, an item or an achievement. +GameProduct is a subclass of Good Relations: ProductOrService & schema:Product. Since vgo:GameProduct is a type of buyable product, it reuses the properties available in the schema and Good Relations, such as currency price, validity of the offer and so on. + + + + + + + + Genre + The vgo:Genre class describes the genre a game belongs to. All of the games have at least one genre. Examples of this are RPG, Simulator and Adventure + + + + + + + + hard mode + + The vgo:HardMode achievement describes succeeding in a game on a high difficulty level. An example could be completing the “Doom” game on Nightmare difficulty level. + + + + + + + + in-app purchase event + + The vgo:InAppPurchaseEvent describes an event that is related to making a purchase with real money inside a game. This is a subclass of InstantaneousEvent because it happens at certain moment in time. An example of vgo:InAppPurchaseEvent would be unlocking secret levels with real money or purchasing better equipment with real money. + + + + + + + + instantaneous event + The vgo:InstantaneousEvent class describes an event that happens during the gameplay at a certain moment in time. This can be a player gaining an achievement, killing an enemy or making an in-app purchase. + + + + + + + + Item + A vgo:Item portrays any item that exists in a game. The item can either be just visual part of the game or a concrete usable item. As an example an item could be a drinkable potion, a magical sword or just a flower pot. + + + + + + + + Leaderboard + + The vgo:Leaderboard class describes a ranking system of the players. There can be multiple rankings in a game, for example, the kill-count ranking of Modern Warfare or the best time listing of Formula 1 game. + + + + + + + + lose event + + vgo:LoseEvent describes an event that is related to character/player losing something in a game. This is a subclass of GameEvent as gaining something is related to a specific game. For example, a player can lose a character due to trade with another player. Another example would be a character losing item due to consuming it. + + + + + + + + Loyalty + + The vgo:Loyalty achievement is used to give recognition to loyal players. For example, this could be an achievement received after subscribing to the game for a year. + + + + + + + + Luck + + The vgo:Lucky describes an achievement that is awarded to the player in a lucky situation. An example of vgo:Lucky achievement would be winning in a lottery or throwing “Yahtzee” without re-rolling the dice. + + + + + + + + menu event + + The vgo:MenuEvent describes an event that is related to interacting with the ingame menu. An example of menu event is muting sounds, changing graphic settings, changing gameplay difficulty or remapping game controls. + + + + + + + + Minigame + + The vgo:Minigame achievement describes success in mini-games that have been included in a certain game but are not vital for completing the game. An example could be to complete all the Pizza deliveries in GTA minigame or gaining over 100 dollars while playing poker in Red Dead Redemption. + + + + + + + + Multiplayer + + The vgo:Multiplayer achievement describes anything that can be awarded to one or multiple players due to their gameplay in multiplayer. For example, this could be winning 10 Team Fortress matches in a row with the same team or getting killed ten times in a row in Counter-Strike. + + + + + + + + Paragon + + The vgo:Paragon is a rare achievement that is given only to limited number of players. An example of vgo:Paragon achievement could be the first player to finish a game under 10 hours or the first ten players to complete the game 100% through. + + + + + + + + Player + + The vgo:Player describes the entity playing the game. This can be either a human or a computer. vgo:Player class is used to keep a profile of a certain playing entity and to connect all the games, achievements and characters he/she has. The vgo:Player is a subclass of foaf:Person as it contains all relative information of a certain person. + + + + + + + + player event + + The vgo:PlayerEvent describes a vgo:InstantaneousEvent that is caused by the player. For example jumping in the game, throwing an item or pressing a joystick button. + + + + + + + + playing area + The vgo:PlayingArea is the description of a place where the gameplay takes place. All of the games have some kind of area where they are played in. An example of playing areas could be football field in soccer game, a race track from a racing game or a star system of EVE Online. + + + + + + + + Session + + The vgo:Session class describes a session of gameplay. A session can be a single round of chess, a round of Counter-Strike, one half-time of soccer or one race of Formula 1. vgo:Session class can be used to store gameplay information, especially for analytical reasons. + + + + + + + + special play style + + The vgo:SpecialPlayStyle achievement is awarded to players after playing a game in special fashion. Often this is something harder than the regular play and requires more player experience to excel in it. An example of vgo:SpecialPlayStyle could be to complete a game without any violence or against a timer. + + + + + + + + Tutorial + + The vgo:Tutorial achievement is awarded to a player for trying out various features of the game. This is often related to learning how to play the game, how the controls work and how the game logic works. An example of vgo:Tutorial could be testing out newly gained special equipment or just playing through the in-game tutorial in the beginning. + + + + + + + + Veteran + + The vgo:Veteran achievement is an award that is given for accumulating a lot of play hours or game actions. For example, vgo:Veteran could be playing thousand hours of World of Tanks or making 100 goals in ice hockey game. + + + + + + + + Virtuosity + + The vgo:Virtuosity describes an achievement that is awarded for playing masterfully in the game. Examples of virtuous play could be finishing the game without saving at all, dying zero times or preventing an opposing team from scoring any goals in a soccer game. + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/run-tests.sh b/tests/run-tests.sh index bd900575..79563ed0 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -6,9 +6,10 @@ bin/schema extract-cardinalities # Build models rm -Rf build/ -mkdir -p build/ecommerce/ build/address-book/ +mkdir -p build/ecommerce/ build/address-book/ build/vgo/ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml +bin/schema generate-types build/vgo/ tests/config/vgo.yml # Check code CS vendor/bin/php-cs-fixer --dry-run --diff -vvv fix src/ From e768aa8f917757a69b4c7535658121f7a91a14c2 Mon Sep 17 00:00:00 2001 From: Youssef El Montaser Date: Sat, 3 Oct 2015 23:35:23 +0200 Subject: [PATCH 023/258] Add serialization groups --- .../SerializerGroupsAnnotationGenerator.php | 44 +++++++++++++++++++ src/TypesGeneratorConfiguration.php | 4 ++ 2 files changed, 48 insertions(+) create mode 100644 src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php diff --git a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php b/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php new file mode 100644 index 00000000..33d3e2dd --- /dev/null +++ b/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php @@ -0,0 +1,44 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +/** + * Symfony Serializer Groups annotation generator. + * + * @author Youssef El Montaser + * + * @link https://symfony.com/doc/master/components/serializer.html + */ +class SerializerGroupsAnnotationGenerator extends AbstractAnnotationGenerator +{ + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + $annotations = []; + + $properties = $this->config['types'][$className]['properties']; + + if (false === $this->classes[$className]['fields'][$fieldName]['isId'] && $groups = $properties[$fieldName]['groups']) { + $annotations[] = sprintf('@Groups({"%s"})', implode('","', $groups)); + } + + return $annotations; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + return ['Symfony\Component\Serializer\Annotation\Groups']; + } +} diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index aa6affef..93b14224 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -109,6 +109,10 @@ public function getConfigTreeBuilder() CardinalitiesExtractor::CARDINALITY_N_N, CardinalitiesExtractor::CARDINALITY_UNKNOWN, ])->end() + ->arrayNode('groups') + ->info('Symfony Serialization Groups') + ->prototype('scalar')->end() + ->end() ->end() ->end() ->end() From 45c66e3aa3345327face39a5bdf426d669bc7b7b Mon Sep 17 00:00:00 2001 From: Youssef El Montaser Date: Sun, 4 Oct 2015 19:53:25 +0200 Subject: [PATCH 024/258] Add nullable option --- src/TypesGenerator.php | 13 +++++++++---- src/TypesGeneratorConfiguration.php | 1 + 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index d3e35c8e..322adba2 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -538,10 +538,15 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t CardinalitiesExtractor::CARDINALITY_1_N, CardinalitiesExtractor::CARDINALITY_N_N, ]); - $isNullable = !in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_1_1, - CardinalitiesExtractor::CARDINALITY_1_N, - ]); + + if (false === $typeConfig['properties'][$propertyName]['nullable']) { + $isNullable = false; + } else { + $isNullable = !in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_1_1, + CardinalitiesExtractor::CARDINALITY_1_N, + ]); + } $class['fields'][$propertyName] = [ 'name' => $propertyName, diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 93b14224..8f3a031c 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -113,6 +113,7 @@ public function getConfigTreeBuilder() ->info('Symfony Serialization Groups') ->prototype('scalar')->end() ->end() + ->scalarNode('nullable')->defaultTrue()->info('The property nullable')->end() ->end() ->end() ->end() From fc3e875ae193fff7d8caeec9384b2141dbe51642 Mon Sep 17 00:00:00 2001 From: Youssef El Montaser Date: Sun, 4 Oct 2015 19:53:25 +0200 Subject: [PATCH 025/258] Add unique option --- .../ConstraintAnnotationGenerator.php | 34 +++++++++++++++++++ .../DoctrineOrmAnnotationGenerator.php | 17 ++++++++-- src/TypesGenerator.php | 2 ++ src/TypesGeneratorConfiguration.php | 1 + 4 files changed, 52 insertions(+), 2 deletions(-) diff --git a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php index 44229429..6db64472 100644 --- a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php +++ b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php @@ -89,6 +89,7 @@ public function generateUses($className) $uses = []; $uses[] = 'Symfony\Component\Validator\Constraints as Assert'; + $uses[] = 'Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity'; foreach ($this->classes[$className]['fields'] as $field) { if ($field['isEnum']) { @@ -104,4 +105,37 @@ public function generateUses($className) return $uses; } + + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + if ($this->classes[$className]['isEnum']) { + return []; + } + + $annotation = []; + $uniqueFields = []; + + foreach ($this->classes[$className]['fields'] as $field) { + if (false === $field['isUnique']) { + continue; + } + + $uniqueFields[] = $field['name']; + } + + if (0 === count($uniqueFields)) { + return []; + } + + if (1 === count($uniqueFields)) { + $annotation[] = sprintf('@UniqueEntity("%s")', $uniqueFields[0]); + } else { + $annotation[] = sprintf('@UniqueEntity(fields={"%s"})', implode('","', $uniqueFields)); + } + + return $annotation; + } } diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index c73dda1a..eab0d7fc 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -94,12 +94,17 @@ public function generateFieldAnnotations($className, $fieldName) if (isset($type)) { $annotation = '@ORM\Column'; + $isColumnHasProperties = false; + + if ($type !== 'string' || $field['isNullable'] || $field['isUnique']) { + $isColumnHasProperties = true; + } if ($field['isArray']) { $type = 'simple_array'; } - if ($type !== 'string' || $field['isNullable']) { + if ($isColumnHasProperties) { $annotation .= '('; } @@ -115,7 +120,15 @@ public function generateFieldAnnotations($className, $fieldName) $annotation .= 'nullable=true'; } - if ($type !== 'string' || $field['isNullable']) { + if ($field['isUnique'] && $field['isNullable']) { + $annotation .= ', '; + } + + if ($field['isUnique']) { + $annotation .= 'unique=true'; + } + + if ($isColumnHasProperties) { $annotation .= ')'; } diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 322adba2..c8cdd76f 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -256,6 +256,7 @@ public function generate($config) 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, 'isArray' => false, 'isNullable' => false, + 'isUnique' => false, 'isCustom' => true, 'isEnum' => false, 'isId' => true, @@ -555,6 +556,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t 'cardinality' => $cardinality, 'isArray' => $isArray, 'isNullable' => $isNullable, + 'isUnique' => $typeConfig['properties'][$propertyName]['unique'], 'isCustom' => empty($property), 'isId' => false, ]; diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 8f3a031c..d378f1f4 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -114,6 +114,7 @@ public function getConfigTreeBuilder() ->prototype('scalar')->end() ->end() ->scalarNode('nullable')->defaultTrue()->info('The property nullable')->end() + ->scalarNode('unique')->defaultFalse()->info('The property unique')->end() ->end() ->end() ->end() From e1c5262a983941f2afa5cdba45dfbd9553f2c0da Mon Sep 17 00:00:00 2001 From: restotelry Date: Sat, 10 Oct 2015 13:56:19 +0200 Subject: [PATCH 026/258] Add full namespace to target-entity --- src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index eab0d7fc..23645390 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -212,6 +212,10 @@ private function getRelationName($range) return $class['interfaceName']; } + if (isset($this->config['namespaces']['entity']) && null !== $this->config['namespaces']['entity']) { + return $this->config['namespaces']['entity'] . '\\' . $class['name']; + } + return $class['name']; } } From ef4993a0970d77ad8ef0686ee64452aa3d72522d Mon Sep 17 00:00:00 2001 From: restotelry Date: Sat, 10 Oct 2015 21:57:05 +0200 Subject: [PATCH 027/258] Fix target-entity cannot be found msg when extending a generated entity --- src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index 23645390..04550479 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -212,8 +212,12 @@ private function getRelationName($range) return $class['interfaceName']; } + if (isset($this->config['types'][$class['name']]['namespaces']['class']) && null !== $this->config['types'][$class['name']]['namespaces']['class']) { + return $this->config['types'][$class['name']]['namespaces']['class'].'\\'.$class['name']; + } + if (isset($this->config['namespaces']['entity']) && null !== $this->config['namespaces']['entity']) { - return $this->config['namespaces']['entity'] . '\\' . $class['name']; + return $this->config['namespaces']['entity'].'\\'.$class['name']; } return $class['name']; From 72d1c309933d923bfe30e25b7a600389ab72e754 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 13 Oct 2015 13:55:28 +0200 Subject: [PATCH 028/258] New CONTRIBUTING.md file --- CONTRIBUTING.md | 105 +++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 96 insertions(+), 9 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1045b771..ee1dda09 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,17 +1,104 @@ -# Contributing +# Contributing to API Platform -## License +First of all, thank you for contributing, you're awesome! -Before you start, you must know that all the patches you are going to submit must be released under the MIT license. +To have your code integrated in the API Platform project, there is some rules to follow, but don't panic, it's easy! -## Run tests +## Reporting bugs -Run the following command: `tests/run-tests.sh` +If you happen to find a bug, we kindly request you to report it. However, before submitting it, please: -## Make a Pull Request + * Check the [project documentation available online](https://api-platform.com/doc/) -All Pull Requests must be open on [the GitHub project page](https://github.com/api-platform/schema-generator). +Then, if it appears that it's a real bug, you may report it using Github by following these 3 points: -## Going further + * Check if the bug is not already reported! + * A clear title to resume the issue + * A description of the workflow needed to reproduce the bug, + +> _NOTE:_ Don’t hesitate giving as much information as you can (OS, PHP version extensions...) + +## Pull requests + +### Writing a Pull Request + +First of all, you must decide on what branch your changes will be based. If the changes your are going to make are +fully backward-compatible, you should base your changes on the latest stable branch (`1.0` at the moment). +Otherwise, you should base your changes on the `master` branch. + +### Matching coding standards + +The API Platform project follows [Symfony coding standards](https://symfony.com/doc/current/contributing/code/standards.html). +But don't worry, you can fix CS issues automatically using the [PHP CS Fixer](http://cs.sensiolabs.org/) tool + +```bash +php-cs-fixer.phar fix +``` + +And then, add fixed file to your commit before push. +Be sure to add only **your modified files**. If another files are fixed by cs tools, just revert it before commit. + +### Sending a Pull Request + +When you send a PR, just make sure that: + +* You add valid test cases (Behat and PHPUnit). +* Tests are green. +* You make a PR on the related documentation in the [api-platform/doc](https://github.com/api-platform/doc) repository. +* You make the PR on the same branch you based your changes on. If you see commits +that you did not make in your PR, you're doing it wrong. +* Also don't forget to add a comment when you update a PR with a ping to the maintainer (`@dunglas`, `@sroze` or `@theofidry`), so he/she will get a notification. +* Squash your commits into one commit. (see the next chapter) + +All Pull Requests must include the following header: + +```markdown +| Q | A +| ------------- | --- +| Bug fix? | yes/no +| New feature? | yes/no +| BC breaks? | no +| Deprecations? | no +| Tests pass? | yes +| Fixed tickets | #1234, #5678 +| License | MIT +| Doc PR | api-platform/doc#1234 +``` + +## Squash your commits + +If you have 3 commits. So start with: + +```bash +git rebase -i HEAD~3 +``` + +An editor will be opened with your 3 commits, all prefixed by `pick`. + +Replace all `pick` prefixes by `fixup` (or `f`) **except the first commit** of the list. + +Save and quit the editor. + +After that, all your commits where squashed into the first one and the commit message of the first commit. + +If you would like to rename your commit message type: + +```bash +git commit --amend +``` + +Now force push to update your PR: + +```bash +git push --force +``` + +# License and copyright attribution + +When you open a Pull Request to the API Platform project, you agree to license your code under the [MIT license](LICENSE) +and to transfer the copyright on the submitted code to Kévin Dunglas. + +Be sure to you have the right to do that (if you are a professional, ask your company)! + +If you include code from another project, please mention it in the Pull Request description and credit the original author. -Read [the Symfony documentation about contributing code](https://symfony.com/doc/current/contributing/code/patches.html). From 3afd1de219ec88f66078ae3b4fcf1b9dc71190d5 Mon Sep 17 00:00:00 2001 From: JhonnyL Date: Sat, 24 Oct 2015 14:25:44 +0200 Subject: [PATCH 029/258] Add embeddable support --- .../DoctrineOrmAnnotationGenerator.php | 13 +++++++++- src/TypesGenerator.php | 26 ++++++++++++++----- src/TypesGeneratorConfiguration.php | 3 +++ 3 files changed, 35 insertions(+), 7 deletions(-) diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index eab0d7fc..4b590674 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -33,7 +33,15 @@ public function generateClassAnnotations($className) if (isset($this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping'])) { $inheritanceMapping = $this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping']; } else { - $inheritanceMapping = $class['abstract'] ? '@ORM\MappedSuperclass' : '@ORM\Entity'; + $inheritanceMapping = '@ORM\Entity'; + + if ($class['abstract']) { + $inheritanceMapping = '@ORM\MappedSuperclass'; + } + + if ($class['embeddable']) { + $inheritanceMapping = '@ORM\Embeddable'; + } } return [ @@ -133,6 +141,9 @@ public function generateFieldAnnotations($className, $fieldName) } $annotations[] = $annotation; + } elseif ($field['isEmbedded']) { + $columnPrefix = $field['columnPrefix'] ? ', columnPrefix=true' : ', columnPrefix=false'; + $annotations[] = sprintf('@ORM\Embedded(class="%s"%s)', $this->getRelationName($field['range']), $columnPrefix); } else { switch ($field['cardinality']) { case CardinalitiesExtractor::CARDINALITY_0_1: diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index c8cdd76f..cf2361be 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -190,6 +190,9 @@ public function generate($config) $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; } + // Embeddable + $class['embeddable'] = isset($typeConfig['embeddable']) ? $typeConfig['embeddable'] : false; + if (!empty($config['types']) && $class['parent'] && !isset($config['types'][$class['parent']])) { $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class['parent'], $type->localName())); } @@ -247,7 +250,7 @@ public function generate($config) // Generate ID if ($config['generateId']) { foreach ($classes as &$class) { - if (!$class['hasChild'] && !$class['isEnum']) { + if (!$class['hasChild'] && !$class['isEnum'] && !$class['embeddable']) { $class['fields'] = [ 'id' => [ 'name' => 'id', @@ -511,9 +514,11 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t } } + $propertyConfig = $typeConfig['properties'][$propertyName]; + $ranges = []; - if (isset($typeConfig['properties'][$propertyName]['range']) && $typeConfig['properties'][$propertyName]['range']) { - $ranges[] = $typeConfig['properties'][$propertyName]['range']; + if (isset($propertyConfig['range']) && $propertyConfig['range']) { + $ranges[] = $propertyConfig['range']; } elseif (!empty($property)) { foreach ($property->all(self::SCHEMA_ORG_RANGE) as $range) { if (!$typesDefined || $this->isDatatype($range->localName()) || isset($config['types'][$range->localName()])) { @@ -530,7 +535,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t $this->logger->error(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); } - $cardinality = isset($typeConfig['properties'][$propertyName]['cardinality']) ? $typeConfig['properties'][$propertyName]['cardinality'] : false; + $cardinality = isset($propertyConfig['cardinality']) ? $propertyConfig['cardinality'] : false; if (!$cardinality || $cardinality === CardinalitiesExtractor::CARDINALITY_UNKNOWN) { $cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1; } @@ -540,7 +545,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t CardinalitiesExtractor::CARDINALITY_N_N, ]); - if (false === $typeConfig['properties'][$propertyName]['nullable']) { + if (false === $propertyConfig['nullable']) { $isNullable = false; } else { $isNullable = !in_array($cardinality, [ @@ -549,6 +554,13 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t ]); } + $columnPrefix = false; + $isEmbedded = isset($propertyConfig['embedded']) ? $propertyConfig['embedded'] : false; + + if (true === $isEmbedded) { + $columnPrefix = isset($propertyConfig['columnPrefix']) ? $propertyConfig['columnPrefix'] : false; + } + $class['fields'][$propertyName] = [ 'name' => $propertyName, 'resource' => $property, @@ -556,8 +568,10 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t 'cardinality' => $cardinality, 'isArray' => $isArray, 'isNullable' => $isNullable, - 'isUnique' => $typeConfig['properties'][$propertyName]['unique'], + 'isUnique' => $propertyConfig['unique'], 'isCustom' => empty($property), + 'isEmbedded' => $isEmbedded, + 'columnPrefix' => $columnPrefix, 'isId' => false, ]; if ($isArray) { diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index d378f1f4..23a06e9a 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -76,6 +76,7 @@ public function getConfigTreeBuilder() ->children() ->scalarNode('vocabularyNamespace')->defaultValue(TypesGenerator::SCHEMA_ORG_NAMESPACE)->info('Namespace of the vocabulary the type belongs to.')->end() ->booleanNode('abstract')->defaultNull()->info('Is the class abstract? (null to guess)')->end() + ->booleanNode('embeddable')->defaultFalse()->info('Is the class embeddable?')->end() ->arrayNode('namespaces') ->addDefaultsIfNotSet() ->info('Type namespaces') @@ -115,6 +116,8 @@ public function getConfigTreeBuilder() ->end() ->scalarNode('nullable')->defaultTrue()->info('The property nullable')->end() ->scalarNode('unique')->defaultFalse()->info('The property unique')->end() + ->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end() + ->booleanNode('columnPrefix')->defaultFalse()->info('The property columnPrefix')->end() ->end() ->end() ->end() From fbfd24ec02dcc4c2e3dbbb2cfde1302414c633be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 21 Nov 2015 17:00:37 +0100 Subject: [PATCH 030/258] Tweak #31 --- .../DoctrineOrmAnnotationGenerator.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index a8c7312c..09c34110 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -223,12 +223,12 @@ private function getRelationName($range) return $class['interfaceName']; } - if (isset($this->config['types'][$class['name']]['namespaces']['class']) && null !== $this->config['types'][$class['name']]['namespaces']['class']) { - return $this->config['types'][$class['name']]['namespaces']['class'].'\\'.$class['name']; + if (isset($this->config['types'][$class['name']]['namespaces']['class']) && null) { + return sprintf('%s\\%s', $this->config['types'][$class['name']]['namespaces']['class'], $class['name']); } - if (isset($this->config['namespaces']['entity']) && null !== $this->config['namespaces']['entity']) { - return $this->config['namespaces']['entity'].'\\'.$class['name']; + if (isset($this->config['namespaces']['entity'])) { + return sprintf('%s\\%s', $this->config['namespaces']['entity'], $class['name']); } return $class['name']; From 087b5c72f3219dc4e2a28babbb1e0aa711404873 Mon Sep 17 00:00:00 2001 From: Lubomir Haralampiev Date: Fri, 16 Oct 2015 17:07:58 +0200 Subject: [PATCH 031/258] fixed the code generation for the remove methods --- composer.lock | 208 ++++++++++++++++++--------------------- templates/class.php.twig | 4 + 2 files changed, 100 insertions(+), 112 deletions(-) diff --git a/composer.lock b/composer.lock index 40c06e2e..ada480a1 100644 --- a/composer.lock +++ b/composer.lock @@ -5,6 +5,7 @@ "This file is @generated automatically" ], "hash": "096a8471cec7fd85d1645e1f389a52e5", + "content-hash": "9c5712d1572b9852d41a558d9612f17b", "packages": [ { "name": "easyrdf/easyrdf", @@ -70,16 +71,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.10", + "version": "v1.10.2", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "8e21b4fb32c4618a425817d9f0daf3d57a9808d1" + "reference": "e8b3c4e41dc1484210fdc45363c41af6c2d56f20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/8e21b4fb32c4618a425817d9f0daf3d57a9808d1", - "reference": "8e21b4fb32c4618a425817d9f0daf3d57a9808d1", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/e8b3c4e41dc1484210fdc45363c41af6c2d56f20", + "reference": "e8b3c4e41dc1484210fdc45363c41af6c2d56f20", "shasum": "" }, "require": { @@ -120,20 +121,20 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-07-27 20:56:10" + "time": "2015-10-21 19:19:43" }, { "name": "league/html-to-markdown", - "version": "4.0.1", + "version": "4.1.1", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "c496c27e01b9dce310e03afbcdf783347738f67b" + "reference": "01bbfe039d9b97526e3f3a3ee32543fc1d8dba00" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/c496c27e01b9dce310e03afbcdf783347738f67b", - "reference": "c496c27e01b9dce310e03afbcdf783347738f67b", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/01bbfe039d9b97526e3f3a3ee32543fc1d8dba00", + "reference": "01bbfe039d9b97526e3f3a3ee32543fc1d8dba00", "shasum": "" }, "require": { @@ -142,13 +143,17 @@ "php": ">=5.3.3" }, "require-dev": { + "mikehaertl/php-shellcommand": "~1.1.0", "phpunit/phpunit": "4.*", "scrutinizer/ocular": "~1.1" }, + "bin": [ + "bin/html-to-markdown" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "4.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -180,7 +185,7 @@ "html", "markdown" ], - "time": "2015-09-01 22:39:54" + "time": "2015-11-20 16:20:25" }, { "name": "psr/log", @@ -274,25 +279,22 @@ }, { "name": "symfony/config", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Config.git", - "reference": "5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8" + "url": "https://github.com/symfony/config.git", + "reference": "831f88908b51b9ce945f5e6f402931d1ac544423" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Config/zipball/5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8", - "reference": "5ab9ff48b3cb5b40951a607f77fc1cbfd29edba8", + "url": "https://api.github.com/repos/symfony/config/zipball/831f88908b51b9ce945f5e6f402931d1ac544423", + "reference": "831f88908b51b9ce945f5e6f402931d1ac544423", "shasum": "" }, "require": { "php": ">=5.3.9", "symfony/filesystem": "~2.3" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { @@ -320,20 +322,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com/", - "time": "2015-08-27 06:45:45" + "time": "2015-10-11 09:39:48" }, { "name": "symfony/console", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Console.git", - "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8" + "url": "https://github.com/symfony/console.git", + "reference": "5efd632294c8320ea52492db22292ff853a43766" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Console/zipball/9ff9032151186bd66ecee727d728f1319f52d1d8", - "reference": "9ff9032151186bd66ecee727d728f1319f52d1d8", + "url": "https://api.github.com/repos/symfony/console/zipball/5efd632294c8320ea52492db22292ff853a43766", + "reference": "5efd632294c8320ea52492db22292ff853a43766", "shasum": "" }, "require": { @@ -342,7 +344,6 @@ "require-dev": { "psr/log": "~1.0", "symfony/event-dispatcher": "~2.1", - "symfony/phpunit-bridge": "~2.7", "symfony/process": "~2.1" }, "suggest": { @@ -377,20 +378,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com/", - "time": "2015-09-03 11:40:38" + "time": "2015-10-20 14:38:46" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/EventDispatcher.git", - "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa" + "url": "https://github.com/symfony/event-dispatcher.git", + "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/EventDispatcher/zipball/b58c916f1db03a611b72dd702564f30ad8fe83fa", - "reference": "b58c916f1db03a611b72dd702564f30ad8fe83fa", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87a5db5ea887763fa3a31a5471b512ff1596d9b8", + "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8", "shasum": "" }, "require": { @@ -401,7 +402,6 @@ "symfony/config": "~2.0,>=2.0.5", "symfony/dependency-injection": "~2.6", "symfony/expression-language": "~2.6", - "symfony/phpunit-bridge": "~2.7", "symfony/stopwatch": "~2.3" }, "suggest": { @@ -435,28 +435,25 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com/", - "time": "2015-08-24 07:13:45" + "time": "2015-10-11 09:39:48" }, { "name": "symfony/filesystem", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Filesystem.git", - "reference": "f079e9933799929584200b9a926f72f29e291654" + "url": "https://github.com/symfony/filesystem.git", + "reference": "56fd6df73be859323ff97418d97edc1d756df6df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Filesystem/zipball/f079e9933799929584200b9a926f72f29e291654", - "reference": "f079e9933799929584200b9a926f72f29e291654", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/56fd6df73be859323ff97418d97edc1d756df6df", + "reference": "56fd6df73be859323ff97418d97edc1d756df6df", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { @@ -484,28 +481,25 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com/", - "time": "2015-08-27 07:03:44" + "time": "2015-10-18 20:23:18" }, { "name": "symfony/finder", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Finder.git", - "reference": "fff4b0c362640a0ab7355e2647b3d461608e9065" + "url": "https://github.com/symfony/finder.git", + "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Finder/zipball/fff4b0c362640a0ab7355e2647b3d461608e9065", - "reference": "fff4b0c362640a0ab7355e2647b3d461608e9065", + "url": "https://api.github.com/repos/symfony/finder/zipball/2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", + "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { @@ -533,28 +527,25 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com/", - "time": "2015-08-26 17:56:37" + "time": "2015-10-11 09:39:48" }, { "name": "symfony/process", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Process.git", - "reference": "f7b3f73f70a7f8f49a1c838dc3debbf054732d8e" + "url": "https://github.com/symfony/process.git", + "reference": "4a959dd4e19c2c5d7512689413921e0a74386ec7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Process/zipball/f7b3f73f70a7f8f49a1c838dc3debbf054732d8e", - "reference": "f7b3f73f70a7f8f49a1c838dc3debbf054732d8e", + "url": "https://api.github.com/repos/symfony/process/zipball/4a959dd4e19c2c5d7512689413921e0a74386ec7", + "reference": "4a959dd4e19c2c5d7512689413921e0a74386ec7", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { @@ -582,28 +573,25 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com/", - "time": "2015-08-27 06:45:45" + "time": "2015-10-23 14:47:27" }, { "name": "symfony/stopwatch", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Stopwatch.git", - "reference": "abc61bac76fb10ffa2c6373d7932bc35190dbf3b" + "url": "https://github.com/symfony/stopwatch.git", + "reference": "f8ab957c17e4b85a73c4df03bdf94ee597f2bd55" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Stopwatch/zipball/abc61bac76fb10ffa2c6373d7932bc35190dbf3b", - "reference": "abc61bac76fb10ffa2c6373d7932bc35190dbf3b", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f8ab957c17e4b85a73c4df03bdf94ee597f2bd55", + "reference": "f8ab957c17e4b85a73c4df03bdf94ee597f2bd55", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { @@ -631,28 +619,25 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com/", - "time": "2015-08-24 07:13:45" + "time": "2015-10-12 12:42:24" }, { "name": "symfony/yaml", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Yaml.git", - "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661" + "url": "https://github.com/symfony/yaml.git", + "reference": "eca9019c88fbe250164affd107bc8057771f3f4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Yaml/zipball/2dc7b06c065df96cc686c66da2705e5e18aef661", - "reference": "2dc7b06c065df96cc686c66da2705e5e18aef661", + "url": "https://api.github.com/repos/symfony/yaml/zipball/eca9019c88fbe250164affd107bc8057771f3f4d", + "reference": "eca9019c88fbe250164affd107bc8057771f3f4d", "shasum": "" }, "require": { "php": ">=5.3.9" }, - "require-dev": { - "symfony/phpunit-bridge": "~2.7" - }, "type": "library", "extra": { "branch-alias": { @@ -680,20 +665,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com/", - "time": "2015-08-24 07:13:45" + "time": "2015-10-11 09:39:48" }, { "name": "twig/twig", - "version": "v1.22.1", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "b7fc2469fa009897871fb95b68237286fc54a5ad" + "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/b7fc2469fa009897871fb95b68237286fc54a5ad", - "reference": "b7fc2469fa009897871fb95b68237286fc54a5ad", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6", + "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6", "shasum": "" }, "require": { @@ -706,7 +691,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.22-dev" + "dev-master": "1.23-dev" } }, "autoload": { @@ -741,7 +726,7 @@ "keywords": [ "templating" ], - "time": "2015-09-15 06:50:16" + "time": "2015-11-05 12:49:06" } ], "packages-dev": [ @@ -815,16 +800,16 @@ }, { "name": "doctrine/cache", - "version": "v1.4.2", + "version": "v1.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca" + "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/8c434000f420ade76a07c64cbe08ca47e5c101ca", - "reference": "8c434000f420ade76a07c64cbe08ca47e5c101ca", + "url": "https://api.github.com/repos/doctrine/cache/zipball/2b9cec5a5e722010cbebc91713d4c11eaa064d5e", + "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e", "shasum": "" }, "require": { @@ -845,8 +830,8 @@ } }, "autoload": { - "psr-0": { - "Doctrine\\Common\\Cache\\": "lib/" + "psr-4": { + "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" } }, "notification-url": "https://packagist.org/downloads/", @@ -881,7 +866,7 @@ "cache", "caching" ], - "time": "2015-08-31 12:36:41" + "time": "2015-11-02 18:35:48" }, { "name": "doctrine/collections", @@ -1095,16 +1080,16 @@ }, { "name": "doctrine/inflector", - "version": "v1.0.1", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604" + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/0bcb2e79d8571787f18b7eb036ed3d004908e604", - "reference": "0bcb2e79d8571787f18b7eb036ed3d004908e604", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", + "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", "shasum": "" }, "require": { @@ -1116,7 +1101,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.1.x-dev" } }, "autoload": { @@ -1158,7 +1143,7 @@ "singularize", "string" ], - "time": "2014-12-20 21:24:13" + "time": "2015-11-06 14:35:42" }, { "name": "doctrine/instantiator", @@ -1347,16 +1332,16 @@ }, { "name": "symfony/translation", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Translation.git", - "reference": "485877661835e188cd78345c6d4eef1290d17571" + "url": "https://github.com/symfony/translation.git", + "reference": "6ccd9289ec1c71d01a49d83480de3b5293ce30c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Translation/zipball/485877661835e188cd78345c6d4eef1290d17571", - "reference": "485877661835e188cd78345c6d4eef1290d17571", + "url": "https://api.github.com/repos/symfony/translation/zipball/6ccd9289ec1c71d01a49d83480de3b5293ce30c8", + "reference": "6ccd9289ec1c71d01a49d83480de3b5293ce30c8", "shasum": "" }, "require": { @@ -1369,7 +1354,6 @@ "psr/log": "~1.0", "symfony/config": "~2.7", "symfony/intl": "~2.4", - "symfony/phpunit-bridge": "~2.7", "symfony/yaml": "~2.2" }, "suggest": { @@ -1404,20 +1388,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com/", - "time": "2015-09-06 08:36:38" + "time": "2015-10-27 15:38:06" }, { "name": "symfony/validator", - "version": "v2.7.4", + "version": "v2.7.6", "source": { "type": "git", - "url": "https://github.com/symfony/Validator.git", - "reference": "356459a697e26274d44c608513c05c23dc1d8ea7" + "url": "https://github.com/symfony/validator.git", + "reference": "df9021e689aa3d08367881e7f8917219fabe5e64" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/Validator/zipball/356459a697e26274d44c608513c05c23dc1d8ea7", - "reference": "356459a697e26274d44c608513c05c23dc1d8ea7", + "url": "https://api.github.com/repos/symfony/validator/zipball/df9021e689aa3d08367881e7f8917219fabe5e64", + "reference": "df9021e689aa3d08367881e7f8917219fabe5e64", "shasum": "" }, "require": { @@ -1427,12 +1411,12 @@ "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", + "doctrine/common": "~2.3", "egulias/email-validator": "~1.2,>=1.2.1", "symfony/config": "~2.2", "symfony/expression-language": "~2.4", "symfony/http-foundation": "~2.1", "symfony/intl": "~2.4", - "symfony/phpunit-bridge": "~2.7", "symfony/property-access": "~2.3", "symfony/yaml": "~2.0,>=2.0.5" }, @@ -1474,7 +1458,7 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", - "time": "2015-09-06 08:36:38" + "time": "2015-10-18 20:23:18" } ], "aliases": [], diff --git a/templates/class.php.twig b/templates/class.php.twig index d8adc177..d3cd6887 100644 --- a/templates/class.php.twig +++ b/templates/class.php.twig @@ -76,10 +76,14 @@ use {{ use }}; */ public function remove{{ field.name|ucfirst }}({% if field.typeHint %}{{ field.typeHint }} {% endif %}${{ field.name }}) { +{% if config.doctrine.useCollection and field.isArray and field.typeHint and not field.isEnum %} + $this->{{ field.name }}->removeElement({% if field.isEnum %}(string) {% endif %}${{ field.name }}); +{% else %} $key = array_search({% if field.isEnum %}(string) {% endif %}${{ field.name }}, $this->{{ field.name }}, true); if (false !== $key) { unset($this->{{ field.name }}[$key]); } +{% endif %} return $this; } From d543d29a52373a842b5795f3b6f556adfb5b1f65 Mon Sep 17 00:00:00 2001 From: scurron Date: Sat, 21 Nov 2015 23:56:42 +0100 Subject: [PATCH 032/258] Fixes target-entity namespace generation --- src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index 09c34110..69723a6f 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -223,7 +223,7 @@ private function getRelationName($range) return $class['interfaceName']; } - if (isset($this->config['types'][$class['name']]['namespaces']['class']) && null) { + if (isset($this->config['types'][$class['name']]['namespaces']['class'])) { return sprintf('%s\\%s', $this->config['types'][$class['name']]['namespaces']['class'], $class['name']); } From 7c19009f3a2086f00e8a3caf740544a0202fd58a Mon Sep 17 00:00:00 2001 From: scurron Date: Sun, 22 Nov 2015 00:18:37 +0100 Subject: [PATCH 033/258] Inserts parent class namespace when generating a class hierarchy --- src/TypesGenerator.php | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index cf2361be..4cbf6a9d 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -190,6 +190,10 @@ public function generate($config) $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; } + if (null !== $class['parent']) { + $class['uses'][] = sprintf('%s\\%s', $config['types']['Thing']['namespaces']['class'], $class['parent']); + } + // Embeddable $class['embeddable'] = isset($typeConfig['embeddable']) ? $typeConfig['embeddable'] : false; From 03a7db885553d899938590d870642dd72992b7b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=A9my=20Hubert?= Date: Wed, 2 Dec 2015 13:19:01 +0100 Subject: [PATCH 034/258] Added ability to create custom classes --- src/TypesGenerator.php | 28 +++++++++++++++++----------- src/TypesGeneratorConfiguration.php | 1 + templates/interface.php.twig | 2 ++ tests/config/ecommerce.yml | 7 +++++++ 4 files changed, 27 insertions(+), 11 deletions(-) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index cf2361be..5a4aa012 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -141,7 +141,9 @@ public function generate($config) if ($resource) { $typesToGenerate[] = $resource; } else { - $this->logger->critical('Type "{key}" cannot be found.', ['key' => $key]); + $this->logger->warning('Type "{key}" cannot be found. Using "{guessFrom}" type to generate entity.', ['key' => $key, 'guessFrom' => $value['guessFrom']]); + $type = $graph->resource($value['vocabularyNamespace'].$value['guessFrom'], 'rdfs:Class'); + $typesToGenerate[$key] = $type; } } } @@ -149,11 +151,12 @@ public function generate($config) $classes = []; $propertiesMap = $this->createPropertiesMap($typesToGenerate); - foreach ($typesToGenerate as $type) { - $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; + foreach ($typesToGenerate as $key => $type) { + $typeName = is_string($key) ? $key : $type->localName(); + $typeConfig = isset($config['types'][$typeName]) ? $config['types'][$typeName] : null; $class = $baseClass; - $class['name'] = $type->localName(); + $class['name'] = $typeName; $class['label'] = $type->get('rdfs:comment')->getValue(); $class['resource'] = $type; $class['config'] = $typeConfig; @@ -200,7 +203,7 @@ public function generate($config) // Interfaces if ($config['useInterface']) { $class['interfaceNamespace'] = isset($typeConfig['namespaces']['interface']) && $typeConfig['namespaces']['interface'] ? $typeConfig['namespaces']['interface'] : $config['namespaces']['interface']; - $class['interfaceName'] = sprintf('%sInterface', $type->localName()); + $class['interfaceName'] = sprintf('%sInterface', $typeName); } } @@ -211,7 +214,7 @@ public function generate($config) continue; } - $class = $this->generateField($config, $class, $type, $property->localName(), $property); + $class = $this->generateField($config, $class, $type, $typeName, $property->localName(), $property); } // Add custom fields (non schema.org) @@ -219,11 +222,11 @@ public function generate($config) foreach (array_diff_key($typeConfig['properties'], $class['fields']) as $propertyName => $property) { $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->localName())); - $class = $this->generateField($config, $class, $type, $propertyName); + $class = $this->generateField($config, $class, $type, $typeName, $propertyName); } } - $classes[$type->localName()] = $class; + $classes[$typeName] = $class; } // Second pass @@ -285,7 +288,9 @@ public function generate($config) foreach ($classes as $className => &$class) { $class['uses'] = $this->generateClassUses($annotationGenerators, $classes, $className); $class['annotations'] = $this->generateClassAnnotations($annotationGenerators, $className); - $class['interfaceAnnotations'] = $this->generateInterfaceAnnotations($annotationGenerators, $className); + if (false === isset($typesToGenerate[$className])) { + $class['interfaceAnnotations'] = $this->generateInterfaceAnnotations($annotationGenerators, $className); + } foreach ($class['constants'] as $constantName => $constant) { $class['constants'][$constantName]['annotations'] = $this->generateConstantAnnotations($annotationGenerators, $className, $constantName); @@ -486,14 +491,15 @@ private function isDateTime($type) * @param array $config * @param array $class * @param \EasyRdf_Resource $type + * @param string $typeName * @param string $propertyName * @param \EasyRdf_Resource|null $property * * @return array $class */ - private function generateField(array $config, array $class, \EasyRdf_Resource $type, $propertyName, \EasyRdf_Resource $property = null) + private function generateField(array $config, array $class, \EasyRdf_Resource $type, $typeName, $propertyName, \EasyRdf_Resource $property = null) { - $typeConfig = isset($config['types'][$type->localName()]) ? $config['types'][$type->localName()] : null; + $typeConfig = isset($config['types'][$typeName]) ? $config['types'][$typeName] : null; $typesDefined = !empty($config['types']); // Warn when property are not part of GoodRelations diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 23a06e9a..c3f3b69f 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -92,6 +92,7 @@ public function getConfigTreeBuilder() ->end() ->end() ->scalarNode('parent')->defaultNull()->info('The parent class, set to false for a top level class')->end() + ->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end() ->arrayNode('properties') ->info('Properties of this type to use') ->useAttributeAsKey('id') diff --git a/templates/interface.php.twig b/templates/interface.php.twig index 3d0c1ef4..c7226b26 100644 --- a/templates/interface.php.twig +++ b/templates/interface.php.twig @@ -10,11 +10,13 @@ namespace {{ class.interfaceNamespace }}; +{% if class.interfaceAnnotations|length > 0 %} /** {% for annotation in class.interfaceAnnotations %} * {{ annotation }} {% endfor %} */ +{% endif %} interface {{ class.interfaceName }} { } diff --git a/tests/config/ecommerce.yml b/tests/config/ecommerce.yml index c5757f19..fd186997 100644 --- a/tests/config/ecommerce.yml +++ b/tests/config/ecommerce.yml @@ -45,10 +45,17 @@ types: height: { range: "Text" } weight: { range: "Text" } width: { range: "Text" } + seller: { range: "Seller" } Brand: parent: "Thing" properties: logo: { range: "ImageObject" } + Seller: + parent: false + guessFrom: Person + properties: + name: ~ + birthDate: ~ ImageObject: parent: Thing properties: From be5d92eb68e2acc649c5183990dc9a53c50fc705 Mon Sep 17 00:00:00 2001 From: yohang Date: Wed, 16 Dec 2015 09:39:32 +0100 Subject: [PATCH 035/258] Made compatible with Symfony 3.0 * Updated composer version constraints * Updated test-suite YAML files --- composer.json | 6 +- composer.lock | 361 +++++++++++++++++++++------------- tests/config/address-book.yml | 2 +- tests/config/ecommerce.yml | 6 +- tests/config/vgo.yml | 2 +- 5 files changed, 232 insertions(+), 145 deletions(-) diff --git a/composer.json b/composer.json index f5803c1f..c5e398eb 100644 --- a/composer.json +++ b/composer.json @@ -17,9 +17,9 @@ "require": { "php": ">=5.4", "ext-json": "*", - "symfony/console": "~2.5", - "symfony/yaml": "~2.4", - "symfony/config": "~2.4", + "symfony/console": "~2.5|~3.0", + "symfony/yaml": "~2.4|~3.0", + "symfony/config": "~2.4|~3.0", "twig/twig": "~1.0", "psr/log": "~1.0", "easyrdf/easyrdf": "~0.9.0", diff --git a/composer.lock b/composer.lock index ada480a1..1f32fa19 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "096a8471cec7fd85d1645e1f389a52e5", - "content-hash": "9c5712d1572b9852d41a558d9612f17b", + "hash": "d90df784ad2c70ce79dc716881144741", + "content-hash": "902da9fc5e839837f3fc831966648c32", "packages": [ { "name": "easyrdf/easyrdf", @@ -71,28 +71,28 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.10.2", + "version": "v1.11", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "e8b3c4e41dc1484210fdc45363c41af6c2d56f20" + "reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/e8b3c4e41dc1484210fdc45363c41af6c2d56f20", - "reference": "e8b3c4e41dc1484210fdc45363c41af6c2d56f20", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef", + "reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef", "shasum": "" }, "require": { "ext-tokenizer": "*", "php": ">=5.3.6", "sebastian/diff": "~1.1", - "symfony/console": "~2.3", - "symfony/event-dispatcher": "~2.1", - "symfony/filesystem": "~2.1", - "symfony/finder": "~2.1", - "symfony/process": "~2.3", - "symfony/stopwatch": "~2.5" + "symfony/console": "~2.3|~3.0", + "symfony/event-dispatcher": "~2.1|~3.0", + "symfony/filesystem": "~2.1|~3.0", + "symfony/finder": "~2.1|~3.0", + "symfony/process": "~2.3|~3.0", + "symfony/stopwatch": "~2.5|~3.0" }, "require-dev": { "satooshi/php-coveralls": "0.7.*@dev" @@ -121,7 +121,7 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-10-21 19:19:43" + "time": "2015-12-01 22:34:33" }, { "name": "league/html-to-markdown", @@ -227,28 +227,28 @@ }, { "name": "sebastian/diff", - "version": "1.3.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3" + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/863df9687835c62aa423a22412d26fa2ebde3fd3", - "reference": "863df9687835c62aa423a22412d26fa2ebde3fd3", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", + "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "~4.8" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -271,40 +271,43 @@ } ], "description": "Diff implementation", - "homepage": "http://www.github.com/sebastianbergmann/diff", + "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ "diff" ], - "time": "2015-02-22 15:13:53" + "time": "2015-12-08 07:14:41" }, { "name": "symfony/config", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "831f88908b51b9ce945f5e6f402931d1ac544423" + "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/831f88908b51b9ce945f5e6f402931d1ac544423", - "reference": "831f88908b51b9ce945f5e6f402931d1ac544423", + "url": "https://api.github.com/repos/symfony/config/zipball/40bae8658dbbb500ebc19aa9fde22dc4295fc290", + "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290", "shasum": "" }, "require": { - "php": ">=5.3.9", - "symfony/filesystem": "~2.3" + "php": ">=5.5.9", + "symfony/filesystem": "~2.8|~3.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Config\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -322,29 +325,30 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com/", - "time": "2015-10-11 09:39:48" + "time": "2015-11-02 20:34:04" }, { "name": "symfony/console", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5efd632294c8320ea52492db22292ff853a43766" + "reference": "175871ca8d1ef16ff8d8cac395a1c73afa8d0e63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5efd632294c8320ea52492db22292ff853a43766", - "reference": "5efd632294c8320ea52492db22292ff853a43766", + "url": "https://api.github.com/repos/symfony/console/zipball/175871ca8d1ef16ff8d8cac395a1c73afa8d0e63", + "reference": "175871ca8d1ef16ff8d8cac395a1c73afa8d0e63", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.1", - "symfony/process": "~2.1" + "symfony/event-dispatcher": "~2.8|~3.0", + "symfony/process": "~2.8|~3.0" }, "suggest": { "psr/log": "For using the console logger", @@ -354,13 +358,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Console\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -378,31 +385,31 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com/", - "time": "2015-10-20 14:38:46" + "time": "2015-11-30 12:36:17" }, { "name": "symfony/event-dispatcher", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8" + "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/87a5db5ea887763fa3a31a5471b512ff1596d9b8", - "reference": "87a5db5ea887763fa3a31a5471b512ff1596d9b8", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d36355e026905fa5229e1ed7b4e9eda2e67adfcf", + "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5", - "symfony/dependency-injection": "~2.6", - "symfony/expression-language": "~2.6", - "symfony/stopwatch": "~2.3" + "symfony/config": "~2.8|~3.0", + "symfony/dependency-injection": "~2.8|~3.0", + "symfony/expression-language": "~2.8|~3.0", + "symfony/stopwatch": "~2.8|~3.0" }, "suggest": { "symfony/dependency-injection": "", @@ -411,13 +418,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\EventDispatcher\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -435,35 +445,38 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com/", - "time": "2015-10-11 09:39:48" + "time": "2015-10-30 23:35:59" }, { "name": "symfony/filesystem", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "56fd6df73be859323ff97418d97edc1d756df6df" + "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/56fd6df73be859323ff97418d97edc1d756df6df", - "reference": "56fd6df73be859323ff97418d97edc1d756df6df", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/692d98d813e4ef314b9c22775c86ddbeb0f44884", + "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Filesystem\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -481,35 +494,38 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com/", - "time": "2015-10-18 20:23:18" + "time": "2015-11-23 10:41:47" }, { "name": "symfony/finder", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d" + "reference": "3577eb98dba90721d1a0a3edfc6956ab8b1aecee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", - "reference": "2ffb4e9598db3c48eb6d0ae73b04bbf09280c59d", + "url": "https://api.github.com/repos/symfony/finder/zipball/3577eb98dba90721d1a0a3edfc6956ab8b1aecee", + "reference": "3577eb98dba90721d1a0a3edfc6956ab8b1aecee", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Finder\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -527,35 +543,94 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com/", - "time": "2015-10-11 09:39:48" + "time": "2015-10-30 23:35:59" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "0b6a8940385311a24e060ec1fe35680e17c74497" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497", + "reference": "0b6a8940385311a24e060ec1fe35680e17c74497", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com/", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "time": "2015-11-04 20:28:58" }, { "name": "symfony/process", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "4a959dd4e19c2c5d7512689413921e0a74386ec7" + "reference": "01383ed02a1020759bc8ee5d975fcec04ba16fbf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/4a959dd4e19c2c5d7512689413921e0a74386ec7", - "reference": "4a959dd4e19c2c5d7512689413921e0a74386ec7", + "url": "https://api.github.com/repos/symfony/process/zipball/01383ed02a1020759bc8ee5d975fcec04ba16fbf", + "reference": "01383ed02a1020759bc8ee5d975fcec04ba16fbf", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Process\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -573,35 +648,38 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com/", - "time": "2015-10-23 14:47:27" + "time": "2015-11-30 12:36:17" }, { "name": "symfony/stopwatch", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "f8ab957c17e4b85a73c4df03bdf94ee597f2bd55" + "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f8ab957c17e4b85a73c4df03bdf94ee597f2bd55", - "reference": "f8ab957c17e4b85a73c4df03bdf94ee597f2bd55", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6aeac8907e3e1340a0033b0a9ec075f8e6524800", + "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Stopwatch\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -619,35 +697,38 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com/", - "time": "2015-10-12 12:42:24" + "time": "2015-10-30 23:35:59" }, { "name": "symfony/yaml", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "eca9019c88fbe250164affd107bc8057771f3f4d" + "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/eca9019c88fbe250164affd107bc8057771f3f4d", - "reference": "eca9019c88fbe250164affd107bc8057771f3f4d", + "url": "https://api.github.com/repos/symfony/yaml/zipball/177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", + "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Yaml\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -665,7 +746,7 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com/", - "time": "2015-10-11 09:39:48" + "time": "2015-11-30 12:36:17" }, { "name": "twig/twig", @@ -800,16 +881,16 @@ }, { "name": "doctrine/cache", - "version": "v1.5.1", + "version": "v1.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e" + "reference": "47c7128262da274f590ae6f86eb137a7a64e82af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/2b9cec5a5e722010cbebc91713d4c11eaa064d5e", - "reference": "2b9cec5a5e722010cbebc91713d4c11eaa064d5e", + "url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af", + "reference": "47c7128262da274f590ae6f86eb137a7a64e82af", "shasum": "" }, "require": { @@ -866,7 +947,7 @@ "cache", "caching" ], - "time": "2015-11-02 18:35:48" + "time": "2015-12-03 10:50:37" }, { "name": "doctrine/collections", @@ -936,16 +1017,16 @@ }, { "name": "doctrine/common", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9" + "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0009b8f0d4a917aabc971fb089eba80e872f83f9", - "reference": "0009b8f0d4a917aabc971fb089eba80e872f83f9", + "url": "https://api.github.com/repos/doctrine/common/zipball/311001fd9865a4d0d59efff4eac6d7dcb3f5270c", + "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c", "shasum": "" }, "require": { @@ -962,7 +1043,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6.x-dev" + "dev-master": "2.5.x-dev" } }, "autoload": { @@ -1005,7 +1086,7 @@ "persistence", "spl" ], - "time": "2015-08-31 13:00:22" + "time": "2015-12-04 12:49:42" }, { "name": "doctrine/dbal", @@ -1255,16 +1336,16 @@ }, { "name": "doctrine/orm", - "version": "v2.5.1", + "version": "v2.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "e6a83bedbe67579cb0bfb688e982e617943a2945" + "reference": "464b5fdbfbbeb4a65465ac173c4c5d90960f41ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/e6a83bedbe67579cb0bfb688e982e617943a2945", - "reference": "e6a83bedbe67579cb0bfb688e982e617943a2945", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/464b5fdbfbbeb4a65465ac173c4c5d90960f41ff", + "reference": "464b5fdbfbbeb4a65465ac173c4c5d90960f41ff", "shasum": "" }, "require": { @@ -1275,12 +1356,12 @@ "doctrine/instantiator": "~1.0.1", "ext-pdo": "*", "php": ">=5.4", - "symfony/console": "~2.5" + "symfony/console": "~2.5|~3.0" }, "require-dev": { "phpunit/phpunit": "~4.0", "satooshi/php-coveralls": "dev-master", - "symfony/yaml": "~2.1" + "symfony/yaml": "~2.3|~3.0" }, "suggest": { "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" @@ -1328,33 +1409,34 @@ "database", "orm" ], - "time": "2015-08-31 12:59:39" + "time": "2015-11-23 12:44:25" }, { "name": "symfony/translation", - "version": "v2.7.6", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "6ccd9289ec1c71d01a49d83480de3b5293ce30c8" + "reference": "7f14717150a7445f8475864d1235875dd04061fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/6ccd9289ec1c71d01a49d83480de3b5293ce30c8", - "reference": "6ccd9289ec1c71d01a49d83480de3b5293ce30c8", + "url": "https://api.github.com/repos/symfony/translation/zipball/7f14717150a7445f8475864d1235875dd04061fb", + "reference": "7f14717150a7445f8475864d1235875dd04061fb", "shasum": "" }, "require": { - "php": ">=5.3.9" + "php": ">=5.5.9", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/config": "<2.7" + "symfony/config": "<2.8" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.7", - "symfony/intl": "~2.4", - "symfony/yaml": "~2.2" + "symfony/config": "~2.8|~3.0", + "symfony/intl": "~2.8|~3.0", + "symfony/yaml": "~2.8|~3.0" }, "suggest": { "psr/log": "To use logging capability in translator", @@ -1364,13 +1446,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "3.0-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Translation\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1388,37 +1473,36 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com/", - "time": "2015-10-27 15:38:06" + "time": "2015-11-18 13:48:51" }, { "name": "symfony/validator", - "version": "v2.7.6", + "version": "v2.8.0", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "df9021e689aa3d08367881e7f8917219fabe5e64" + "reference": "8c42b96f5b23f0642c1a518addafcef8077154a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/df9021e689aa3d08367881e7f8917219fabe5e64", - "reference": "df9021e689aa3d08367881e7f8917219fabe5e64", + "url": "https://api.github.com/repos/symfony/validator/zipball/8c42b96f5b23f0642c1a518addafcef8077154a2", + "reference": "8c42b96f5b23f0642c1a518addafcef8077154a2", "shasum": "" }, "require": { "php": ">=5.3.9", - "symfony/translation": "~2.4" + "symfony/translation": "~2.4|~3.0.0" }, "require-dev": { "doctrine/annotations": "~1.0", "doctrine/cache": "~1.0", - "doctrine/common": "~2.3", "egulias/email-validator": "~1.2,>=1.2.1", - "symfony/config": "~2.2", - "symfony/expression-language": "~2.4", - "symfony/http-foundation": "~2.1", - "symfony/intl": "~2.4", - "symfony/property-access": "~2.3", - "symfony/yaml": "~2.0,>=2.0.5" + "symfony/config": "~2.2|~3.0.0", + "symfony/expression-language": "~2.4|~3.0.0", + "symfony/http-foundation": "~2.1|~3.0.0", + "symfony/intl": "~2.4|~3.0.0", + "symfony/property-access": "~2.3|~3.0.0", + "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" }, "suggest": { "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", @@ -1434,13 +1518,16 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.7-dev" + "dev-master": "2.8-dev" } }, "autoload": { "psr-4": { "Symfony\\Component\\Validator\\": "" - } + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1458,7 +1545,7 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", - "time": "2015-10-18 20:23:18" + "time": "2015-11-20 14:39:26" } ], "aliases": [], diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index 38c59c92..038d624f 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -1,6 +1,6 @@ # The PHP namespace of generated entities namespaces: - entity: "AddressBook\Entity" + entity: 'AddressBook\Entity' # Enable DunglasApiAnnotationGenerator annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator diff --git a/tests/config/ecommerce.yml b/tests/config/ecommerce.yml index c5757f19..429f4674 100644 --- a/tests/config/ecommerce.yml +++ b/tests/config/ecommerce.yml @@ -12,9 +12,9 @@ rdfa: relations: - tests/data/v1.owl namespaces: - entity: "Dunglas\EcommerceBundle\Entity" - enum: "Dunglas\EcommerceBundle\Enum" - interface: "Dunglas\EcommerceBundle\Model" + entity: 'Dunglas\EcommerceBundle\Entity' + enum: 'Dunglas\EcommerceBundle\Enum' + interface: 'Dunglas\EcommerceBundle\Model' author: "Kévin Dunglas " debug: true useInterface: true diff --git a/tests/config/vgo.yml b/tests/config/vgo.yml index f31af863..b98a79f5 100644 --- a/tests/config/vgo.yml +++ b/tests/config/vgo.yml @@ -5,7 +5,7 @@ annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator namespaces: - entity: AppBundle\Entity + entity: 'AppBundle\Entity' types: Session: vocabularyNamespace: http://purl.org/net/VideoGameOntology# From ff27d29755f674d20776fd1a70004b957dcffd8e Mon Sep 17 00:00:00 2001 From: Youssef El Montaser Date: Mon, 28 Dec 2015 22:35:07 +0000 Subject: [PATCH 036/258] Fix some display errors --- tests/config/address-book.yml | 2 +- tests/config/ecommerce.yml | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index 038d624f..f1d99983 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -17,7 +17,7 @@ types: givenName: ~ additionalName: ~ gender: ~ - address: ~ + address: { range: PostalAddress } birthDate: ~ telephone: ~ email: ~ diff --git a/tests/config/ecommerce.yml b/tests/config/ecommerce.yml index 429f4674..e034d9d6 100644 --- a/tests/config/ecommerce.yml +++ b/tests/config/ecommerce.yml @@ -24,7 +24,7 @@ types: properties: name: ~ description: ~ - image: ~ + image: { range: ImageObject } additionalType: ~ Product: properties: @@ -32,7 +32,7 @@ types: cardinality: "(0..1)" url: ~ brand: ~ - productId: ~ + productID: ~ releaseDate: ~ offers: ~ itemCondition: ~ @@ -68,13 +68,14 @@ types: deliveryLeadTime: ~ inventoryLevel: ~ itemCondition: ~ - price: ~ + price: { range: Number } priceCurrency: ~ validFrom: ~ validThrough: ~ - DeliveryChargeSpecification: ~ - PaymentChargeSpecification: ~ + DeliveryChargeSpecification: { parent: false } + PaymentChargeSpecification: { parent: false } OfferItemCondition: ~ PaymentMethod: ~ ItemAvailability: ~ DeliveryMethod: ~ + QuantitativeValue: { parent: false } From 50b515dee7139555a12ca1b9b34c71b81d993838 Mon Sep 17 00:00:00 2001 From: Kevin Eyermann Date: Thu, 28 Jan 2016 09:16:54 +0100 Subject: [PATCH 037/258] custom ORM\Column annotation --- .../DoctrineOrmAnnotationGenerator.php | 56 ++++++++++--------- src/TypesGenerator.php | 7 ++- src/TypesGeneratorConfiguration.php | 1 + 3 files changed, 36 insertions(+), 28 deletions(-) diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index 69723a6f..2f2632df 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -104,40 +104,44 @@ public function generateFieldAnnotations($className, $fieldName) $annotation = '@ORM\Column'; $isColumnHasProperties = false; - if ($type !== 'string' || $field['isNullable'] || $field['isUnique']) { - $isColumnHasProperties = true; - } + if ($field['ormColumn']) { + $annotation .= '('.$field['ormColumn'].')'; + } else { + if ($type !== 'string' || $field['isNullable'] || $field['isUnique']) { + $isColumnHasProperties = true; + } - if ($field['isArray']) { - $type = 'simple_array'; - } + if ($field['isArray']) { + $type = 'simple_array'; + } - if ($isColumnHasProperties) { - $annotation .= '('; - } + if ($isColumnHasProperties) { + $annotation .= '('; + } - if ($type !== 'string') { - $annotation .= sprintf('type="%s"', $type); - } + if ($type !== 'string') { + $annotation .= sprintf('type="%s"', $type); + } - if ($type !== 'string' && $field['isNullable']) { - $annotation .= ', '; - } + if ($type !== 'string' && $field['isNullable']) { + $annotation .= ', '; + } - if ($field['isNullable']) { - $annotation .= 'nullable=true'; - } + if ($field['isNullable']) { + $annotation .= 'nullable=true'; + } - if ($field['isUnique'] && $field['isNullable']) { - $annotation .= ', '; - } + if ($field['isUnique'] && $field['isNullable']) { + $annotation .= ', '; + } - if ($field['isUnique']) { - $annotation .= 'unique=true'; - } + if ($field['isUnique']) { + $annotation .= 'unique=true'; + } - if ($isColumnHasProperties) { - $annotation .= ')'; + if ($isColumnHasProperties) { + $annotation .= ')'; + } } $annotations[] = $annotation; diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 5a4aa012..3d8d3f7d 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -260,6 +260,7 @@ public function generate($config) 'resource' => null, 'range' => 'Integer', 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, + 'ormColumn' => null, 'isArray' => false, 'isNullable' => false, 'isUnique' => false, @@ -546,6 +547,8 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t $cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1; } + $ormColumn = isset($propertyConfig['ormColumn']) ? $propertyConfig['ormColumn'] : null; + $isArray = in_array($cardinality, [ CardinalitiesExtractor::CARDINALITY_1_N, CardinalitiesExtractor::CARDINALITY_N_N, @@ -572,6 +575,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t 'resource' => $property, 'range' => $ranges[0], 'cardinality' => $cardinality, + 'ormColumn' => $ormColumn, 'isArray' => $isArray, 'isNullable' => $isNullable, 'isUnique' => $propertyConfig['unique'], @@ -755,8 +759,7 @@ private function generateClassUses($annotationGenerators, $classes, $className) { $uses = $classes[$className]['uses']; - if ( - isset($classes[$className]['interfaceNamespace']) + if (isset($classes[$className]['interfaceNamespace']) && $classes[$className]['interfaceNamespace'] !== $classes[$className]['namespace'] ) { $uses[] = sprintf( diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index c3f3b69f..2833d47a 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -111,6 +111,7 @@ public function getConfigTreeBuilder() CardinalitiesExtractor::CARDINALITY_N_N, CardinalitiesExtractor::CARDINALITY_UNKNOWN, ])->end() + ->scalarNode('ormColumn')->defaultNull()->info('The doctrine column annotation content')->example('type="decimal", precision=2, scale=1, options={"comment" = "my comment"}')->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') ->prototype('scalar')->end() From 631442afa8e273de2589a8c3de92379674930e27 Mon Sep 17 00:00:00 2001 From: Kevin Eyermann Date: Thu, 28 Jan 2016 09:37:56 +0100 Subject: [PATCH 038/258] push for travis --- src/TypesGeneratorConfiguration.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 2833d47a..c7765615 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -111,7 +111,7 @@ public function getConfigTreeBuilder() CardinalitiesExtractor::CARDINALITY_N_N, CardinalitiesExtractor::CARDINALITY_UNKNOWN, ])->end() - ->scalarNode('ormColumn')->defaultNull()->info('The doctrine column annotation content')->example('type="decimal", precision=2, scale=1, options={"comment" = "my comment"}')->end() + ->scalarNode('ormColumn')->defaultNull()->info('The doctrine column annotation content')->example('type="decimal", precision=5, scale=1, options={"comment" = "my comment"}')->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') ->prototype('scalar')->end() From ed9df4b53fd4058cfa4636831074afdd078aa566 Mon Sep 17 00:00:00 2001 From: Kevin Eyermann Date: Thu, 28 Jan 2016 13:45:19 +0100 Subject: [PATCH 039/258] custom ormColumn test --- tests/config/address-book.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index f1d99983..7baaa805 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -18,7 +18,8 @@ types: additionalName: ~ gender: ~ address: { range: PostalAddress } - birthDate: ~ + # Custom range and custom ORM\Column content + birthDate: { range: DateTime, ormColumn: 'type="datetimetz", nullable=true, options={"comment" = "Birthdate with timezone."}' } telephone: ~ email: ~ jobTitle: ~ @@ -45,3 +46,5 @@ types: parent: false properties: name: ~ + # Custom property with custom ORM\Column content + adminCode: {range: Text, ormColumn: 'type="string", length=3, unique=true, nullable=false, options={"comment" = "A code for central administration."}' } From 7d517a51953bad8c80332d0b8897f36deb1042d7 Mon Sep 17 00:00:00 2001 From: meyerbaptiste Date: Thu, 3 Mar 2016 22:14:21 +0100 Subject: [PATCH 040/258] Add ability to specify the format of the RDFa URI --- src/Command/GenerateTypesCommand.php | 6 +++--- src/TypesGeneratorConfiguration.php | 11 ++++++++--- tests/config/ecommerce.yml | 4 +++- tests/config/vgo.yml | 7 +++++-- 4 files changed, 19 insertions(+), 9 deletions(-) diff --git a/src/Command/GenerateTypesCommand.php b/src/Command/GenerateTypesCommand.php index c3906c5d..62f8962d 100644 --- a/src/Command/GenerateTypesCommand.php +++ b/src/Command/GenerateTypesCommand.php @@ -66,10 +66,10 @@ protected function execute(InputInterface $input, OutputInterface $output) $graphs = []; foreach ($processedConfiguration['rdfa'] as $rdfa) { $graph = new \EasyRdf_Graph(); - if ('http://' === substr($rdfa, 0, 7) || 'https://' === substr($rdfa, 0, 8)) { - $graph->load($rdfa); + if ('http://' === substr($rdfa['uri'], 0, 7) || 'https://' === substr($rdfa['uri'], 0, 8)) { + $graph->load($rdfa['uri'], $rdfa['format']); } else { - $graph->parseFile($rdfa); + $graph->parseFile($rdfa['uri'], $rdfa['format']); } $graphs[] = $graph; diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index c3f3b69f..a917aeea 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -32,11 +32,16 @@ public function getConfigTreeBuilder() $rootNode ->children() ->arrayNode('rdfa') - ->info('RDFa files to use') + ->info('RDFa files') ->defaultValue([ - self::SCHEMA_ORG_RDFA_URL, + ['uri' => self::SCHEMA_ORG_RDFA_URL, 'format' => null], ]) - ->prototype('scalar')->end() + ->prototype('array') + ->children() + ->scalarNode('uri')->defaultValue(self::SCHEMA_ORG_RDFA_URL)->info('RDFa URI to use')->example(self::SCHEMA_ORG_RDFA_URL)->end() + ->scalarNode('format')->defaultNull()->info('RDFa URI data format')->example('rdfxml')->end() + ->end() + ->end() ->end() ->arrayNode('relations') ->info('OWL relation files to use') diff --git a/tests/config/ecommerce.yml b/tests/config/ecommerce.yml index 08d93ec4..14362ba8 100644 --- a/tests/config/ecommerce.yml +++ b/tests/config/ecommerce.yml @@ -8,7 +8,9 @@ header: | * file that was distributed with this source code. */ rdfa: - - tests/data/schema.rdfa + - + uri: tests/data/schema.rdfa + format: rdfa relations: - tests/data/v1.owl namespaces: diff --git a/tests/config/vgo.yml b/tests/config/vgo.yml index b98a79f5..50e04c6c 100644 --- a/tests/config/vgo.yml +++ b/tests/config/vgo.yml @@ -12,5 +12,8 @@ types: Thing: ~ debug: true rdfa: - - tests/data/vgo.rdf - - tests/data/schema.rdfa + - + uri: tests/data/vgo.rdf + format: ~ + - + uri: tests/data/schema.rdfa From ffc35129cadfb8691ee12e2a70ef233963494679 Mon Sep 17 00:00:00 2001 From: Andrew Meshchanchuk Date: Sun, 6 Mar 2016 11:32:14 +0300 Subject: [PATCH 041/258] Add MongoDB annotation generator --- .../DoctrineMongoDBAnnotationGenerator.php | 162 ++++++++++++++++++ 1 file changed, 162 insertions(+) create mode 100644 src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php diff --git a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php new file mode 100644 index 00000000..1bd14465 --- /dev/null +++ b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php @@ -0,0 +1,162 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\TypesGenerator; + +/** + * Doctrine MongoDB annotation generator. + * + * @author Andrew Meshchanchuk > + */ +class DoctrineMongoDBAnnotationGenerator extends AbstractAnnotationGenerator +{ + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + $class = $this->classes[$className]; + + if ($class['isEnum']) { + return []; + } + + if (isset($this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping'])) { + $inheritanceMapping = $this->config['types'][$class['resource']->localName()]['doctrine']['inheritanceMapping']; + } else { + $inheritanceMapping = $class['abstract'] ? '@MongoDB\MappedSuperclass' : '@MongoDB\Document'; + } + + return [ + '', + $inheritanceMapping, + ]; + } + + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + $this->classes[$className]; + $field = $this->classes[$className]['fields'][$fieldName]; + + $annotations = []; + + if ($field['isEnum']) { + if ($field['isArray']) { + $type = 'simple_array'; + } else { + $type = 'string'; + } + } else { + switch ($field['range']) { + case 'Boolean': + $type = 'boolean'; + break; + case 'Date': + // No break + case 'DateTime': + $type = 'date'; + break; + case 'Time': + $type = 'time'; + break; + case 'Number': + // No break + case 'Float': + $type = 'float'; + break; + case 'Integer': + $type = 'integer'; + break; + case 'Text': + // No break + case 'URL': + $type = 'string'; + break; + } + } + + if (isset($type)) { + if (!$field['isId']) { + $annotation = '@MongoDB\Field'; + + if ($field['isArray']) { + $type = 'collection'; + } + + $annotation .= sprintf('(type="%s")', $type); + + $annotations[] = $annotation; + } + } else { + switch ($field['cardinality']) { + case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_0_1 + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_1_1): + + $annotations[] = sprintf('@MongoDB\ReferenceOne(targetDocument="%s", simple=true))', $this->getRelationName($field['range'])); + break; + case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_UNKNOWN): + // No break + case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_0 + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_1): + + $annotations[] = sprintf('@MongoDB\ReferenceOne(targetDocument="%s", simple=true))', $this->getRelationName($field['range'])); + break; + case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_0_N + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_1_N + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_N): + + $annotations[] = sprintf('@MongoDB\ReferenceMany(targetDocument="%s", simple=true)', $this->getRelationName($field['range'])); + break; + } + } + + if ($field['isId']) { + $annotations[] = '@MongoDB\Id'; + } + + return $annotations; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + $resource = $this->classes[$className]['resource']; + + $subClassOf = $resource->get('rdfs:subClassOf'); + $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; + + return $typeIsEnum ? [] : ['Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB']; + } + + /** + * Gets class or interface name to use in relations. + * + * @param string $range + * + * @return string + */ + private function getRelationName($range) + { + $class = $this->classes[$range]; + + if (isset($class['interfaceName'])) { + return $class['interfaceName']; + } + + return $class['name']; + } +} From bd2e57d20ddf3bf02cdbb75580a1ba97c3e59006 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 5 Mar 2016 19:11:27 +0100 Subject: [PATCH 042/258] Support annotations of api-patform/core v2 --- .travis.yml | 5 +- composer.json | 3 + composer.lock | 215 +++++++++--------- phpunit.xml.dist | 24 ++ .../ApiPlatformCoreAnnotationGenerator.php | 53 +++++ ...ApiPlatformCoreAnnotationGeneratorTest.php | 66 ++++++ tests/bootstrap.php | 10 + tests/config/address-book.yml | 2 +- tests/run-tests.sh | 2 +- 9 files changed, 270 insertions(+), 110 deletions(-) create mode 100644 phpunit.xml.dist create mode 100644 src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php create mode 100644 tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php create mode 100644 tests/bootstrap.php diff --git a/.travis.yml b/.travis.yml index fd9c8da5..d259478f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,16 +7,14 @@ cache: - $HOME/.composer/cache php: - - 5.4 - 5.5 - 5.6 - 7.0 - - nightly - hhvm matrix: allow_failures: - - php: nightly + - php: hhvm fast_finish: true before_script: @@ -24,4 +22,5 @@ before_script: - composer install script: + - phpunit - tests/run-tests.sh diff --git a/composer.json b/composer.json index c5e398eb..6e6836f6 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,9 @@ "autoload": { "psr-4": { "ApiPlatform\\SchemaGenerator\\": "src/" } }, + "autoload-dev": { + "psr-4": { "ApiPlatform\\SchemaGenerator\\Tests\\": "tests/" } + }, "require": { "php": ">=5.4", "ext-json": "*", diff --git a/composer.lock b/composer.lock index 1f32fa19..e08010b9 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "hash": "d90df784ad2c70ce79dc716881144741", + "hash": "53c13f038d508087e8a20786c79593ee", "content-hash": "902da9fc5e839837f3fc831966648c32", "packages": [ { @@ -71,16 +71,16 @@ }, { "name": "fabpot/php-cs-fixer", - "version": "v1.11", + "version": "v1.11.2", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef" + "reference": "41f70154642ec0f9ea9ea9c290943f3b5dfa76fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef", - "reference": "bd3ec2c2b774e0e127ac2c737ec646d9cf2f9eef", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/41f70154642ec0f9ea9ea9c290943f3b5dfa76fc", + "reference": "41f70154642ec0f9ea9ea9c290943f3b5dfa76fc", "shasum": "" }, "require": { @@ -121,20 +121,20 @@ } ], "description": "A tool to automatically fix PHP code style", - "time": "2015-12-01 22:34:33" + "time": "2016-02-26 07:37:29" }, { "name": "league/html-to-markdown", - "version": "4.1.1", + "version": "4.2.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "01bbfe039d9b97526e3f3a3ee32543fc1d8dba00" + "reference": "9a5becc8c6b520920fb846afefcfd7faf4c31712" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/01bbfe039d9b97526e3f3a3ee32543fc1d8dba00", - "reference": "01bbfe039d9b97526e3f3a3ee32543fc1d8dba00", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/9a5becc8c6b520920fb846afefcfd7faf4c31712", + "reference": "9a5becc8c6b520920fb846afefcfd7faf4c31712", "shasum": "" }, "require": { @@ -153,7 +153,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.2-dev" + "dev-master": "4.3-dev" } }, "autoload": { @@ -185,7 +185,7 @@ "html", "markdown" ], - "time": "2015-11-20 16:20:25" + "time": "2016-02-01 16:49:02" }, { "name": "psr/log", @@ -279,22 +279,25 @@ }, { "name": "symfony/config", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290" + "reference": "79a97025f7bf4bbf8352b5df1905aa136a531066" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/40bae8658dbbb500ebc19aa9fde22dc4295fc290", - "reference": "40bae8658dbbb500ebc19aa9fde22dc4295fc290", + "url": "https://api.github.com/repos/symfony/config/zipball/79a97025f7bf4bbf8352b5df1905aa136a531066", + "reference": "79a97025f7bf4bbf8352b5df1905aa136a531066", "shasum": "" }, "require": { "php": ">=5.5.9", "symfony/filesystem": "~2.8|~3.0" }, + "suggest": { + "symfony/yaml": "To use the yaml reference dumper" + }, "type": "library", "extra": { "branch-alias": { @@ -325,20 +328,20 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com/", - "time": "2015-11-02 20:34:04" + "time": "2016-02-23 15:16:06" }, { "name": "symfony/console", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "175871ca8d1ef16ff8d8cac395a1c73afa8d0e63" + "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/175871ca8d1ef16ff8d8cac395a1c73afa8d0e63", - "reference": "175871ca8d1ef16ff8d8cac395a1c73afa8d0e63", + "url": "https://api.github.com/repos/symfony/console/zipball/2ed5e2706ce92313d120b8fe50d1063bcfd12e04", + "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04", "shasum": "" }, "require": { @@ -385,20 +388,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com/", - "time": "2015-11-30 12:36:17" + "time": "2016-02-28 16:24:34" }, { "name": "symfony/event-dispatcher", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf" + "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d36355e026905fa5229e1ed7b4e9eda2e67adfcf", - "reference": "d36355e026905fa5229e1ed7b4e9eda2e67adfcf", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", + "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", "shasum": "" }, "require": { @@ -445,20 +448,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com/", - "time": "2015-10-30 23:35:59" + "time": "2016-01-27 05:14:46" }, { "name": "symfony/filesystem", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884" + "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/692d98d813e4ef314b9c22775c86ddbeb0f44884", - "reference": "692d98d813e4ef314b9c22775c86ddbeb0f44884", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/23ae8f9648d0a7fe94a47c8e20e5bf37c489a451", + "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451", "shasum": "" }, "require": { @@ -494,20 +497,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com/", - "time": "2015-11-23 10:41:47" + "time": "2016-02-23 15:16:06" }, { "name": "symfony/finder", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "3577eb98dba90721d1a0a3edfc6956ab8b1aecee" + "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/3577eb98dba90721d1a0a3edfc6956ab8b1aecee", - "reference": "3577eb98dba90721d1a0a3edfc6956ab8b1aecee", + "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723", + "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723", "shasum": "" }, "require": { @@ -543,29 +546,32 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com/", - "time": "2015-10-30 23:35:59" + "time": "2016-01-27 05:14:46" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.0.0", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0b6a8940385311a24e060ec1fe35680e17c74497" + "reference": "1289d16209491b584839022f29257ad859b8532d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0b6a8940385311a24e060ec1fe35680e17c74497", - "reference": "0b6a8940385311a24e060ec1fe35680e17c74497", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", + "reference": "1289d16209491b584839022f29257ad859b8532d", "shasum": "" }, "require": { "php": ">=5.3.3" }, + "suggest": { + "ext-mbstring": "For best performance" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.1-dev" } }, "autoload": { @@ -599,20 +605,20 @@ "portable", "shim" ], - "time": "2015-11-04 20:28:58" + "time": "2016-01-20 09:13:37" }, { "name": "symfony/process", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "01383ed02a1020759bc8ee5d975fcec04ba16fbf" + "reference": "dfecef47506179db2501430e732adbf3793099c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/01383ed02a1020759bc8ee5d975fcec04ba16fbf", - "reference": "01383ed02a1020759bc8ee5d975fcec04ba16fbf", + "url": "https://api.github.com/repos/symfony/process/zipball/dfecef47506179db2501430e732adbf3793099c8", + "reference": "dfecef47506179db2501430e732adbf3793099c8", "shasum": "" }, "require": { @@ -648,20 +654,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com/", - "time": "2015-11-30 12:36:17" + "time": "2016-02-02 13:44:19" }, { "name": "symfony/stopwatch", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800" + "reference": "4a204804952ff267ace88cf499e0b4bb302a475e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/6aeac8907e3e1340a0033b0a9ec075f8e6524800", - "reference": "6aeac8907e3e1340a0033b0a9ec075f8e6524800", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4a204804952ff267ace88cf499e0b4bb302a475e", + "reference": "4a204804952ff267ace88cf499e0b4bb302a475e", "shasum": "" }, "require": { @@ -697,20 +703,20 @@ ], "description": "Symfony Stopwatch Component", "homepage": "https://symfony.com/", - "time": "2015-10-30 23:35:59" + "time": "2016-01-03 15:35:16" }, { "name": "symfony/yaml", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002" + "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", - "reference": "177a015cb0e19ff4a49e0e2e2c5fc1c1bee07002", + "url": "https://api.github.com/repos/symfony/yaml/zipball/b5ba64cd67ecd6887f63868fa781ca094bd1377c", + "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c", "shasum": "" }, "require": { @@ -746,20 +752,20 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com/", - "time": "2015-11-30 12:36:17" + "time": "2016-02-23 15:16:06" }, { "name": "twig/twig", - "version": "v1.23.1", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6" + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6", - "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", + "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", "shasum": "" }, "require": { @@ -772,7 +778,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.23-dev" + "dev-master": "1.24-dev" } }, "autoload": { @@ -807,7 +813,7 @@ "keywords": [ "templating" ], - "time": "2015-11-05 12:49:06" + "time": "2016-01-25 21:22:18" } ], "packages-dev": [ @@ -881,33 +887,33 @@ }, { "name": "doctrine/cache", - "version": "v1.5.2", + "version": "v1.6.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "47c7128262da274f590ae6f86eb137a7a64e82af" + "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/47c7128262da274f590ae6f86eb137a7a64e82af", - "reference": "47c7128262da274f590ae6f86eb137a7a64e82af", + "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6", + "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6", "shasum": "" }, "require": { - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "conflict": { "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "phpunit/phpunit": ">=3.7", + "phpunit/phpunit": "~4.8|~5.0", "predis/predis": "~1.0", "satooshi/php-coveralls": "~0.6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.5.x-dev" + "dev-master": "1.6.x-dev" } }, "autoload": { @@ -947,7 +953,7 @@ "cache", "caching" ], - "time": "2015-12-03 10:50:37" + "time": "2015-12-31 16:37:02" }, { "name": "doctrine/collections", @@ -1017,16 +1023,16 @@ }, { "name": "doctrine/common", - "version": "v2.5.2", + "version": "v2.6.1", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c" + "reference": "a579557bc689580c19fee4e27487a67fe60defc0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/311001fd9865a4d0d59efff4eac6d7dcb3f5270c", - "reference": "311001fd9865a4d0d59efff4eac6d7dcb3f5270c", + "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0", + "reference": "a579557bc689580c19fee4e27487a67fe60defc0", "shasum": "" }, "require": { @@ -1035,20 +1041,20 @@ "doctrine/collections": "1.*", "doctrine/inflector": "1.*", "doctrine/lexer": "1.*", - "php": ">=5.3.2" + "php": "~5.5|~7.0" }, "require-dev": { - "phpunit/phpunit": "~3.7" + "phpunit/phpunit": "~4.8|~5.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.5.x-dev" + "dev-master": "2.7.x-dev" } }, "autoload": { - "psr-0": { - "Doctrine\\Common\\": "lib/" + "psr-4": { + "Doctrine\\Common\\": "lib/Doctrine/Common" } }, "notification-url": "https://packagist.org/downloads/", @@ -1086,24 +1092,24 @@ "persistence", "spl" ], - "time": "2015-12-04 12:49:42" + "time": "2015-12-25 13:18:31" }, { "name": "doctrine/dbal", - "version": "v2.5.2", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c" + "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/01dbcbc5cd0a913d751418e635434a18a2f2a75c", - "reference": "01dbcbc5cd0a913d751418e635434a18a2f2a75c", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769", + "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769", "shasum": "" }, "require": { - "doctrine/common": ">=2.4,<2.6-dev", + "doctrine/common": ">=2.4,<2.7-dev", "php": ">=5.3.2" }, "require-dev": { @@ -1157,7 +1163,7 @@ "persistence", "queryobject" ], - "time": "2015-09-16 16:29:33" + "time": "2016-01-05 22:11:12" }, { "name": "doctrine/inflector", @@ -1336,22 +1342,22 @@ }, { "name": "doctrine/orm", - "version": "v2.5.2", + "version": "v2.5.4", "source": { "type": "git", "url": "https://github.com/doctrine/doctrine2.git", - "reference": "464b5fdbfbbeb4a65465ac173c4c5d90960f41ff" + "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/464b5fdbfbbeb4a65465ac173c4c5d90960f41ff", - "reference": "464b5fdbfbbeb4a65465ac173c4c5d90960f41ff", + "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/bc4ddbfb0114cb33438cc811c9a740d8aa304aab", + "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab", "shasum": "" }, "require": { "doctrine/cache": "~1.4", "doctrine/collections": "~1.2", - "doctrine/common": ">=2.5-dev,<2.6-dev", + "doctrine/common": ">=2.5-dev,<2.7-dev", "doctrine/dbal": ">=2.5-dev,<2.6-dev", "doctrine/instantiator": "~1.0.1", "ext-pdo": "*", @@ -1360,7 +1366,6 @@ }, "require-dev": { "phpunit/phpunit": "~4.0", - "satooshi/php-coveralls": "dev-master", "symfony/yaml": "~2.3|~3.0" }, "suggest": { @@ -1409,20 +1414,20 @@ "database", "orm" ], - "time": "2015-11-23 12:44:25" + "time": "2016-01-05 21:34:58" }, { "name": "symfony/translation", - "version": "v3.0.0", + "version": "v3.0.3", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "7f14717150a7445f8475864d1235875dd04061fb" + "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/7f14717150a7445f8475864d1235875dd04061fb", - "reference": "7f14717150a7445f8475864d1235875dd04061fb", + "url": "https://api.github.com/repos/symfony/translation/zipball/2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91", + "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91", "shasum": "" }, "require": { @@ -1473,20 +1478,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com/", - "time": "2015-11-18 13:48:51" + "time": "2016-02-02 13:44:19" }, { "name": "symfony/validator", - "version": "v2.8.0", + "version": "v2.8.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "8c42b96f5b23f0642c1a518addafcef8077154a2" + "reference": "3a529b9a428812c5ccb5e462c936e36f5492d716" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/8c42b96f5b23f0642c1a518addafcef8077154a2", - "reference": "8c42b96f5b23f0642c1a518addafcef8077154a2", + "url": "https://api.github.com/repos/symfony/validator/zipball/3a529b9a428812c5ccb5e462c936e36f5492d716", + "reference": "3a529b9a428812c5ccb5e462c936e36f5492d716", "shasum": "" }, "require": { @@ -1545,7 +1550,7 @@ ], "description": "Symfony Validator Component", "homepage": "https://symfony.com/", - "time": "2015-11-20 14:39:26" + "time": "2016-02-23 18:27:29" } ], "aliases": [], diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..571924a2 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,24 @@ + + + + + + + tests + + + + + + . + + tests + vendor + + + + diff --git a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php new file mode 100644 index 00000000..c6986a91 --- /dev/null +++ b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php @@ -0,0 +1,53 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; + +use ApiPlatform\SchemaGenerator\TypesGenerator; + +/** + * Generates API Platform core annotations. + * + * @author Kévin Dunglas + * + * @link https://github.com/api-platform/core + */ +class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerator +{ + /** + * {@inheritdoc} + */ + public function generateClassAnnotations($className) + { + $resource = $this->classes[$className]['resource']; + + return [sprintf('@Resource(iri="%s")', $resource->getUri())]; + } + + /** + * {@inheritdoc} + */ + public function generateFieldAnnotations($className, $fieldName) + { + return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Property(iri="http://schema.org/%s")', $fieldName)]; + } + + /** + * {@inheritdoc} + */ + public function generateUses($className) + { + $resource = $this->classes[$className]['resource']; + + $subClassOf = $resource->get('rdfs:subClassOf'); + $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; + + return $typeIsEnum ? [] : ['ApiPlatform\Core\Annotation\Resource', 'ApiPlatform\Core\Annotation\Property']; + } +} diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php new file mode 100644 index 00000000..366ee85f --- /dev/null +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -0,0 +1,66 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +namespace ApiPlatform\SchemaGenerator\Tests; + +use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; +use ApiPlatform\SchemaGenerator\TypesGenerator; +use Psr\Log\NullLogger; + +/** + * @author Kévin Dunglas + */ +class ApiPlatformCoreAnnotationGeneratorTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var ApiPlatformCoreAnnotationGenerator + */ + private $generator; + + public function setUp() + { + $graph = new \EasyRdf_Graph(); + $myEnum = new \EasyRdf_Resource('http://schema.org/MyEnum', $graph); + $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); + + $this->generator = new ApiPlatformCoreAnnotationGenerator( + new NullLogger(), + [], + [], + [], + [ + 'Res' => [ + 'resource' => new \EasyRdf_Resource('http://schema.org/Res', $graph), + 'fields' => [ + 'prop' => ['isCustom' => false], + 'customProp' => ['isCustom' => true], + ], + ], + 'MyEnum' => ['resource' => $myEnum], + ] + ); + } + + public function testGenerateClassAnnotations() + { + $this->assertSame(['@Resource(iri="http://schema.org/Res")'], $this->generator->generateClassAnnotations('Res')); + } + + public function testGenerateFieldAnnotations() + { + $this->assertSame(['@Property(iri="http://schema.org/prop")'], $this->generator->generateFieldAnnotations('Res', 'prop')); + $this->assertSame([], $this->generator->generateFieldAnnotations('Res', 'customProp')); + } + + public function testGenerateUses() + { + $this->assertSame(['ApiPlatform\Core\Annotation\Resource', 'ApiPlatform\Core\Annotation\Property'], $this->generator->generateUses('Res')); + $this->assertSame([], $this->generator->generateUses('MyEnum')); + } +} diff --git a/tests/bootstrap.php b/tests/bootstrap.php new file mode 100644 index 00000000..207b855c --- /dev/null +++ b/tests/bootstrap.php @@ -0,0 +1,10 @@ + + * + * This source file is subject to the MIT license that is bundled + * with this source code in the file LICENSE. + */ + +return require __DIR__.'/../vendor/autoload.php'; diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index f1d99983..da1e550a 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -6,7 +6,7 @@ annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator # The list of types and properties we want to use types: Person: diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 79563ed0..cbe6e014 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash -e # Test commands bin/schema dump-configuration From 29d95eb23198879251bc5198f42b2417f1b9465c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 6 Mar 2016 17:12:18 +0100 Subject: [PATCH 043/258] Quality fixes --- .gitignore | 8 +- .travis.yml | 8 +- composer.lock | 1566 ----------------- .../AbstractAnnotationGenerator.php | 2 +- .../ConstraintAnnotationGenerator.php | 2 +- src/CardinalitiesExtractor.php | 2 +- src/GoodRelationsBridge.php | 10 +- src/TypesGenerator.php | 32 +- 8 files changed, 32 insertions(+), 1598 deletions(-) delete mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 452993de..8f8675e0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,4 @@ -composer.phar -vendor -build/ -.couscous +/composer.phar +/composer.lock +/vendor +/build diff --git a/.travis.yml b/.travis.yml index d259478f..df9d9d0c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -7,19 +7,15 @@ cache: - $HOME/.composer/cache php: + - 5.4 - 5.5 - 5.6 - 7.0 - hhvm -matrix: - allow_failures: - - php: hhvm - fast_finish: true - before_script: - composer self-update - - composer install + - composer update script: - phpunit diff --git a/composer.lock b/composer.lock deleted file mode 100644 index e08010b9..00000000 --- a/composer.lock +++ /dev/null @@ -1,1566 +0,0 @@ -{ - "_readme": [ - "This file locks the dependencies of your project to a known state", - "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", - "This file is @generated automatically" - ], - "hash": "53c13f038d508087e8a20786c79593ee", - "content-hash": "902da9fc5e839837f3fc831966648c32", - "packages": [ - { - "name": "easyrdf/easyrdf", - "version": "0.9.1", - "source": { - "type": "git", - "url": "https://github.com/njh/easyrdf.git", - "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/njh/easyrdf/zipball/acd09dfe0555fbcfa254291e433c45fdd4652566", - "reference": "acd09dfe0555fbcfa254291e433c45fdd4652566", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "ext-pcre": "*", - "php": ">=5.2.8" - }, - "require-dev": { - "phpunit/phpunit": "~3.5", - "sami/sami": "~1.4", - "squizlabs/php_codesniffer": "~1.4.3" - }, - "suggest": { - "ml/json-ld": "~1.0" - }, - "type": "library", - "autoload": { - "psr-0": { - "EasyRdf_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nicholas Humfrey", - "email": "njh@aelius.com", - "homepage": "http://www.aelius.com/njh/", - "role": "Developer" - }, - { - "name": "Alexey Zakhlestin", - "email": "indeyets@gmail.com", - "role": "Developer" - } - ], - "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", - "homepage": "http://www.easyrdf.org/", - "keywords": [ - "Linked Data", - "RDF", - "Semantic Web", - "Turtle", - "rdfa", - "sparql" - ], - "time": "2015-02-27 09:45:49" - }, - { - "name": "fabpot/php-cs-fixer", - "version": "v1.11.2", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "41f70154642ec0f9ea9ea9c290943f3b5dfa76fc" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/41f70154642ec0f9ea9ea9c290943f3b5dfa76fc", - "reference": "41f70154642ec0f9ea9ea9c290943f3b5dfa76fc", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=5.3.6", - "sebastian/diff": "~1.1", - "symfony/console": "~2.3|~3.0", - "symfony/event-dispatcher": "~2.1|~3.0", - "symfony/filesystem": "~2.1|~3.0", - "symfony/finder": "~2.1|~3.0", - "symfony/process": "~2.3|~3.0", - "symfony/stopwatch": "~2.5|~3.0" - }, - "require-dev": { - "satooshi/php-coveralls": "0.7.*@dev" - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "autoload": { - "psr-4": { - "Symfony\\CS\\": "Symfony/CS/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - }, - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "time": "2016-02-26 07:37:29" - }, - { - "name": "league/html-to-markdown", - "version": "4.2.0", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "9a5becc8c6b520920fb846afefcfd7faf4c31712" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/9a5becc8c6b520920fb846afefcfd7faf4c31712", - "reference": "9a5becc8c6b520920fb846afefcfd7faf4c31712", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-xml": "*", - "php": ">=5.3.3" - }, - "require-dev": { - "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "4.*", - "scrutinizer/ocular": "~1.1" - }, - "bin": [ - "bin/html-to-markdown" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.3-dev" - } - }, - "autoload": { - "psr-4": { - "League\\HTMLToMarkdown\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Colin O'Dell", - "email": "colinodell@gmail.com", - "homepage": "http://www.colinodell.com/", - "role": "Lead Developer" - }, - { - "name": "Nick Cernis", - "email": "nick@cern.is", - "homepage": "http://modernnerd.net/", - "role": "Original Author" - } - ], - "description": "An HTML-to-markdown conversion helper for PHP", - "homepage": "https://github.com/thephpleague/html-to-markdown", - "keywords": [ - "html", - "markdown" - ], - "time": "2016-02-01 16:49:02" - }, - { - "name": "psr/log", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe0936ee26643249e916849d48e3a51d5f5e278b", - "reference": "fe0936ee26643249e916849d48e3a51d5f5e278b", - "shasum": "" - }, - "type": "library", - "autoload": { - "psr-0": { - "Psr\\Log\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for logging libraries", - "keywords": [ - "log", - "psr", - "psr-3" - ], - "time": "2012-12-21 11:40:51" - }, - { - "name": "sebastian/diff", - "version": "1.4.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "require-dev": { - "phpunit/phpunit": "~4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff" - ], - "time": "2015-12-08 07:14:41" - }, - { - "name": "symfony/config", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/config.git", - "reference": "79a97025f7bf4bbf8352b5df1905aa136a531066" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/79a97025f7bf4bbf8352b5df1905aa136a531066", - "reference": "79a97025f7bf4bbf8352b5df1905aa136a531066", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/filesystem": "~2.8|~3.0" - }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Config\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Config Component", - "homepage": "https://symfony.com/", - "time": "2016-02-23 15:16:06" - }, - { - "name": "symfony/console", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/2ed5e2706ce92313d120b8fe50d1063bcfd12e04", - "reference": "2ed5e2706ce92313d120b8fe50d1063bcfd12e04", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/event-dispatcher": "~2.8|~3.0", - "symfony/process": "~2.8|~3.0" - }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/process": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Console Component", - "homepage": "https://symfony.com/", - "time": "2016-02-28 16:24:34" - }, - { - "name": "symfony/event-dispatcher", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", - "reference": "4dd5df31a28c0f82b41cb1e1599b74b5dcdbdafa", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0", - "symfony/dependency-injection": "~2.8|~3.0", - "symfony/expression-language": "~2.8|~3.0", - "symfony/stopwatch": "~2.8|~3.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony EventDispatcher Component", - "homepage": "https://symfony.com/", - "time": "2016-01-27 05:14:46" - }, - { - "name": "symfony/filesystem", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/filesystem.git", - "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/23ae8f9648d0a7fe94a47c8e20e5bf37c489a451", - "reference": "23ae8f9648d0a7fe94a47c8e20e5bf37c489a451", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Filesystem\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Filesystem Component", - "homepage": "https://symfony.com/", - "time": "2016-02-23 15:16:06" - }, - { - "name": "symfony/finder", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/623bda0abd9aa29e529c8e9c08b3b84171914723", - "reference": "623bda0abd9aa29e529c8e9c08b3b84171914723", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Finder Component", - "homepage": "https://symfony.com/", - "time": "2016-01-27 05:14:46" - }, - { - "name": "symfony/polyfill-mbstring", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "1289d16209491b584839022f29257ad859b8532d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/1289d16209491b584839022f29257ad859b8532d", - "reference": "1289d16209491b584839022f29257ad859b8532d", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-mbstring": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for the Mbstring extension", - "homepage": "https://symfony.com/", - "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" - ], - "time": "2016-01-20 09:13:37" - }, - { - "name": "symfony/process", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "dfecef47506179db2501430e732adbf3793099c8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/dfecef47506179db2501430e732adbf3793099c8", - "reference": "dfecef47506179db2501430e732adbf3793099c8", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Process Component", - "homepage": "https://symfony.com/", - "time": "2016-02-02 13:44:19" - }, - { - "name": "symfony/stopwatch", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "4a204804952ff267ace88cf499e0b4bb302a475e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/4a204804952ff267ace88cf499e0b4bb302a475e", - "reference": "4a204804952ff267ace88cf499e0b4bb302a475e", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Stopwatch Component", - "homepage": "https://symfony.com/", - "time": "2016-01-03 15:35:16" - }, - { - "name": "symfony/yaml", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/yaml.git", - "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/b5ba64cd67ecd6887f63868fa781ca094bd1377c", - "reference": "b5ba64cd67ecd6887f63868fa781ca094bd1377c", - "shasum": "" - }, - "require": { - "php": ">=5.5.9" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Yaml\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Yaml Component", - "homepage": "https://symfony.com/", - "time": "2016-02-23 15:16:06" - }, - { - "name": "twig/twig", - "version": "v1.24.0", - "source": { - "type": "git", - "url": "https://github.com/twigphp/Twig.git", - "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", - "reference": "3e5aa30ebfbafd5951fb1b01e338e1800ce7e0e8", - "shasum": "" - }, - "require": { - "php": ">=5.2.7" - }, - "require-dev": { - "symfony/debug": "~2.7", - "symfony/phpunit-bridge": "~2.7" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.24-dev" - } - }, - "autoload": { - "psr-0": { - "Twig_": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com", - "homepage": "http://fabien.potencier.org/", - "role": "Lead Developer" - }, - { - "name": "Armin Ronacher", - "email": "armin.ronacher@active-4.com", - "role": "Project Founder" - }, - { - "name": "Twig Team", - "homepage": "http://twig.sensiolabs.org/contributors", - "role": "Contributors" - } - ], - "description": "Twig, the flexible, fast, and secure template language for PHP", - "homepage": "http://twig.sensiolabs.org/", - "keywords": [ - "templating" - ], - "time": "2016-01-25 21:22:18" - } - ], - "packages-dev": [ - { - "name": "doctrine/annotations", - "version": "v1.2.7", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/f25c8aab83e0c3e976fd7d19875f198ccf2f7535", - "reference": "f25c8aab83e0c3e976fd7d19875f198ccf2f7535", - "shasum": "" - }, - "require": { - "doctrine/lexer": "1.*", - "php": ">=5.3.2" - }, - "require-dev": { - "doctrine/cache": "1.*", - "phpunit/phpunit": "4.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.3.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Annotations\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2015-08-31 12:32:49" - }, - { - "name": "doctrine/cache", - "version": "v1.6.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/f8af318d14bdb0eff0336795b428b547bd39ccb6", - "reference": "f8af318d14bdb0eff0336795b428b547bd39ccb6", - "shasum": "" - }, - "require": { - "php": "~5.5|~7.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "phpunit/phpunit": "~4.8|~5.0", - "predis/predis": "~1.0", - "satooshi/php-coveralls": "~0.6" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Caching library offering an object-oriented API for many cache backends", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "cache", - "caching" - ], - "time": "2015-12-31 16:37:02" - }, - { - "name": "doctrine/collections", - "version": "v1.3.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/collections.git", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/6c1e4eef75f310ea1b3e30945e9f06e652128b8a", - "reference": "6c1e4eef75f310ea1b3e30945e9f06e652128b8a", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "~4.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Collections\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Collections Abstraction library", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "array", - "collections", - "iterator" - ], - "time": "2015-04-14 22:21:58" - }, - { - "name": "doctrine/common", - "version": "v2.6.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "a579557bc689580c19fee4e27487a67fe60defc0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/a579557bc689580c19fee4e27487a67fe60defc0", - "reference": "a579557bc689580c19fee4e27487a67fe60defc0", - "shasum": "" - }, - "require": { - "doctrine/annotations": "1.*", - "doctrine/cache": "1.*", - "doctrine/collections": "1.*", - "doctrine/inflector": "1.*", - "doctrine/lexer": "1.*", - "php": "~5.5|~7.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.8|~5.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Common Library for Doctrine projects", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "annotations", - "collections", - "eventmanager", - "persistence", - "spl" - ], - "time": "2015-12-25 13:18:31" - }, - { - "name": "doctrine/dbal", - "version": "v2.5.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/dbal.git", - "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/abbdfd1cff43a7b99d027af3be709bc8fc7d4769", - "reference": "abbdfd1cff43a7b99d027af3be709bc8fc7d4769", - "shasum": "" - }, - "require": { - "doctrine/common": ">=2.4,<2.7-dev", - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "4.*", - "symfony/console": "2.*" - }, - "suggest": { - "symfony/console": "For helpful console commands such as SQL execution and import of files." - }, - "bin": [ - "bin/doctrine-dbal" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.5.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\DBAL\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - } - ], - "description": "Database Abstraction Layer", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "database", - "dbal", - "persistence", - "queryobject" - ], - "time": "2016-01-05 22:11:12" - }, - { - "name": "doctrine/inflector", - "version": "v1.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/inflector.git", - "reference": "90b2128806bfde671b6952ab8bea493942c1fdae" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/90b2128806bfde671b6952ab8bea493942c1fdae", - "reference": "90b2128806bfde671b6952ab8bea493942c1fdae", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "require-dev": { - "phpunit/phpunit": "4.*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.1.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Inflector\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Common String Manipulations with regard to casing and singular/plural rules.", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "inflection", - "pluralize", - "singularize", - "string" - ], - "time": "2015-11-06 14:35:42" - }, - { - "name": "doctrine/instantiator", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", - "shasum": "" - }, - "require": { - "php": ">=5.3,<8.0-DEV" - }, - "require-dev": { - "athletic/athletic": "~0.1.8", - "ext-pdo": "*", - "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://github.com/doctrine/instantiator", - "keywords": [ - "constructor", - "instantiate" - ], - "time": "2015-06-14 21:17:01" - }, - { - "name": "doctrine/lexer", - "version": "v1.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c", - "reference": "83893c552fd2045dd78aef794c31e694c37c0b8c", - "shasum": "" - }, - "require": { - "php": ">=5.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\Common\\Lexer\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "lexer", - "parser" - ], - "time": "2014-09-09 13:34:57" - }, - { - "name": "doctrine/orm", - "version": "v2.5.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/doctrine2.git", - "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/doctrine2/zipball/bc4ddbfb0114cb33438cc811c9a740d8aa304aab", - "reference": "bc4ddbfb0114cb33438cc811c9a740d8aa304aab", - "shasum": "" - }, - "require": { - "doctrine/cache": "~1.4", - "doctrine/collections": "~1.2", - "doctrine/common": ">=2.5-dev,<2.7-dev", - "doctrine/dbal": ">=2.5-dev,<2.6-dev", - "doctrine/instantiator": "~1.0.1", - "ext-pdo": "*", - "php": ">=5.4", - "symfony/console": "~2.5|~3.0" - }, - "require-dev": { - "phpunit/phpunit": "~4.0", - "symfony/yaml": "~2.3|~3.0" - }, - "suggest": { - "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" - }, - "bin": [ - "bin/doctrine", - "bin/doctrine.php" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.6.x-dev" - } - }, - "autoload": { - "psr-0": { - "Doctrine\\ORM\\": "lib/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - } - ], - "description": "Object-Relational-Mapper for PHP", - "homepage": "http://www.doctrine-project.org/", - "keywords": [ - "database", - "orm" - ], - "time": "2016-01-05 21:34:58" - }, - { - "name": "symfony/translation", - "version": "v3.0.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/translation.git", - "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91", - "reference": "2de0b6f7ebe43cffd8a06996ebec6aab79ea9e91", - "shasum": "" - }, - "require": { - "php": ">=5.5.9", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/config": "<2.8" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0", - "symfony/intl": "~2.8|~3.0", - "symfony/yaml": "~2.8|~3.0" - }, - "suggest": { - "psr/log": "To use logging capability in translator", - "symfony/config": "", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Translation\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Translation Component", - "homepage": "https://symfony.com/", - "time": "2016-02-02 13:44:19" - }, - { - "name": "symfony/validator", - "version": "v2.8.3", - "source": { - "type": "git", - "url": "https://github.com/symfony/validator.git", - "reference": "3a529b9a428812c5ccb5e462c936e36f5492d716" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/3a529b9a428812c5ccb5e462c936e36f5492d716", - "reference": "3a529b9a428812c5ccb5e462c936e36f5492d716", - "shasum": "" - }, - "require": { - "php": ">=5.3.9", - "symfony/translation": "~2.4|~3.0.0" - }, - "require-dev": { - "doctrine/annotations": "~1.0", - "doctrine/cache": "~1.0", - "egulias/email-validator": "~1.2,>=1.2.1", - "symfony/config": "~2.2|~3.0.0", - "symfony/expression-language": "~2.4|~3.0.0", - "symfony/http-foundation": "~2.1|~3.0.0", - "symfony/intl": "~2.4|~3.0.0", - "symfony/property-access": "~2.3|~3.0.0", - "symfony/yaml": "~2.0,>=2.0.5|~3.0.0" - }, - "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", - "egulias/email-validator": "Strict (RFC compliant) email validation", - "symfony/config": "", - "symfony/expression-language": "For using the 2.4 Expression validator", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/property-access": "For using the 2.4 Validator API", - "symfony/yaml": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.8-dev" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Component\\Validator\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony Validator Component", - "homepage": "https://symfony.com/", - "time": "2016-02-23 18:27:29" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.4", - "ext-json": "*" - }, - "platform-dev": [] -} diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php index 81b6bcf3..8c2469eb 100644 --- a/src/AnnotationGenerator/AbstractAnnotationGenerator.php +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -175,7 +175,7 @@ protected function toPhpType(array $field, $adderOrRemover = false) break; } - if ($data) { + if (false !== $data) { if ($field['isArray']) { return sprintf('%s[]', $data); } diff --git a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php index 6db64472..2de0d615 100644 --- a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php +++ b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php @@ -51,7 +51,7 @@ public function generateFieldAnnotations($className, $fieldName) $asserts[] = '@Assert\Email'; } - if (!$asserts) { + if (empty($asserts)) { $phpType = $this->toPhpType($field); if (in_array($phpType, ['boolean', 'float', 'integer', 'string'])) { $asserts[] = sprintf('@Assert\Type(type="%s")', $phpType); diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index 2b064b44..49ab0f68 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -75,7 +75,7 @@ private function extractForProperty(\EasyRdf_Resource $property) { $localName = $property->localName(); $fromGoodRelations = $this->goodRelationsBridge->extractCardinality($localName); - if ($fromGoodRelations) { + if (false !== $fromGoodRelations) { return $fromGoodRelations; } diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index f71e8c53..b93c62ff 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -90,7 +90,7 @@ public function __construct(array $relations) public function exist($id) { foreach ($this->relations as $relation) { - $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]', static::getPropertyUrl($id))); + $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]', $this->getPropertyUrl($id))); if (!empty($result)) { return true; } @@ -109,7 +109,7 @@ public function exist($id) public function extractCardinality($id) { foreach ($this->relations as $relation) { - $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', static::getPropertyUrl($id))); + $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', $this->getPropertyUrl($id))); if (count($result)) { preg_match('/\(.\.\..\)/', $result[0]->asXML(), $matches); @@ -127,7 +127,7 @@ public function extractCardinality($id) * * @return string */ - private static function convertPropertyId($id) + private function convertPropertyId($id) { if (isset(static::$datatypePropertiesTable[$id])) { return static::$datatypePropertiesTable[$id]; @@ -147,8 +147,8 @@ private static function convertPropertyId($id) * * @return string */ - private static function getPropertyUrl($id) + private function getPropertyUrl($id) { - return sprintf('%s%s', static::GOOD_RELATIONS_NAMESPACE, static::convertPropertyId($id)); + return self::GOOD_RELATIONS_NAMESPACE.$this->convertPropertyId($id); } } diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 5a4aa012..940e23e9 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -61,22 +61,27 @@ class TypesGenerator * @var \Twig_Environment */ private $twig; + /** * @var LoggerInterface */ private $logger; + /** * @var \EasyRdf_Graph[] */ private $graphs; + /** * @var CardinalitiesExtractor */ private $cardinalitiesExtractor; + /** * @var GoodRelationsBridge */ private $goodRelationsBridge; + /** * @var array */ @@ -89,13 +94,12 @@ class TypesGenerator * @param CardinalitiesExtractor $cardinalitiesExtractor * @param GoodRelationsBridge $goodRelationsBridge */ - public function __construct( - \Twig_Environment $twig, - LoggerInterface $logger, - array $graphs, - CardinalitiesExtractor $cardinalitiesExtractor, - GoodRelationsBridge $goodRelationsBridge - ) { + public function __construct(\Twig_Environment $twig, LoggerInterface $logger, array $graphs, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge) + { + if (empty($graphs)) { + throw new \InvalidArgumentException('At least one graph must be injected.'); + } + $this->twig = $twig; $this->logger = $logger; $this->graphs = $graphs; @@ -156,8 +160,10 @@ public function generate($config) $typeConfig = isset($config['types'][$typeName]) ? $config['types'][$typeName] : null; $class = $baseClass; + $comment = $type->get('rdfs:comment'); + $class['name'] = $typeName; - $class['label'] = $type->get('rdfs:comment')->getValue(); + $class['label'] = $comment ? $comment->getValue() : ''; $class['resource'] = $type; $class['config'] = $typeConfig; @@ -280,11 +286,9 @@ public function generate($config) $annotationGenerators[] = $generator; } - if (isset($class['interfaceNamespace']) && $config['doctrine']['resolveTargetEntityConfigPath']) { - $interfaceMappings = []; - } - + $interfaceMappings = []; $generatedFiles = []; + foreach ($classes as $className => &$class) { $class['uses'] = $this->generateClassUses($annotationGenerators, $classes, $className); $class['annotations'] = $this->generateClassAnnotations($annotationGenerators, $className); @@ -360,7 +364,7 @@ public function generate($config) } } - if (isset($interfaceMappings) && $config['doctrine']['resolveTargetEntityConfigPath']) { + if (!empty($interfaceMappings) && $config['doctrine']['resolveTargetEntityConfigPath']) { $file = $config['output'].'/'.$config['doctrine']['resolveTargetEntityConfigPath']; $dir = dirname($file); if (!file_exists($dir)) { @@ -408,7 +412,7 @@ private function getParentClasses(\EasyRdf_Resource $resource, array $parentClas $subclasses = $resource->all('rdfs:subClassOf'); - if (!$subclasses) { + if (empty($subclasses)) { return $parentClasses; } From 5893927aa9076fd78938921d4c6d9a5b0d3069ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 6 Mar 2016 17:29:22 +0100 Subject: [PATCH 044/258] Update Travis badge --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index f077225f..c9a2460a 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ # API Platform Model Generator -This Schema.org based model generator is part of [the API Platform framework](http://api-platform.com) that instantly generates a PHP data model from the [Schema.org](http://schema.org) +This Schema.org based model generator is part of [the API Platform framework](https://api-platform.com) that instantly generates a PHP data model from the [Schema.org](https://schema.org) vocabulary. Browse Schema.org, choose the types and properties you need, run our code generator and you're done! You get a fully featured PHP data model including: * A set of PHP entities with properties, constants (enum values), getters, setters, adders and removers. The class @@ -11,7 +11,7 @@ code complies with [PSR](http://www.php-fig.org/) coding standards. inheritance (through the `@AbstractSuperclass` annotation). * Data validation through [Symfony Validator](https://symfony.com/doc/current/book/validation.html) annotations including data type validation, enum support (choices) and check for required properties. -* Interfaces and [Doctrine `ResolveTargetEntityListener`](http://doctrine-orm.readthedocs.org/en/latest/cookbook/resolve-target-entity-listener.html) +* Interfaces and [Doctrine `ResolveTargetEntityListener`](https://doctrine-orm.readthedocs.org/en/latest/cookbook/resolve-target-entity-listener.html) support. * Custom PHP namespace support. * List of values provided by Schema.org with [PHP Enum](https://github.com/myclabs/php-enum) classes. @@ -21,14 +21,14 @@ Bonus: * The code generator is fully configurable and extensible: all features can be deactivated (e.g.: the Doctrine mapping generator) and custom generator can be added (e.g.: a Doctrine ODM mapping generator). * The generated code can be used as is in a [Symfony](http://symfony.com) app (but it will work too in a raw PHP project -or any other framework including [Laravel](http://laravel.com) and [Zend Framework](http://framework.zend.com/)). +or any other framework including [Laravel](https://laravel.com) and [Zend Framework](http://framework.zend.com/)). -[![Build Status](https://travis-ci.org/dunglas/php-schema.svg?branch=master)](https://travis-ci.org/dunglas/php-schema) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5/mini.png)](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5) +[![Build Status](https://travis-ci.org/api-platform/schema-generator.svg?branch=master)](https://travis-ci.org/api-platform/schema-generator) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5/mini.png)](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5) ## What is Schema.org? -Schema.org is a vocabulary representing common data structures and their relations. Schema.org can be exposed as [JSON-LD](http://en.wikipedia.org/wiki/JSON-LD), -[microdata](http://en.wikipedia.org/wiki/Microdata_(HTML)) and [RDFa](https://en.wikipedia.org/wiki/RDFa). +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). 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. From bbb89f1c8806916a599fd89af997fa146e546d44 Mon Sep 17 00:00:00 2001 From: Andrew Meshchanchuk Date: Mon, 7 Mar 2016 07:50:35 +0300 Subject: [PATCH 045/258] Change license --- src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php index 1bd14465..27b409f3 100644 --- a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php @@ -1,7 +1,7 @@ + * (c) Kévin Dunglas * * This source file is subject to the MIT license that is bundled * with this source code in the file LICENSE. From ab25b1c5fd57e00dc2ac550e2872bb99aa70c8de Mon Sep 17 00:00:00 2001 From: Andrew Meshchanchuk Date: Mon, 7 Mar 2016 09:14:46 +0300 Subject: [PATCH 046/258] Refactoring code style --- .../DoctrineMongoDBAnnotationGenerator.php | 28 ++++++------------- 1 file changed, 9 insertions(+), 19 deletions(-) diff --git a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php index 27b409f3..9a4a65e7 100644 --- a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php @@ -100,25 +100,15 @@ public function generateFieldAnnotations($className, $fieldName) $annotations[] = $annotation; } } else { - switch ($field['cardinality']) { - case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_0_1 - || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_1_1): - - $annotations[] = sprintf('@MongoDB\ReferenceOne(targetDocument="%s", simple=true))', $this->getRelationName($field['range'])); - break; - case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_UNKNOWN): - // No break - case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_0 - || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_1): - - $annotations[] = sprintf('@MongoDB\ReferenceOne(targetDocument="%s", simple=true))', $this->getRelationName($field['range'])); - break; - case ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_0_N - || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_1_N - || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_N): - - $annotations[] = sprintf('@MongoDB\ReferenceMany(targetDocument="%s", simple=true)', $this->getRelationName($field['range'])); - break; + if ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_0_1 + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_1_1 + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_0 + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_1) { + $annotations[] = sprintf('@MongoDB\ReferenceOne(targetDocument="%s", simple=true))', $this->getRelationName($field['range'])); + } elseif ($field['cardinality'] === CardinalitiesExtractor::CARDINALITY_0_N + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_1_N + || $field['cardinality'] === CardinalitiesExtractor::CARDINALITY_N_N) { + $annotations[] = sprintf('@MongoDB\ReferenceMany(targetDocument="%s", simple=true)', $this->getRelationName($field['range'])); } } From 6de776b500eacd5e8f1beac0cd71254d03988cad Mon Sep 17 00:00:00 2001 From: Andrew Meshchanchuk Date: Mon, 7 Mar 2016 09:15:44 +0300 Subject: [PATCH 047/258] Create tests for MongoDB annotation generator --- tests/config/mongodb/address-book.yml | 47 ++++++++++++++ tests/config/mongodb/ecommerce.yml | 94 +++++++++++++++++++++++++++ tests/run-tests.sh | 4 ++ 3 files changed, 145 insertions(+) create mode 100644 tests/config/mongodb/address-book.yml create mode 100644 tests/config/mongodb/ecommerce.yml diff --git a/tests/config/mongodb/address-book.yml b/tests/config/mongodb/address-book.yml new file mode 100644 index 00000000..1ad65aca --- /dev/null +++ b/tests/config/mongodb/address-book.yml @@ -0,0 +1,47 @@ +# The PHP namespace of generated entities +namespaces: + entity: 'AddressBook\Document' +# Enable DunglasApiAnnotationGenerator +annotationGenerators: + - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineMongoDBAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator +# The list of types and properties we want to use +types: + Person: + parent: false + properties: + name: ~ + familyName: ~ + givenName: ~ + additionalName: ~ + gender: ~ + address: { range: PostalAddress } + birthDate: ~ + telephone: ~ + email: ~ + jobTitle: ~ + # Default relation table name would be "person_organization" for all following fields, but we customize them + affiliation: ~ + brand: { relationTableName: "person_brand"} + memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} + worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} + # url field is a custom one without definition, it should render error + url: ~ + friends: { range: "Person", cardinality: (0..*) } + 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" } + addressLocality: ~ + addressRegion: ~ + postOfficeBoxNumber: ~ + postalCode: ~ + streetAddress: ~ + Organization: + parent: false + properties: + name: ~ diff --git a/tests/config/mongodb/ecommerce.yml b/tests/config/mongodb/ecommerce.yml new file mode 100644 index 00000000..080d6567 --- /dev/null +++ b/tests/config/mongodb/ecommerce.yml @@ -0,0 +1,94 @@ +header: | + /* + * This file is part of the Ecommerce package. + * + * (c) Kévin Dunglas + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +rdfa: + - + uri: tests/data/schema.rdfa + format: rdfa +relations: + - tests/data/v1.owl +namespaces: + entity: 'Dunglas\EcommerceBundle\Document' + enum: 'Dunglas\EcommerceBundle\Enum' + interface: 'Dunglas\EcommerceBundle\Model' +annotationGenerators: + - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineMongoDBAnnotationGenerator +author: "Kévin Dunglas " +debug: true +useInterface: true +checkIsGoodRelations: true +types: + Thing: + properties: + name: ~ + description: ~ + image: { range: ImageObject } + additionalType: ~ + Product: + properties: + sku: + cardinality: "(0..1)" + url: ~ + brand: ~ + productID: ~ + releaseDate: ~ + offers: ~ + itemCondition: ~ + gtin13: ~ + gtin14: ~ + gtin8: ~ + mpn: ~ + color: ~ + depth: { range: "Text" } + height: { range: "Text" } + weight: { range: "Text" } + width: { range: "Text" } + seller: { range: "Seller" } + Brand: + parent: "Thing" + properties: + logo: { range: "ImageObject" } + Seller: + parent: false + guessFrom: Person + properties: + name: ~ + birthDate: ~ + ImageObject: + parent: Thing + properties: + caption: ~ + ProductModel: + properties: + isVariantOf: ~ + Offer: + parent: Thing + properties: + acceptedPaymentMethod: ~ + availability: ~ + availabilityStarts: ~ + availabilityEnds: ~ + availableDeliveryMethod: ~ + category: { range: "Text" } + deliveryLeadTime: ~ + inventoryLevel: ~ + itemCondition: ~ + price: { range: Number } + priceCurrency: ~ + validFrom: ~ + validThrough: ~ + DeliveryChargeSpecification: { parent: false } + PaymentChargeSpecification: { parent: false } + OfferItemCondition: ~ + PaymentMethod: ~ + ItemAvailability: ~ + DeliveryMethod: ~ + QuantitativeValue: { parent: false } diff --git a/tests/run-tests.sh b/tests/run-tests.sh index 79563ed0..cdf13838 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -11,6 +11,10 @@ bin/schema generate-types build/address-book/ tests/config/address-book.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml bin/schema generate-types build/vgo/ tests/config/vgo.yml +mkdir -p build/mongodb/ecommerce/ build/mongodb/address-book/ +bin/schema generate-types build/mongodb/address-book/ tests/config/mongodb/address-book.yml +bin/schema generate-types build/mongodb/ecommerce/ tests/config/mongodb/ecommerce.yml + # Check code CS vendor/bin/php-cs-fixer --dry-run --diff -vvv fix src/ From 8494ae7d11828fcf5d3cc7f65ed2986557b0dcf7 Mon Sep 17 00:00:00 2001 From: meyerbaptiste Date: Wed, 9 Mar 2016 12:46:19 +0100 Subject: [PATCH 048/258] Remove BC break introduced by #46 for the RDFa files configuration --- src/TypesGeneratorConfiguration.php | 11 +++++++++++ tests/config/vgo.yml | 3 +-- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index a917aeea..5a868e42 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -36,6 +36,17 @@ public function getConfigTreeBuilder() ->defaultValue([ ['uri' => self::SCHEMA_ORG_RDFA_URL, 'format' => null], ]) + ->beforeNormalization() + ->ifArray() + ->then(function (array $v) { + return array_map( + function ($rdfa) { + return is_scalar($rdfa) ? ['uri' => $rdfa, 'format' => null] : $rdfa; + }, + $v + ); + }) + ->end() ->prototype('array') ->children() ->scalarNode('uri')->defaultValue(self::SCHEMA_ORG_RDFA_URL)->info('RDFa URI to use')->example(self::SCHEMA_ORG_RDFA_URL)->end() diff --git a/tests/config/vgo.yml b/tests/config/vgo.yml index 50e04c6c..2205d139 100644 --- a/tests/config/vgo.yml +++ b/tests/config/vgo.yml @@ -15,5 +15,4 @@ rdfa: - uri: tests/data/vgo.rdf format: ~ - - - uri: tests/data/schema.rdfa + - tests/data/schema.rdfa From 259c80ac4c3e67376576fd51ae954f4075e4c067 Mon Sep 17 00:00:00 2001 From: dunglas Date: Fri, 11 Mar 2016 05:44:50 -0500 Subject: [PATCH 049/258] Applied fixes from StyleCI --- .../AbstractAnnotationGenerator.php | 6 ++++-- .../AnnotationGeneratorInterface.php | 6 ++++-- .../ApiPlatformCoreAnnotationGenerator.php | 6 ++++-- .../ConstraintAnnotationGenerator.php | 6 ++++-- .../DoctrineOrmAnnotationGenerator.php | 6 ++++-- .../DunglasApiAnnotationGenerator.php | 6 ++++-- .../PhpDocAnnotationGenerator.php | 6 ++++-- .../SerializerGroupsAnnotationGenerator.php | 6 ++++-- src/CardinalitiesExtractor.php | 6 ++++-- src/Command/DumpConfigurationCommand.php | 9 +++++---- src/Command/ExtractCardinalitiesCommand.php | 11 ++++++----- src/Command/GenerateTypesCommand.php | 15 ++++++++------- src/GoodRelationsBridge.php | 6 ++++-- src/TypesGenerator.php | 13 +++++++------ src/TypesGeneratorConfiguration.php | 9 +++++---- .../ApiPlatformCoreAnnotationGeneratorTest.php | 6 ++++-- tests/bootstrap.php | 6 ++++-- 17 files changed, 79 insertions(+), 50 deletions(-) diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php index 8c2469eb..bdde6492 100644 --- a/src/AnnotationGenerator/AbstractAnnotationGenerator.php +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/AnnotationGeneratorInterface.php b/src/AnnotationGenerator/AnnotationGeneratorInterface.php index abb45954..7a17171e 100644 --- a/src/AnnotationGenerator/AnnotationGeneratorInterface.php +++ b/src/AnnotationGenerator/AnnotationGeneratorInterface.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php index c6986a91..c5366b3a 100644 --- a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php +++ b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php index 2de0d615..262a220f 100644 --- a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php +++ b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index 69723a6f..30031836 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php index c2f8c366..eb1894b9 100644 --- a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index 0d648360..1d39b6b5 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php b/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php index 33d3e2dd..80ceb56f 100644 --- a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php +++ b/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index 49ab0f68..bbaaaa30 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator; diff --git a/src/Command/DumpConfigurationCommand.php b/src/Command/DumpConfigurationCommand.php index 55dfa9a0..ee375ee1 100644 --- a/src/Command/DumpConfigurationCommand.php +++ b/src/Command/DumpConfigurationCommand.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\Command; @@ -29,8 +31,7 @@ protected function configure() { $this ->setName('dump-configuration') - ->setDescription('Dump configuration') - ; + ->setDescription('Dump configuration'); } /** diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 1fed5f81..44c6429b 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -1,17 +1,19 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\Command; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; @@ -30,8 +32,7 @@ protected function configure() { $this ->setName('extract-cardinalities') - ->setDescription('Extract properties\' cardinality') - ; + ->setDescription('Extract properties\' cardinality'); } /** diff --git a/src/Command/GenerateTypesCommand.php b/src/Command/GenerateTypesCommand.php index 62f8962d..c05761f6 100644 --- a/src/Command/GenerateTypesCommand.php +++ b/src/Command/GenerateTypesCommand.php @@ -1,24 +1,26 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\Command; +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\GoodRelationsBridge; use ApiPlatform\SchemaGenerator\TypesGenerator; use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use ApiPlatform\SchemaGenerator\GoodRelationsBridge; -use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Logger\ConsoleLogger; use Symfony\Component\Console\Output\OutputInterface; -use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Yaml\Parser; /** @@ -37,8 +39,7 @@ protected function configure() ->setName('generate-types') ->setDescription('Generate types') ->addArgument('output', InputArgument::REQUIRED, 'The output directory') - ->addArgument('config', InputArgument::OPTIONAL, 'The config file to use') - ; + ->addArgument('config', InputArgument::OPTIONAL, 'The config file to use'); } /** diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index b93c62ff..4b6b5a67 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator; diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 940e23e9..888fee44 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator; @@ -823,13 +825,12 @@ private function fixCs(array $files) $resolver ->setAllFixers($fixer->getFixers()) ->setConfig($config) - ->setOptions(array( + ->setOptions([ 'level' => 'symfony', 'fixers' => null, 'progress' => false, - )) - ->resolve() - ; + ]) + ->resolve(); $config->fixers($resolver->getFixers()); diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 5a868e42..9ff8ca9d 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator; @@ -150,8 +152,7 @@ function ($rdfa) { ]) ->prototype('scalar')->end() ->end() - ->end() - ; + ->end(); return $treeBuilder; } diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index 366ee85f..e254f69e 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\Tests; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 207b855c..1ce7a174 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ return require __DIR__.'/../vendor/autoload.php'; From c8bdd7e8bc17f7d2dc43f3d4adb7517d602b37fb Mon Sep 17 00:00:00 2001 From: Teoh Han Hui Date: Wed, 16 Mar 2016 17:11:36 +0800 Subject: [PATCH 050/258] Add test for TypesGenerator Also includes partial fix for #43 (Config problem is still unresolved) --- .travis.yml | 31 +- src/TypesGenerator.php | 67 ++- ...ApiPlatformCoreAnnotationGeneratorTest.php | 2 +- tests/TypesGeneratorTest.php | 395 ++++++++++++++++++ tests/config/blog.yml | 27 ++ tests/run-tests.sh | 3 +- 6 files changed, 494 insertions(+), 31 deletions(-) create mode 100644 tests/TypesGeneratorTest.php create mode 100644 tests/config/blog.yml diff --git a/.travis.yml b/.travis.yml index df9d9d0c..828b91d0 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,20 +3,25 @@ language: php sudo: false cache: - directories: - - $HOME/.composer/cache + directories: + - $HOME/.composer/cache -php: - - 5.4 - - 5.5 - - 5.6 - - 7.0 - - hhvm +matrix: + fast_finish: true + include: + - php: '5.4' + - php: '5.5' + - php: '5.6' + - php: '7.0' + - php: hhvm -before_script: - - composer self-update - - composer update +before_install: + - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpenv config-rm xdebug.ini; fi; + - composer self-update + +install: + - composer update --no-interaction --prefer-dist script: - - phpunit - - tests/run-tests.sh + - phpunit + - tests/run-tests.sh diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 888fee44..eeeab635 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -133,13 +133,13 @@ public function generate($config) $typesToGenerate = $graph->allOfType('rdfs:Class'); } } else { - foreach ($config['types'] as $key => $value) { + foreach ($config['types'] as $typeName => $typeConfig) { $resource = null; foreach ($this->graphs as $graph) { $resources = $graph->resources(); - if (isset($resources[$value['vocabularyNamespace'].$key])) { - $resource = $graph->resource($value['vocabularyNamespace'].$key, 'rdfs:Class'); + if (isset($resources[$typeConfig['vocabularyNamespace'].$typeName])) { + $resource = $graph->resource($typeConfig['vocabularyNamespace'].$typeName, 'rdfs:Class'); break; } } @@ -147,9 +147,9 @@ public function generate($config) if ($resource) { $typesToGenerate[] = $resource; } else { - $this->logger->warning('Type "{key}" cannot be found. Using "{guessFrom}" type to generate entity.', ['key' => $key, 'guessFrom' => $value['guessFrom']]); - $type = $graph->resource($value['vocabularyNamespace'].$value['guessFrom'], 'rdfs:Class'); - $typesToGenerate[$key] = $type; + $this->logger->warning('Type "{typeName}" cannot be found. Using "{guessFrom}" type to generate entity.', ['typeName' => $typeName, 'guessFrom' => $typeConfig['guessFrom']]); + $type = $graph->resource($typeConfig['vocabularyNamespace'].$typeConfig['guessFrom'], 'rdfs:Class'); + $typesToGenerate[$typeName] = $type; } } } @@ -157,8 +157,8 @@ public function generate($config) $classes = []; $propertiesMap = $this->createPropertiesMap($typesToGenerate); - foreach ($typesToGenerate as $key => $type) { - $typeName = is_string($key) ? $key : $type->localName(); + foreach ($typesToGenerate as $typeName => $type) { + $typeName = is_string($typeName) ? $typeName : $type->localName(); $typeConfig = isset($config['types'][$typeName]) ? $config['types'][$typeName] : null; $class = $baseClass; @@ -195,7 +195,7 @@ public function generate($config) $numberOfSupertypes = count($type->all('rdfs:subClassOf')); if ($numberOfSupertypes > 1) { - $this->logger->error(sprintf('The type "%s" has several supertypes. Using the first one.', $type->localName())); + $this->logger->warning(sprintf('The type "%s" has several supertypes. Using the first one.', $type->localName())); } $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; @@ -218,7 +218,7 @@ public function generate($config) // Fields foreach ($propertiesMap[$type->getUri()] as $property) { // Ignore properties not set if using a config file - if (is_array($typeConfig['properties']) && !isset($typeConfig['properties'][$property->localName()])) { + if (isset($typeConfig['properties']) && is_array($typeConfig['properties']) && !array_key_exists($property->localName(), $typeConfig['properties'])) { continue; } @@ -226,7 +226,7 @@ public function generate($config) } // Add custom fields (non schema.org) - if (is_array($typeConfig['properties'])) { + if (isset($typeConfig['properties']) && is_array($typeConfig['properties'])) { foreach (array_diff_key($typeConfig['properties'], $class['fields']) as $propertyName => $property) { $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->localName())); @@ -256,6 +256,41 @@ public function generate($config) } else { $class['abstract'] = $class['hasChild']; } + + // When including all properties, ignore properties already set on parent + $typeConfig = isset($config['types'][$class['name']]) ? $config['types'][$class['name']] : null; + if ((!isset($typeConfig['properties']) || !is_array($typeConfig['properties'])) && $class['parent']) { + $type = $class['resource']; + + foreach ($propertiesMap[$type->getUri()] as $property) { + if (!isset($class['fields'][$property->localName()])) { + continue; + } + + $parentConfig = isset($config['types'][$class['parent']]) ? $config['types'][$class['parent']] : null; + $parentClass = $classes[$class['parent']]; + + while ($parentClass) { + if (!isset($parentConfig['properties']) || !is_array($parentConfig['properties'])) { + // Unset implicit property + $parentType = $parentClass['resource']; + if (in_array($property, $propertiesMap[$parentType->getUri()])) { + unset($class['fields'][$property->localName()]); + continue 2; + } + } else { + // Unset explicit property + if (array_key_exists($property->localName(), $parentConfig['properties'])) { + unset($class['fields'][$property->localName()]); + continue 2; + } + } + + $parentConfig = $parentClass['parent'] ? (isset($config['types'][$parentClass['parent']]) ? $config['types'][$parentClass['parent']] : null) : null; + $parentClass = $parentClass['parent'] ? $classes[$parentClass['parent']] : null; + } + } + } } // Generate ID @@ -435,7 +470,7 @@ private function getParentClasses(\EasyRdf_Resource $resource, array $parentClas } /** - * Create a maps between class an properties. + * Creates a map between classes and properties. * * @param array $types * @@ -526,7 +561,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t } } - $propertyConfig = $typeConfig['properties'][$propertyName]; + $propertyConfig = isset($typeConfig['properties'][$propertyName]) ? $typeConfig['properties'][$propertyName] : null; $ranges = []; if (isset($propertyConfig['range']) && $propertyConfig['range']) { @@ -544,7 +579,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyName, $type->localName())); } else { if ($numberOfRanges > 1) { - $this->logger->error(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); + $this->logger->warning(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); } $cardinality = isset($propertyConfig['cardinality']) ? $propertyConfig['cardinality'] : false; @@ -557,7 +592,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t CardinalitiesExtractor::CARDINALITY_N_N, ]); - if (false === $propertyConfig['nullable']) { + if (isset($propertyConfig['nullable']) && false === $propertyConfig['nullable']) { $isNullable = false; } else { $isNullable = !in_array($cardinality, [ @@ -580,7 +615,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t 'cardinality' => $cardinality, 'isArray' => $isArray, 'isNullable' => $isNullable, - 'isUnique' => $propertyConfig['unique'], + 'isUnique' => isset($propertyConfig['unique']) && $propertyConfig['unique'], 'isCustom' => empty($property), 'isEmbedded' => $isEmbedded, 'columnPrefix' => $columnPrefix, diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index e254f69e..0bd00e08 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace ApiPlatform\SchemaGenerator\Tests; +namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; use ApiPlatform\SchemaGenerator\TypesGenerator; diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php new file mode 100644 index 00000000..d0bc1c85 --- /dev/null +++ b/tests/TypesGeneratorTest.php @@ -0,0 +1,395 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ApiPlatform\SchemaGenerator\Tests; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\TypesGenerator; +use Prophecy\Argument; +use Psr\Log\NullLogger; + +/** + * @author Teoh Han Hui + */ +class TypesGeneratorTest extends \PHPUnit_Framework_TestCase +{ + public function testGenerate() + { + $twigProphecy = $this->prophesize('Twig_Environment'); + $classes = $this->getClasses(); + foreach ($classes as $class) { + $twigProphecy->render('class.php.twig', Argument::that($this->getContextMatcher($class)))->willReturn()->shouldBeCalled(); + } + $twigProphecy->render('class.php.twig', Argument::type('array'))->willReturn(); + $twig = $twigProphecy->reveal(); + + $logger = new NullLogger(); + + $graphs = $this->getGraphs(); + + $cardinalitiesExtractorProphecy = $this->prophesize('ApiPlatform\SchemaGenerator\CardinalitiesExtractor'); + $cardinalities = $this->getCardinalities(); + $cardinalitiesExtractorProphecy->extract()->willReturn($cardinalities)->shouldBeCalled(); + $cardinalitiesExtractor = $cardinalitiesExtractorProphecy->reveal(); + + $goodRelationsBridgeProphecy = $this->prophesize('ApiPlatform\SchemaGenerator\GoodRelationsBridge'); + $goodRelationsBridge = $goodRelationsBridgeProphecy->reveal(); + + $typesGenerator = new TypesGenerator($twig, $logger, $graphs, $cardinalitiesExtractor, $goodRelationsBridge); + + $config = $this->getConfig(); + $typesGenerator->generate($config); + } + + private function getGraphs() + { + $graph = new \EasyRdf_Graph(); + + $graph->addResource('http://schema.org/Article', 'rdf:type', 'rdfs:Class'); + $graph->addResource('http://schema.org/Article', 'rdfs:subClassOf', 'http://schema.org/CreativeWork'); + + $graph->addResource('http://schema.org/BlogPosting', 'rdf:type', 'rdfs:Class'); + $graph->addResource('http://schema.org/BlogPosting', 'rdfs:subClassOf', 'http://schema.org/SocialMediaPosting'); + + $graph->addResource('http://schema.org/CreativeWork', 'rdf:type', 'rdfs:Class'); + $graph->addResource('http://schema.org/CreativeWork', 'rdfs:subClassOf', 'http://schema.org/Thing'); + + $graph->addResource('http://schema.org/Person', 'rdf:type', 'rdfs:Class'); + $graph->addResource('http://schema.org/Person', 'rdfs:subClassOf', 'http://schema.org/Thing'); + + $graph->addResource('http://schema.org/SocialMediaPosting', 'rdf:type', 'rdfs:Class'); + $graph->addResource('http://schema.org/SocialMediaPosting', 'rdfs:subClassOf', 'http://schema.org/Article'); + + $graph->addResource('http://schema.org/Thing', 'rdf:type', 'rdfs:Class'); + + $graph->addResource('http://schema.org/articleBody', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/articleBody', 'schema:domainIncludes', 'http://schema.org/Article'); + $graph->addResource('http://schema.org/articleBody', 'schema:rangeIncludes', 'http://schema.org/Text'); + + $graph->addResource('http://schema.org/articleSection', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/articleSection', 'schema:domainIncludes', 'http://schema.org/Article'); + $graph->addResource('http://schema.org/articleSection', 'schema:rangeIncludes', 'http://schema.org/Text'); + + $graph->addResource('http://schema.org/author', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/author', 'schema:domainIncludes', 'http://schema.org/CreativeWork'); + $graph->addResource('http://schema.org/author', 'schema:rangeIncludes', 'http://schema.org/Person'); + + $graph->addResource('http://schema.org/datePublished', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/datePublished', 'schema:domainIncludes', 'http://schema.org/CreativeWork'); + $graph->addResource('http://schema.org/datePublished', 'schema:rangeIncludes', 'http://schema.org/Date'); + + $graph->addResource('http://schema.org/headline', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/headline', 'schema:domainIncludes', 'http://schema.org/CreativeWork'); + $graph->addResource('http://schema.org/headline', 'schema:rangeIncludes', 'http://schema.org/Text'); + + $graph->addResource('http://schema.org/isFamilyFriendly', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/isFamilyFriendly', 'schema:domainIncludes', 'http://schema.org/CreativeWork'); + $graph->addResource('http://schema.org/isFamilyFriendly', 'schema:rangeIncludes', 'http://schema.org/Boolean'); + + $graph->addResource('http://schema.org/name', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/name', 'schema:domainIncludes', 'http://schema.org/Thing'); + $graph->addResource('http://schema.org/name', 'schema:rangeIncludes', 'http://schema.org/Text'); + + $graph->addResource('http://schema.org/sharedContent', 'rdf:type', 'rdf:Property'); + $graph->addResource('http://schema.org/sharedContent', 'schema:domainIncludes', 'http://schema.org/SocialMediaPosting'); + $graph->addResource('http://schema.org/sharedContent', 'schema:rangeIncludes', 'http://schema.org/CreativeWork'); + + return [ + $graph, + ]; + } + + private function getCardinalities() + { + return [ + 'articleBody' => CardinalitiesExtractor::CARDINALITY_0_1, + 'articleSection' => CardinalitiesExtractor::CARDINALITY_0_N, + 'author' => CardinalitiesExtractor::CARDINALITY_0_1, + 'datePublished' => CardinalitiesExtractor::CARDINALITY_UNKNOWN, + 'headline' => CardinalitiesExtractor::CARDINALITY_UNKNOWN, + 'isFamilyFriendly' => CardinalitiesExtractor::CARDINALITY_0_1, + 'name' => CardinalitiesExtractor::CARDINALITY_0_1, + 'sharedContent' => CardinalitiesExtractor::CARDINALITY_UNKNOWN, + ]; + } + + private function getConfig() + { + return [ + 'annotationGenerators' => [ + ], + 'checkIsGoodRelations' => false, + 'namespaces' => [ + 'entity' => 'AppBundle\Entity', + ], + 'output' => 'build/type-generator-test', + 'types' => [ + 'Article' => [ + 'properties' => [ + 'articleBody' => null, + 'articleSection' => null, + ], + 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, + ], + 'CreativeWork' => [ + 'properties' => [ + 'author' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_N_0, + 'range' => 'Person', + ], + 'datePublished' => null, + 'headline' => null, + 'isFamilyFriendly' => null, + ], + 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, + ], + 'BlogPosting' => [ + 'properties' => null, + 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, + ], + 'Person' => [ + 'properties' => [ + ], + 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, + ], + 'SocialMediaPosting' => [ + 'properties' => null, + 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, + ], + 'Thing' => [ + 'properties' => [ + 'name' => null, + ], + 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, + ], + ], + 'generateId' => true, + 'useInterface' => false, + ]; + } + + private function getClasses() + { + return [ + 'Article' => [ + 'abstract' => true, + 'embeddable' => false, + 'fields' => [ + 'articleBody' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_0_1, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'articleBody', + 'range' => 'Text', + ], + 'articleSection' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_0_N, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'articleSection', + 'range' => 'Text', + ], + ], + 'hasChild' => true, + 'isEnum' => false, + 'name' => 'Article', + 'namespace' => 'AppBundle\Entity', + 'parent' => 'CreativeWork', + ], + 'BlogPosting' => [ + 'abstract' => false, + 'embeddable' => false, + 'fields' => [ + 'id' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, + 'isArray' => false, + 'isCustom' => true, + 'isEnum' => false, + 'isId' => true, + 'isNullable' => false, + 'isUnique' => false, + 'name' => 'id', + 'range' => 'Integer', + ], + ], + 'hasChild' => false, + 'isEnum' => false, + 'name' => 'BlogPosting', + 'namespace' => 'AppBundle\Entity', + 'parent' => 'SocialMediaPosting', + ], + 'CreativeWork' => [ + 'abstract' => true, + 'embeddable' => false, + 'fields' => [ + 'author' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_N_0, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'author', + 'range' => 'Person', + ], + 'datePublished' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_UNKNOWN, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'datePublished', + 'range' => 'Date', + ], + 'headline' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_UNKNOWN, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'headline', + 'range' => 'Text', + ], + 'isFamilyFriendly' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_0_1, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'isFamilyFriendly', + 'range' => 'Boolean', + ], + ], + 'hasChild' => true, + 'isEnum' => false, + 'name' => 'CreativeWork', + 'namespace' => 'AppBundle\Entity', + 'parent' => 'Thing', + ], + 'Person' => [ + 'abstract' => false, + 'embeddable' => false, + 'fields' => [ + 'id' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_1_1, + 'isArray' => false, + 'isCustom' => true, + 'isEnum' => false, + 'isId' => true, + 'isNullable' => false, + 'isUnique' => false, + 'name' => 'id', + 'range' => 'Integer', + ], + ], + 'hasChild' => false, + 'isEnum' => false, + 'name' => 'Person', + 'namespace' => 'AppBundle\Entity', + 'parent' => 'Thing', + ], + 'SocialMediaPosting' => [ + 'abstract' => true, + 'embeddable' => false, + 'fields' => [ + 'sharedContent' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_UNKNOWN, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'sharedContent', + 'range' => 'CreativeWork', + ], + ], + 'hasChild' => true, + 'isEnum' => false, + 'name' => 'SocialMediaPosting', + 'namespace' => 'AppBundle\Entity', + 'parent' => 'Article', + ], + 'Thing' => [ + 'abstract' => true, + 'embeddable' => false, + 'fields' => [ + 'name' => [ + 'cardinality' => CardinalitiesExtractor::CARDINALITY_0_1, + 'isArray' => false, + 'isCustom' => false, + 'isEnum' => false, + 'isId' => false, + 'isNullable' => true, + 'isUnique' => false, + 'name' => 'name', + 'range' => 'Text', + ], + ], + 'hasChild' => true, + 'isEnum' => false, + 'name' => 'Thing', + 'namespace' => 'AppBundle\Entity', + 'parent' => false, + ], + ]; + } + + /** + * @return \Closure + */ + private function getContextMatcher(array $class) + { + $config = $this->getConfig(); + $classes = $this->getClasses(); + + return function ($context) use ($config, $classes, $class) { + if (!isset($context['config']) || $config !== $context['config']) { + return false; + } + + $baseClass = array_diff_key($class, [ + 'fields' => null, + ]); + + if (!isset($context['class']) || !is_array($context['class']) || $baseClass != array_intersect_key($context['class'], $baseClass)) { + return false; + } + + if (array_keys($class['fields']) != array_keys($context['class']['fields'])) { + return false; + } + + foreach ($class['fields'] as $fieldName => $field) { + if ($field != array_intersect_key($context['class']['fields'][$fieldName], $field)) { + return false; + } + } + + return true; + }; + } +} diff --git a/tests/config/blog.yml b/tests/config/blog.yml new file mode 100644 index 00000000..81bc5e05 --- /dev/null +++ b/tests/config/blog.yml @@ -0,0 +1,27 @@ +annotationGenerators: # Generators we want to use, keep it as is for any API Platform project + - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator +namespaces: + entity: AppBundle\Entity # The default namespace for entities, following API Platform and Symfony best practices +types: # The list of type to generated (a PHP entity class by type will be generated) + SocialMediaPosting: ~ + BlogPosting: ~ # A type to generate a PHP entity class from, including all its properties (here this type has no specific property, they are all inherited) + Article: # Schema.org has an inheritance system, we will configure all types of the hierarchy + properties: # The list of properties we want to use + articleBody: ~ + articleSection: ~ + CreativeWork: + properties: + author: + range: Person # PHP Schema handle relations. Here we force the type of the property to Person + cardinality: (*..0) # Force the cardinality of the relation + headline: ~ + isFamilyFriendly: ~ + datePublished: ~ + Thing: + properties: + name: ~ + Person: # Person is a relation of the "CreativeWork" type (property "author"), PHP Schema will generate relations for us + properties: {} # We don't want any specific property for a person except "name" inherited from Thing diff --git a/tests/run-tests.sh b/tests/run-tests.sh index cbe6e014..813a8a0c 100755 --- a/tests/run-tests.sh +++ b/tests/run-tests.sh @@ -6,8 +6,9 @@ bin/schema extract-cardinalities # Build models rm -Rf build/ -mkdir -p build/ecommerce/ build/address-book/ build/vgo/ +mkdir -p build/address-book/ build/blog/ build/ecommerce/ build/vgo/ bin/schema generate-types build/address-book/ tests/config/address-book.yml +bin/schema generate-types build/blog/ tests/config/blog.yml bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml bin/schema generate-types build/vgo/ tests/config/vgo.yml From 113e9502ceec056d77df13e989fa64b4ce6fa926 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 11 May 2016 09:01:24 +0200 Subject: [PATCH 051/258] Fix CS --- src/TypesGenerator.php | 2 +- .../ApiPlatformCoreAnnotationGeneratorTest.php | 2 +- tests/TypesGeneratorTest.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index bc027bc1..0f4df665 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -202,7 +202,7 @@ public function generate($config) } if (null !== $class['parent']) { - $class['uses'][] = sprintf('%s\\%s', $config['types']['Thing']['namespaces']['class'], $class['parent']); + $class['uses'][] = sprintf('%s\\%s', $config['types']['Thing']['namespaces']['class'], $class['parent']); } // Embeddable diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index 0bd00e08..ac94a64b 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\tests\AnnotationGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; use ApiPlatform\SchemaGenerator\TypesGenerator; diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index d0bc1c85..4275ba90 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace ApiPlatform\SchemaGenerator\Tests; +namespace ApiPlatform\SchemaGenerator\tests; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\TypesGenerator; From ceb6b55dc0a700cad05c05045c79e8e64399a078 Mon Sep 17 00:00:00 2001 From: dunglas Date: Wed, 11 May 2016 03:01:39 -0400 Subject: [PATCH 052/258] Applied fixes from StyleCI --- .../DoctrineMongoDBAnnotationGenerator.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php index 9a4a65e7..5f8967cb 100644 --- a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php @@ -1,10 +1,12 @@ * - * This source file is subject to the MIT license that is bundled - * with this source code in the file LICENSE. + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. */ namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; From 2a16c063c36ed96bd4276ed0b0ba2bf05400d16a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 11 May 2016 09:02:43 +0200 Subject: [PATCH 053/258] Add StyleCI badge --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index c9a2460a..0e0713e6 100644 --- a/README.md +++ b/README.md @@ -24,6 +24,7 @@ and custom generator can be added (e.g.: a Doctrine ODM mapping generator). or any other framework including [Laravel](https://laravel.com) and [Zend Framework](http://framework.zend.com/)). [![Build Status](https://travis-ci.org/api-platform/schema-generator.svg?branch=master)](https://travis-ci.org/api-platform/schema-generator) [![SensioLabsInsight](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5/mini.png)](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5) +[![StyleCI](https://styleci.io/repos/16409773/shield)](https://styleci.io/repos/16409773) ## What is Schema.org? From 1567edd9b0242a6bbe211d131be6e93e48e2cc3d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 11 May 2016 09:24:58 +0200 Subject: [PATCH 054/258] Fix tests --- src/TypesGenerator.php | 8 ++++++-- tests/TypesGeneratorTest.php | 3 +-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 0f4df665..657941b4 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -201,8 +201,12 @@ public function generate($config) $class['parent'] = $numberOfSupertypes ? $type->all('rdfs:subClassOf')[0]->localName() : false; } - if (null !== $class['parent']) { - $class['uses'][] = sprintf('%s\\%s', $config['types']['Thing']['namespaces']['class'], $class['parent']); + if (isset($class['parent']) && isset($config['types'][$class['parent']]['namespaces']['class'])) { + $parentNamespace = $config['types'][$class['parent']]['namespaces']['class']; + + if ($parentNamespace !== $class['namespace']) { + $class['uses'][] = $parentNamespace.'\\'.$class['parent']; + } } // Embeddable diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 4275ba90..61b5b3f6 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -45,8 +45,7 @@ public function testGenerate() $typesGenerator = new TypesGenerator($twig, $logger, $graphs, $cardinalitiesExtractor, $goodRelationsBridge); - $config = $this->getConfig(); - $typesGenerator->generate($config); + $typesGenerator->generate($this->getConfig()); } private function getGraphs() From a5782255d81c0713d22ca8512bd3158fbee844ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 12 May 2016 08:42:30 +0200 Subject: [PATCH 055/258] Allow to generate all properties again --- src/TypesGenerator.php | 13 ++++++------- src/TypesGeneratorConfiguration.php | 17 ++++++++++++++--- tests/TypesGeneratorTest.php | 19 ++++++++----------- 3 files changed, 28 insertions(+), 21 deletions(-) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 657941b4..b72ad338 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -113,8 +113,10 @@ public function __construct(\Twig_Environment $twig, LoggerInterface $logger, ar /** * Generates files. + * + * @param array $config */ - public function generate($config) + public function generate(array $config) { $baseClass = [ 'constants' => [], @@ -226,11 +228,9 @@ public function generate($config) // Fields foreach ($propertiesMap[$type->getUri()] as $property) { // Ignore properties not set if using a config file - if (isset($typeConfig['properties']) && is_array($typeConfig['properties']) && !array_key_exists($property->localName(), $typeConfig['properties'])) { - continue; + if ($typeConfig['allProperties'] || (is_array($typeConfig['properties']) && array_key_exists($property->localName(), $typeConfig['properties']))) { + $class = $this->generateField($config, $class, $type, $typeName, $property->localName(), $property); } - - $class = $this->generateField($config, $class, $type, $typeName, $property->localName(), $property); } // Add custom fields (non schema.org) @@ -266,8 +266,7 @@ public function generate($config) } // When including all properties, ignore properties already set on parent - $typeConfig = isset($config['types'][$class['name']]) ? $config['types'][$class['name']] : null; - if ((!isset($typeConfig['properties']) || !is_array($typeConfig['properties'])) && $class['parent']) { + if (isset($config['types'][$class['name']]['allProperties']) && $config['types'][$class['name']]['allProperties'] && $class['parent']) { $type = $class['resource']; foreach ($propertiesMap[$type->getUri()] as $property) { diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index f0a0f69d..976e42d6 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -58,9 +58,7 @@ function ($rdfa) { ->end() ->arrayNode('relations') ->info('OWL relation files to use') - ->defaultValue([ - self::GOOD_RELATIONS_OWL_URL, - ]) + ->defaultValue([self::GOOD_RELATIONS_OWL_URL]) ->prototype('scalar')->end() ->end() ->booleanNode('debug')->defaultFalse()->info('Debug mode')->end() @@ -88,6 +86,18 @@ function ($rdfa) { ->scalarNode('author')->defaultFalse()->info('The value of the phpDoc\'s @author annotation')->example('Kévin Dunglas ')->end() ->enumNode('fieldVisibility')->values(['private', 'protected', 'public'])->defaultValue('private')->cannotBeEmpty()->info('Visibility of entities fields')->end() ->arrayNode('types') + ->beforeNormalization() + ->always() + ->then(function ($v) { + foreach ($v as $key => $type) { + if (!isset($type['properties'])) { + $v[$key]['allProperties'] = true; + } + } + + return $v; + }) + ->end() ->info('Schema.org\'s types to use') ->useAttributeAsKey('id') ->prototype('array') @@ -111,6 +121,7 @@ function ($rdfa) { ->end() ->scalarNode('parent')->defaultNull()->info('The parent class, set to false for a top level class')->end() ->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end() + ->booleanNode('allProperties')->defaultFalse()->info('Import all existing properties')->end() ->arrayNode('properties') ->info('Properties of this type to use') ->useAttributeAsKey('id') diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 61b5b3f6..0cb69a0f 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -31,10 +31,6 @@ public function testGenerate() $twigProphecy->render('class.php.twig', Argument::type('array'))->willReturn(); $twig = $twigProphecy->reveal(); - $logger = new NullLogger(); - - $graphs = $this->getGraphs(); - $cardinalitiesExtractorProphecy = $this->prophesize('ApiPlatform\SchemaGenerator\CardinalitiesExtractor'); $cardinalities = $this->getCardinalities(); $cardinalitiesExtractorProphecy->extract()->willReturn($cardinalities)->shouldBeCalled(); @@ -43,7 +39,7 @@ public function testGenerate() $goodRelationsBridgeProphecy = $this->prophesize('ApiPlatform\SchemaGenerator\GoodRelationsBridge'); $goodRelationsBridge = $goodRelationsBridgeProphecy->reveal(); - $typesGenerator = new TypesGenerator($twig, $logger, $graphs, $cardinalitiesExtractor, $goodRelationsBridge); + $typesGenerator = new TypesGenerator($twig, new NullLogger(), $this->getGraphs(), $cardinalitiesExtractor, $goodRelationsBridge); $typesGenerator->generate($this->getConfig()); } @@ -132,6 +128,7 @@ private function getConfig() 'output' => 'build/type-generator-test', 'types' => [ 'Article' => [ + 'allProperties' => false, 'properties' => [ 'articleBody' => null, 'articleSection' => null, @@ -139,6 +136,7 @@ private function getConfig() 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, ], 'CreativeWork' => [ + 'allProperties' => false, 'properties' => [ 'author' => [ 'cardinality' => CardinalitiesExtractor::CARDINALITY_N_0, @@ -151,22 +149,21 @@ private function getConfig() 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, ], 'BlogPosting' => [ + 'allProperties' => true, 'properties' => null, 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, ], 'Person' => [ - 'properties' => [ - ], + 'allProperties' => false, + 'properties' => [], 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, ], 'SocialMediaPosting' => [ - 'properties' => null, + 'allProperties' => true, 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, ], 'Thing' => [ - 'properties' => [ - 'name' => null, - ], + 'allProperties' => true, 'vocabularyNamespace' => TypesGenerator::SCHEMA_ORG_NAMESPACE, ], ], From 8d2ac213be824a699a4c38acc78db66aa8e5220f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 15 May 2016 15:01:46 +0200 Subject: [PATCH 056/258] Add Box support (PHAR) --- .gitignore | 2 ++ .travis.yml | 15 +++++++++++++-- box.json | 26 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 box.json diff --git a/.gitignore b/.gitignore index 8f8675e0..3c2f5269 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /composer.phar /composer.lock +/box.phar /vendor /build +/schema.phar diff --git a/.travis.yml b/.travis.yml index 828b91d0..69bdf99d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,15 +13,26 @@ matrix: - php: '5.5' - php: '5.6' - php: '7.0' - - php: hhvm + - php: 'hhvm' before_install: - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpenv config-rm xdebug.ini; fi; - - composer self-update + - curl -LSs https://box-project.github.io/box2/installer.php | php install: - composer update --no-interaction --prefer-dist + - php box.phar build script: - phpunit - tests/run-tests.sh + +deploy: + provider: releases + api_key: + secure: Oq9TAPQZqnjxhbprWZQE64GhK4vxBHjvcMkS9dkbkCJQVz8cSqGxZOFqMOHulraFs2IX9PLeplrZReFMT630KkMNf74mkTtL9WMuaMJV0bbUPY+X7YpDGlLNNU7OA9Rxjr3y68x1jVxD6mLSlCFZP00qvmYRlOE1i2ltjO7L5Sw= + file: schema.phar + skip_cleanup: true + on: + tags: true + repo: api-platform/schema-generator diff --git a/box.json b/box.json new file mode 100644 index 00000000..eaffa491 --- /dev/null +++ b/box.json @@ -0,0 +1,26 @@ +{ + "directories": ["src/"], + "finder": [ + { + "name": "*.php", + "exclude": [ + ".gitignore", + ".md", + "phpunit", + "Tester", + "Tests", + "tests" + ], + "in": "vendor" + } + ], + "compactors": [ + "Herrera\\Box\\Compactor\\Json", + "Herrera\\Box\\Compactor\\Php" + ], + "git-version": "package_version", + "main": "bin/schema", + "output": "schema.phar", + "stub": true, + "chmod": "0755" +} From 54440e1251fa16ca02af62504f254b365cee557a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 15 May 2016 15:11:50 +0200 Subject: [PATCH 057/258] Fix Travis --- .travis.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 69bdf99d..6f6897ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,11 +17,11 @@ matrix: before_install: - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpenv config-rm xdebug.ini; fi; - - curl -LSs https://box-project.github.io/box2/installer.php | php + - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; install: - composer update --no-interaction --prefer-dist - - php box.phar build + - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then php box.phar build; fi; script: - phpunit @@ -36,3 +36,4 @@ deploy: on: tags: true repo: api-platform/schema-generator + php: '5.6' From fa432cfdf30ff26223e9a552905c6428ae347d7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 15 May 2016 15:38:45 +0200 Subject: [PATCH 058/258] Add a changelog --- CHANGELOG.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 CHANGELOG.md diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 00000000..7df8d046 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,62 @@ +# Changelog + +## 1.1.0 + +* MongoDB support +* API Platform Core v2 support +* Schema Generator is now available as PHAR +* Support any RDF vocabulary (was previously limited to Schema.org) +* Support for custom classes +* Support for [Doctrine Embeddables](http://doctrine-orm.readthedocs.io/projects/doctrine-orm/en/latest/tutorials/embeddables.html) +* Support for serialization groups +* Support for the `nullable` option +* Support for the `unique` option +* Support for custom Doctine `@Column` annotations +* Symfony 3.0 compatibility +* Various bug fixes and improved tests + +## 1.0.0 + +* Rename the package API Platform Schema Generator (formerly PHP Schema) +* Support for external and custom RDFa schemas +* Support custom name for relation tables +* Allow to use properties from parent classes +* Allow to create custom fields +* Improve code quality and tests + +## 0.4.3 + +* Fix compatibility with [API Platform Core](https://github.com/api-platform/core) v1 (formerly DunglasJsonLdApiBundle) + +## 0.4.2 + +* Fix compatibility with [API Platform Core](https://github.com/api-platform/core) v1 (formerly DunglasJsonLdApiBundle) + +## 0.4.1 + +* Make CS fixer working again + +## 0.4.0 + +* [API Platform Core](https://github.com/api-platform/core) v1 (formerly DunglasJsonLdApiBundle) support + +## 0.3.2 + +* Fixed Doctrine relations handling +* Better `null` value handling + +## 0.3.1 + +* Fix a bug when using Doctrine `ArrayCollection` +* Don't call `parent::__construct()`` when the parent constructor doesn't exist + +## 0.3.0 + +* Symfony / Doctrine's ResolveTragetEntityListener config mapping generation +* Refactored Doctrine config +* Removed deprecated call to `YAML::parse()`` + +## 0.2.0 + +* Better generated PHPDoc +* Removed `@type` support From 90bce71b110476f2f950a7798d4f3b34a34ea6cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 15 May 2016 22:43:27 +0200 Subject: [PATCH 059/258] Prefix annotations of API Platform with Api --- .../ApiPlatformCoreAnnotationGenerator.php | 6 +++--- .../ApiPlatformCoreAnnotationGeneratorTest.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php index c5366b3a..61a45fcf 100644 --- a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php +++ b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php @@ -29,7 +29,7 @@ public function generateClassAnnotations($className) { $resource = $this->classes[$className]['resource']; - return [sprintf('@Resource(iri="%s")', $resource->getUri())]; + return [sprintf('@ApiResource(iri="%s")', $resource->getUri())]; } /** @@ -37,7 +37,7 @@ public function generateClassAnnotations($className) */ public function generateFieldAnnotations($className, $fieldName) { - return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Property(iri="http://schema.org/%s")', $fieldName)]; + return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@ApiProperty(iri="http://schema.org/%s")', $fieldName)]; } /** @@ -50,6 +50,6 @@ public function generateUses($className) $subClassOf = $resource->get('rdfs:subClassOf'); $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; - return $typeIsEnum ? [] : ['ApiPlatform\Core\Annotation\Resource', 'ApiPlatform\Core\Annotation\Property']; + return $typeIsEnum ? [] : ['ApiPlatform\Core\Annotation\ApiResource', 'ApiPlatform\Core\Annotation\ApiProperty']; } } diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index ac94a64b..20bb14fa 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -51,18 +51,18 @@ public function setUp() public function testGenerateClassAnnotations() { - $this->assertSame(['@Resource(iri="http://schema.org/Res")'], $this->generator->generateClassAnnotations('Res')); + $this->assertSame(['@ApiResource(iri="http://schema.org/Res")'], $this->generator->generateClassAnnotations('Res')); } public function testGenerateFieldAnnotations() { - $this->assertSame(['@Property(iri="http://schema.org/prop")'], $this->generator->generateFieldAnnotations('Res', 'prop')); + $this->assertSame(['@ApiProperty(iri="http://schema.org/prop")'], $this->generator->generateFieldAnnotations('Res', 'prop')); $this->assertSame([], $this->generator->generateFieldAnnotations('Res', 'customProp')); } public function testGenerateUses() { - $this->assertSame(['ApiPlatform\Core\Annotation\Resource', 'ApiPlatform\Core\Annotation\Property'], $this->generator->generateUses('Res')); + $this->assertSame(['ApiPlatform\Core\Annotation\ApiResource', 'ApiPlatform\Core\Annotation\ApiProperty'], $this->generator->generateUses('Res')); $this->assertSame([], $this->generator->generateUses('MyEnum')); } } From 93a125bb8d93e990e82daa2d769fe02f33df3b5e Mon Sep 17 00:00:00 2001 From: Anto Date: Tue, 31 May 2016 14:07:00 +0200 Subject: [PATCH 060/258] replace abadonned dependency --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 6e6836f6..f3c79eed 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "psr/log": "~1.0", "easyrdf/easyrdf": "~0.9.0", "league/html-to-markdown": "~4.0", - "fabpot/php-cs-fixer": "~1.0" + "friendsofphp/php-cs-fixer": "~1.0" }, "require-dev": { "doctrine/orm": "~2.2", From 768bab88304022598ad72a38bcc2f2919e87d743 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 26 Sep 2016 22:55:05 +0200 Subject: [PATCH 061/258] Fix a notice using Enum. Refactor command's tests. --- .travis.yml | 1 - composer.json | 21 +- src/TypesGenerator.php | 2 +- ...ApiPlatformCoreAnnotationGeneratorTest.php | 2 +- tests/Command/DumpConfigurationTest.php | 166 ++++ .../ExtractCardinalitiesCommandTest.php | 879 ++++++++++++++++++ tests/Command/GenerateTypesCommandTest.php | 56 ++ tests/TypesGeneratorTest.php | 13 +- tests/run-tests.sh | 23 - 9 files changed, 1126 insertions(+), 37 deletions(-) create mode 100644 tests/Command/DumpConfigurationTest.php create mode 100644 tests/Command/ExtractCardinalitiesCommandTest.php create mode 100644 tests/Command/GenerateTypesCommandTest.php delete mode 100755 tests/run-tests.sh diff --git a/.travis.yml b/.travis.yml index 6f6897ba..8a42dffe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -25,7 +25,6 @@ install: script: - phpunit - - tests/run-tests.sh deploy: provider: releases diff --git a/composer.json b/composer.json index f3c79eed..13c4632f 100644 --- a/composer.json +++ b/composer.json @@ -20,18 +20,19 @@ "require": { "php": ">=5.4", "ext-json": "*", - "symfony/console": "~2.5|~3.0", - "symfony/yaml": "~2.4|~3.0", - "symfony/config": "~2.4|~3.0", - "twig/twig": "~1.0", - "psr/log": "~1.0", - "easyrdf/easyrdf": "~0.9.0", - "league/html-to-markdown": "~4.0", - "friendsofphp/php-cs-fixer": "~1.0" + "symfony/console": "^2.7 || ^3.0", + "symfony/yaml": "^2.7 || ^3.0", + "symfony/config": "^2.7 || ^3.0", + "twig/twig": "^1.0", + "psr/log": "^1.0", + "easyrdf/easyrdf": "^0.9", + "league/html-to-markdown": "^4.0", + "friendsofphp/php-cs-fixer": "^1.0" }, "require-dev": { - "doctrine/orm": "~2.2", - "symfony/validator": "~2.6" + "doctrine/orm": "^2.2", + "symfony/validator": "^2.7", + "symfony/filesystem": "^2.7" }, "suggest": { "myclabs/php-enum": "For enumerations", diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index b72ad338..9443739d 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -266,7 +266,7 @@ public function generate(array $config) } // When including all properties, ignore properties already set on parent - if (isset($config['types'][$class['name']]['allProperties']) && $config['types'][$class['name']]['allProperties'] && $class['parent']) { + if (isset($config['types'][$class['name']]['allProperties']) && $config['types'][$class['name']]['allProperties'] && isset($classes[$class['parent']])) { $type = $class['resource']; foreach ($propertiesMap[$type->getUri()] as $property) { diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index 20bb14fa..57f0e393 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace ApiPlatform\SchemaGenerator\tests\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; use ApiPlatform\SchemaGenerator\TypesGenerator; diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php new file mode 100644 index 00000000..e8b1c321 --- /dev/null +++ b/tests/Command/DumpConfigurationTest.php @@ -0,0 +1,166 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ApiPlatform\SchemaGenerator\Tests; + +use ApiPlatform\SchemaGenerator\Command\DumpConfigurationCommand; +use Symfony\Component\Console\Tester\CommandTester; + +/** + * @author Kévin Dunglas + */ +class DumpConfigurationTest extends \PHPUnit_Framework_TestCase +{ + public function testDumpConfiguration() + { + $commandTester = new CommandTester(new DumpConfigurationCommand()); + $this->assertEquals(0, $commandTester->execute([])); + $this->assertEquals(<< + + # PHP namespaces + namespaces: + + # The namespace of the generated entities + entity: SchemaOrg\Entity # Example: Acme\Entity + + # The namespace of the generated enumerations + enum: SchemaOrg\Enum # Example: Acme\Enum + + # The namespace of the generated interfaces + interface: SchemaOrg\Model # Example: Acme\Model + + # Doctrine + doctrine: + + # Use Doctrine's ArrayCollection instead of standard arrays + useCollection: true + + # The Resolve Target Entity Listener config file pass + resolveTargetEntityConfigPath: null + + # The value of the phpDoc's @author annotation + author: false # Example: Kévin Dunglas + + # Visibility of entities fields + fieldVisibility: private # One of "private"; "protected"; "public" + + # Schema.org's types to use + types: + + # Prototype + id: + + # Namespace of the vocabulary the type belongs to. + vocabularyNamespace: 'http://schema.org/' + + # Is the class abstract? (null to guess) + abstract: null + + # Is the class embeddable? + embeddable: false + + # Type namespaces + namespaces: + + # The namespace for the generated class (override any other defined namespace) + class: null + + # The namespace for the generated interface (override any other defined namespace) + interface: null + doctrine: + + # The Doctrine inheritance mapping type (override the guessed one) + inheritanceMapping: null + + # The parent class, set to false for a top level class + parent: null + + # If declaring a custom class, this will be the class from which properties type will be guessed + guessFrom: Thing + + # Import all existing properties + allProperties: false + + # Properties of this type to use + properties: + + # Prototype + id: + + # The property range + range: null # Example: Offer + + # The relation table name + 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"} + + # Symfony Serialization Groups + groups: [] + + # The property nullable + nullable: true + + # The property unique + unique: false + + # Is the property embedded? + embedded: false + + # The property columnPrefix + columnPrefix: false + + # Annotation generators to use + annotationGenerators: + + # Defaults: + - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator + + +YAML +, $commandTester->getDisplay()); + } +} diff --git a/tests/Command/ExtractCardinalitiesCommandTest.php b/tests/Command/ExtractCardinalitiesCommandTest.php new file mode 100644 index 00000000..ccb565b2 --- /dev/null +++ b/tests/Command/ExtractCardinalitiesCommandTest.php @@ -0,0 +1,879 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ApiPlatform\SchemaGenerator\Tests; + +use ApiPlatform\SchemaGenerator\Command\ExtractCardinalitiesCommand; +use Symfony\Component\Console\Tester\CommandTester; + +/** + * @author Kévin Dunglas + */ +class ExtractCardinalitiesCommandTest extends \PHPUnit_Framework_TestCase +{ + public function testExtractCardinalities() + { + $commandTester = new CommandTester(new ExtractCardinalitiesCommand()); + $this->assertEquals(0, $commandTester->execute([])); + $this->assertEquals(<<<'JSON' +{ + "geoRadius": "unknown", + "geoMidpoint": "unknown", + "hasOfferCatalog": "unknown", + "mapType": "unknown", + "orderQuantity": "(0..1)", + "orderItemStatus": "(0..1)", + "orderItemNumber": "(0..1)", + "orderDelivery": "(0..1)", + "additionalNumberOfGuests": "unknown", + "rsvpResponse": "(0..1)", + "schemaVersion": "unknown", + "about": "(0..1)", + "acceptedOffer": "(0..*)", + "acceptedPaymentMethod": "(0..*)", + "acceptsReservations": "unknown", + "accessCode": "unknown", + "accessibilityAPI": "unknown", + "accessibilityControl": "unknown", + "accessibilityFeature": "unknown", + "accessibilityHazard": "unknown", + "accountablePerson": "unknown", + "acquiredFrom": "(0..1)", + "actor": "unknown", + "actors": "unknown", + "additionalName": "unknown", + "additionalType": "unknown", + "addOn": "(0..*)", + "address": "unknown", + "addressCountry": "(0..1)", + "addressLocality": "(0..1)", + "addressRegion": "(0..1)", + "advanceBookingRequirement": "(0..1)", + "affiliation": "unknown", + "agent": "(0..1)", + "aggregateRating": "(0..1)", + "album": "unknown", + "albums": "unknown", + "alignmentType": "unknown", + "alternateName": "unknown", + "alternativeHeadline": "unknown", + "alumni": "unknown", + "alumniOf": "unknown", + "amountOfThisGood": "(1..1)", + "applicationCategory": "unknown", + "applicationSubCategory": "unknown", + "applicationSuite": "(0..1)", + "appliesToDeliveryMethod": "(0..*)", + "appliesToPaymentMethod": "(1..*)", + "area": "(0..1)", + "areaServed": "(0..1)", + "articleBody": "(0..1)", + "articleSection": "(0..*)", + "assembly": "unknown", + "executableLibraryName": "unknown", + "assemblyVersion": "unknown", + "associatedArticle": "unknown", + "associatedMedia": "unknown", + "organizer": "unknown", + "attendee": "unknown", + "attendees": "unknown", + "audience": "unknown", + "audienceType": "(0..1)", + "audio": "unknown", + "author": "(0..1)", + "availability": "(0..1)", + "availabilityEnds": "(0..1)", + "availabilityStarts": "(0..1)", + "availableAtOrFrom": "(0..*)", + "availableChannel": "unknown", + "availableDeliveryMethod": "(0..*)", + "availableFrom": "unknown", + "availableLanguage": "unknown", + "availableThrough": "unknown", + "award": "unknown", + "awards": "unknown", + "baseSalary": "(0..1)", + "benefits": "unknown", + "jobBenefits": "unknown", + "bestRating": "(0..1)", + "billingAddress": "(0..1)", + "billingIncrement": "(0..1)", + "birthDate": "unknown", + "bitrate": "(0..1)", + "blogPost": "unknown", + "blogPosts": "(0..1)", + "bookEdition": "(0..1)", + "bookFormat": "(0..1)", + "borrower": "unknown", + "box": "unknown", + "branchOf": "(0..1)", + "parentOrganization": "(0..1)", + "branchCode": "unknown", + "brand": "(0..*)", + "breadcrumb": "unknown", + "broadcaster": "(0..1)", + "browserRequirements": "unknown", + "businessFunction": "(1..*)", + "buyer": "unknown", + "byArtist": "(0..1)", + "candidate": "unknown", + "caption": "(0..1)", + "carrier": "unknown", + "carrierRequirements": "(0..*)", + "catalog": "unknown", + "includedDataCatalog": "unknown", + "includedInDataCatalog": "unknown", + "category": "(0..*)", + "childMaxAge": "unknown", + "childMinAge": "unknown", + "children": "unknown", + "circle": "unknown", + "citation": "unknown", + "clipNumber": "unknown", + "closes": "(1..1)", + "codeRepository": "unknown", + "colleague": "unknown", + "colleagues": "unknown", + "collection": "unknown", + "targetCollection": "unknown", + "color": "(0..1)", + "comment": "unknown", + "commentText": "(0..1)", + "commentTime": "(0..1)", + "confirmationNumber": "unknown", + "contactOption": "unknown", + "contactPoint": "unknown", + "contactPoints": "unknown", + "contactType": "unknown", + "containedInPlace": "(0..1)", + "containsPlace": "(0..1)", + "containedIn": "(0..1)", + "contentLocation": "(0..1)", + "locationCreated": "(0..1)", + "contentRating": "unknown", + "contentSize": "unknown", + "contentUrl": "unknown", + "expectsAcceptanceOf": "unknown", + "contributor": "unknown", + "copyrightHolder": "(0..1)", + "copyrightYear": "(0..1)", + "countriesNotSupported": "unknown", + "countriesSupported": "unknown", + "course": "unknown", + "exerciseCourse": "unknown", + "countryOfOrigin": "(0..1)", + "creator": "(0..1)", + "currenciesAccepted": "(0..1)", + "customer": "unknown", + "dataset": "unknown", + "dateCreated": "(0..1)", + "dateline": "(0..1)", + "dateDeleted": "(0..1)", + "dateModified": "(0..1)", + "datePosted": "unknown", + "datePublished": "unknown", + "dayOfWeek": "(1..*)", + "deathDate": "unknown", + "deliveryAddress": "unknown", + "deliveryLeadTime": "(0..1)", + "deliveryMethod": "unknown", + "deliveryStatus": "unknown", + "department": "unknown", + "dependencies": "unknown", + "depth": "(0..1)", + "description": "(0..1)", + "device": "unknown", + "availableOnDevice": "unknown", + "director": "unknown", + "directors": "unknown", + "disambiguatingDescription": "unknown", + "discount": "unknown", + "discountCode": "unknown", + "discountCurrency": "(0..1)", + "discusses": "unknown", + "discussionUrl": "unknown", + "distance": "(0..1)", + "distribution": "unknown", + "doorTime": "(0..1)", + "downloadUrl": "unknown", + "duns": "(0..1)", + "duration": "(0..1)", + "durationOfWarranty": "(0..1)", + "editor": "unknown", + "educationalAlignment": "unknown", + "educationalFramework": "(0..1)", + "educationalRole": "unknown", + "educationalUse": "(0..1)", + "educationRequirements": "unknown", + "elevation": "(0..1)", + "eligibleCustomerType": "(0..*)", + "eligibleDuration": "(0..1)", + "eligibleQuantity": "(0..1)", + "eligibleRegion": "(0..*)", + "ineligibleRegion": "(0..*)", + "eligibleTransactionVolume": "(0..1)", + "email": "unknown", + "embedUrl": "unknown", + "employee": "unknown", + "employees": "unknown", + "employmentType": "unknown", + "encodesCreativeWork": "(0..1)", + "encoding": "unknown", + "encodingFormat": "unknown", + "encodings": "unknown", + "endDate": "(0..1)", + "endorsee": "unknown", + "endTime": "(0..1)", + "entertainmentBusiness": "unknown", + "episode": "unknown", + "episodeNumber": "unknown", + "episodes": "unknown", + "equal": "(0..*)", + "event": "unknown", + "events": "unknown", + "eventStatus": "unknown", + "exifData": "unknown", + "expectedArrivalFrom": "(0..1)", + "expectedArrivalUntil": "(0..1)", + "experienceRequirements": "unknown", + "expires": "unknown", + "familyName": "unknown", + "faxNumber": "(0..1)", + "featureList": "unknown", + "fileFormat": "unknown", + "fileSize": "unknown", + "followee": "unknown", + "follows": "(0..*)", + "founder": "unknown", + "founders": "unknown", + "dissolutionDate": "(0..1)", + "foundingDate": "(0..1)", + "free": "unknown", + "isAccessibleForFree": "(0..1)", + "fromLocation": "unknown", + "gender": "unknown", + "genre": "unknown", + "geo": "(0..1)", + "geographicArea": "(0..1)", + "givenName": "unknown", + "globalLocationNumber": "(0..1)", + "greater": "(0..*)", + "greaterOrEqual": "(0..*)", + "gtin12": "(0..1)", + "gtin13": "(0..*)", + "gtin14": "(0..*)", + "gtin8": "(0..*)", + "hasDeliveryMethod": "unknown", + "hasPOS": "(0..*)", + "headline": "unknown", + "height": "(0..1)", + "highPrice": "(0..1)", + "hiringOrganization": "unknown", + "homeLocation": "unknown", + "honorificPrefix": "unknown", + "honorificSuffix": "unknown", + "hoursAvailable": "(0..1)", + "illustrator": "(0..1)", + "image": "unknown", + "inAlbum": "(0..1)", + "incentives": "unknown", + "incentiveCompensation": "unknown", + "includesObject": "(0..*)", + "industry": "(0..1)", + "inLanguage": "(0..1)", + "inPlaylist": "(0..1)", + "installUrl": "unknown", + "instrument": "(0..1)", + "interactionCount": "unknown", + "interactivityType": "(0..1)", + "inventoryLevel": "(0..1)", + "isAccessoryOrSparePartFor": "(0..*)", + "isBasedOnUrl": "(0..1)", + "isBasedOn": "(0..1)", + "isbn": "(0..1)", + "isConsumableFor": "(0..*)", + "isFamilyFriendly": "(0..1)", + "isGift": "(0..1)", + "isicV4": "(0..*)", + "isPartOf": "(0..1)", + "isRelatedTo": "(0..1)", + "isSimilarTo": "(0..*)", + "issuedThrough": "(0..1)", + "isVariantOf": "(0..1)", + "itemCondition": "unknown", + "numberOfItems": "(0..1)", + "itemListOrder": "unknown", + "itemOffered": "(0..1)", + "itemReviewed": "(0..1)", + "itemShipped": "(0..*)", + "jobLocation": "unknown", + "jobTitle": "(0..1)", + "keywords": "unknown", + "knows": "(0..1)", + "landlord": "unknown", + "language": "unknown", + "lastReviewed": "unknown", + "latitude": "(0..1)", + "license": "unknown", + "learningResourceType": "(0..1)", + "legalName": "(0..1)", + "lender": "unknown", + "lesser": "(0..*)", + "lesserOrEqual": "(0..*)", + "line": "unknown", + "location": "(0..1)", + "logo": "unknown", + "longitude": "(0..1)", + "loser": "unknown", + "lowPrice": "(0..1)", + "mainContentOfPage": "unknown", + "mainEntity": "unknown", + "mainEntityOfPage": "unknown", + "makesOffer": "(0..*)", + "offeredBy": "unknown", + "hasMap": "unknown", + "map": "unknown", + "maps": "unknown", + "maxPrice": "(1..1)", + "maxValue": "(0..1)", + "member": "unknown", + "memberOf": "unknown", + "members": "unknown", + "memoryRequirements": "unknown", + "mentions": "unknown", + "menu": "unknown", + "merchant": "unknown", + "minPrice": "(1..1)", + "minValue": "(0..1)", + "model": "(0..1)", + "mpn": "(0..*)", + "manufacturer": "(0..1)", + "musicBy": "(0..1)", + "musicGroupMember": "unknown", + "naics": "(0..*)", + "name": "(0..1)", + "nationality": "unknown", + "netWorth": "(0..1)", + "nonEqual": "(0..*)", + "numberOfEmployees": "(0..1)", + "numberOfEpisodes": "(0..1)", + "numberOfPages": "(0..1)", + "numberOfSeasons": "(0..1)", + "numTracks": "(0..1)", + "object": "(0..1)", + "occupationalCategory": "unknown", + "offerCount": "(0..1)", + "offers": "(0..*)", + "openingHours": "(0..1)", + "openingHoursSpecification": "(0..*)", + "specialOpeningHoursSpecification": "(0..1)", + "opens": "(1..1)", + "operatingSystem": "unknown", + "opponent": "unknown", + "option": "unknown", + "actionOption": "unknown", + "orderDate": "unknown", + "orderedItem": "(0..1)", + "orderNumber": "(0..1)", + "orderStatus": "(0..1)", + "originAddress": "unknown", + "ownedFrom": "(0..1)", + "ownedThrough": "(0..1)", + "owns": "(0..*)", + "parent": "unknown", + "parents": "unknown", + "parentService": "unknown", + "participant": "unknown", + "partOfEpisode": "(0..1)", + "partOfInvoice": "(0..1)", + "partOfOrder": "(0..1)", + "partOfSeason": "(0..1)", + "partOfSeries": "(0..1)", + "partOfTVSeries": "(0..1)", + "paymentAccepted": "unknown", + "paymentDue": "(0..1)", + "paymentMethod": "(0..1)", + "paymentMethodId": "unknown", + "paymentUrl": "(0..1)", + "performer": "unknown", + "performerIn": "unknown", + "performers": "(0..1)", + "permissions": "(0..*)", + "permitAudience": "(0..1)", + "photo": "unknown", + "photos": "unknown", + "playerType": "unknown", + "polygon": "unknown", + "position": "(0..1)", + "postalCode": "(0..1)", + "postOfficeBoxNumber": "(0..1)", + "predecessorOf": "(0..*)", + "previousStartDate": "unknown", + "price": "(0..1)", + "priceRange": "(0..1)", + "priceSpecification": "(0..*)", + "priceType": "(0..1)", + "priceValidUntil": "(0..1)", + "primaryImageOfPage": "unknown", + "printColumn": "(0..1)", + "printEdition": "(0..1)", + "printPage": "unknown", + "printSection": "unknown", + "processingTime": "unknown", + "processorRequirements": "unknown", + "producer": "(0..1)", + "produces": "(0..1)", + "serviceOutput": "(0..1)", + "productID": "(0..1)", + "productionCompany": "(0..1)", + "productSupported": "(0..1)", + "proficiencyLevel": "unknown", + "programmingLanguage": "(0..1)", + "programmingModel": "unknown", + "providesService": "(0..1)", + "publication": "unknown", + "publishedOn": "unknown", + "publisher": "(0..1)", + "publishingPrinciples": "unknown", + "qualifications": "unknown", + "query": "unknown", + "question": "unknown", + "ratingCount": "(0..1)", + "ratingValue": "(0..1)", + "realEstateAgent": "unknown", + "recipient": "unknown", + "recordedAt": "(0..1)", + "recordedIn": "(0..1)", + "relatedLink": "unknown", + "relatedTo": "(0..1)", + "releaseDate": "(0..1)", + "releaseNotes": "unknown", + "replacee": "unknown", + "replacer": "unknown", + "replyToUrl": "(0..1)", + "representativeOfPage": "unknown", + "requiredGender": "unknown", + "requiredMaxAge": "unknown", + "requiredMinAge": "unknown", + "requirements": "unknown", + "softwareRequirements": "unknown", + "requiresSubscription": "unknown", + "responsibilities": "unknown", + "result": "(0..1)", + "resultComment": "unknown", + "resultReview": "unknown", + "review": "unknown", + "reviewBody": "(0..1)", + "reviewCount": "(0..1)", + "reviewedBy": "unknown", + "reviewRating": "(0..1)", + "reviews": "unknown", + "runtime": "unknown", + "runtimePlatform": "unknown", + "salaryCurrency": "(0..1)", + "sameAs": "unknown", + "sampleType": "unknown", + "codeSampleType": "unknown", + "scheduledTime": "(0..1)", + "screenCount": "(0..1)", + "videoFormat": "(0..1)", + "screenshot": "unknown", + "season": "unknown", + "containsSeason": "unknown", + "seasonNumber": "unknown", + "seasons": "unknown", + "seeks": "(0..*)", + "seller": "unknown", + "sender": "unknown", + "serialNumber": "(0..*)", + "servesCuisine": "(0..1)", + "serviceArea": "(0..1)", + "serviceAudience": "(0..1)", + "serviceLocation": "(0..1)", + "serviceOperator": "(0..1)", + "servicePhone": "(0..1)", + "servicePostalAddress": "(0..1)", + "serviceSmsNumber": "(0..1)", + "serviceType": "(0..1)", + "serviceUrl": "(0..1)", + "sibling": "unknown", + "siblings": "unknown", + "significantLink": "unknown", + "significantLinks": "(0..1)", + "skills": "unknown", + "sku": "(0..*)", + "softwareVersion": "unknown", + "sourceOrganization": "(0..1)", + "spatial": "(0..1)", + "spatialCoverage": "(0..*)", + "specialCommitments": "unknown", + "specialty": "unknown", + "sponsor": "unknown", + "funder": "unknown", + "sportsActivityLocation": "unknown", + "sportsEvent": "unknown", + "sportsTeam": "unknown", + "spouse": "(0..1)", + "startDate": "(0..1)", + "startTime": "(0..1)", + "storageRequirements": "unknown", + "streetAddress": "(0..1)", + "subEvent": "unknown", + "subEvents": "unknown", + "subOrganization": "unknown", + "subtitleLanguage": "unknown", + "successorOf": "(0..*)", + "suggestedGender": "(0..1)", + "suggestedMaxAge": "unknown", + "suggestedMinAge": "unknown", + "suitableForDiet": "unknown", + "superEvent": "unknown", + "supportingData": "unknown", + "targetDescription": "(0..1)", + "targetName": "(0..1)", + "targetPlatform": "unknown", + "targetProduct": "unknown", + "targetUrl": "(0..1)", + "taxID": "(0..1)", + "telephone": "(0..1)", + "temporalCoverage": "(0..1)", + "temporal": "(0..1)", + "datasetTimeInterval": "(0..1)", + "text": "(0..1)", + "thumbnail": "unknown", + "thumbnailUrl": "unknown", + "tickerSymbol": "(0..1)", + "timeRequired": "unknown", + "title": "(0..1)", + "toLocation": "unknown", + "trackingNumber": "unknown", + "trackingUrl": "unknown", + "tracks": "unknown", + "trailer": "(0..1)", + "transcript": "unknown", + "typeOfGood": "(1..1)", + "typicalAgeRange": "(0..1)", + "unitCode": "(1..1)", + "uploadDate": "unknown", + "url": "unknown", + "validFor": "(0..1)", + "validFrom": "(0..1)", + "validIn": "(0..1)", + "validThrough": "(0..1)", + "validUntil": "(0..1)", + "value": "(0..1)", + "valueAddedTaxIncluded": "(0..1)", + "valueReference": "(0..*)", + "vatID": "(0..1)", + "vendor": "unknown", + "version": "(0..1)", + "video": "unknown", + "videoFrameSize": "(0..1)", + "videoQuality": "(0..1)", + "warranty": "(0..*)", + "paymentDueDate": "(0..1)", + "warrantyPromise": "(0..*)", + "warrantyScope": "(0..1)", + "weight": "(0..1)", + "width": "(0..1)", + "winner": "unknown", + "wordCount": "(0..1)", + "workHours": "(0..1)", + "workLocation": "unknown", + "worksFor": "unknown", + "worstRating": "(0..1)", + "yearlyRevenue": "(0..1)", + "yearsInOperation": "(0..1)", + "reservationId": "unknown", + "reservationStatus": "(0..1)", + "reservationFor": "(0..1)", + "underName": "(0..1)", + "provider": "(0..1)", + "providerMobility": "unknown", + "bookingAgent": "unknown", + "bookingTime": "(0..1)", + "modifiedTime": "(0..1)", + "programMembershipUsed": "unknown", + "reservedTicket": "unknown", + "totalPrice": "(0..1)", + "priceCurrency": "(1..1)", + "membershipNumber": "unknown", + "programName": "(0..1)", + "hostingOrganization": "(0..1)", + "issuedBy": "(0..1)", + "dateIssued": "(0..1)", + "ticketedSeat": "(0..1)", + "ticketNumber": "(0..1)", + "ticketToken": "unknown", + "seatNumber": "(0..1)", + "seatRow": "(0..1)", + "seatSection": "(0..1)", + "seatingType": "(0..1)", + "subReservation": "(0..1)", + "boardingGroup": "(0..1)", + "passengerSequenceNumber": "(0..1)", + "securityScreening": "(0..1)", + "passengerPriorityStatus": "(0..1)", + "flightNumber": "(0..1)", + "departureTime": "(0..1)", + "arrivalTime": "(0..1)", + "departureAirport": "(0..1)", + "arrivalAirport": "(0..1)", + "departureGate": "unknown", + "arrivalGate": "unknown", + "boardingPolicy": "(0..1)", + "departureTerminal": "unknown", + "arrivalTerminal": "unknown", + "aircraft": "(0..1)", + "mealService": "unknown", + "estimatedFlightDuration": "(0..1)", + "flightDistance": "(0..1)", + "webCheckinTime": "(0..1)", + "iataCode": "unknown", + "icaoCode": "unknown", + "partySize": "unknown", + "trainNumber": "(0..1)", + "trainName": "(0..1)", + "departureStation": "(0..1)", + "arrivalStation": "(0..1)", + "departurePlatform": "(0..1)", + "arrivalPlatform": "(0..1)", + "busNumber": "(0..1)", + "busName": "(0..1)", + "departureBusStop": "(0..1)", + "arrivalBusStop": "(0..1)", + "pickupLocation": "unknown", + "dropoffLocation": "unknown", + "pickupTime": "unknown", + "dropoffTime": "unknown", + "checkinTime": "(0..1)", + "checkoutTime": "(0..1)", + "lodgingUnitType": "unknown", + "lodgingUnitDescription": "unknown", + "numAdults": "(0..1)", + "numChildren": "(0..1)", + "upvoteCount": "(0..1)", + "downvoteCount": "(0..1)", + "answerCount": "(0..1)", + "commentCount": "(0..1)", + "acceptedAnswer": "(0..1)", + "parentItem": "(0..1)", + "suggestedAnswer": "unknown", + "actionStatus": "unknown", + "error": "unknown", + "potentialAction": "unknown", + "actionPlatform": "(0..*)", + "target": "unknown", + "httpMethod": "unknown", + "encodingType": "(0..*)", + "contentType": "(0..*)", + "application": "unknown", + "actionApplication": "unknown", + "urlTemplate": "unknown", + "valueName": "unknown", + "valueRequired": "unknown", + "defaultValue": "(0..1)", + "readonlyValue": "unknown", + "multipleValues": "unknown", + "valueMinLength": "unknown", + "valueMaxLength": "unknown", + "valuePattern": "unknown", + "workPresented": "(0..1)", + "stepValue": "(0..1)", + "workPerformed": "unknown", + "workFeatured": "unknown", + "characterName": "(0..1)", + "namedPosition": "unknown", + "roleName": "unknown", + "hasPart": "unknown", + "issn": "(0..1)", + "issueNumber": "(0..1)", + "pageEnd": "(0..1)", + "pageStart": "(0..1)", + "pagination": "unknown", + "volumeNumber": "unknown", + "workExample": "unknown", + "exampleOfWork": "unknown", + "broker": "unknown", + "itemListElement": "unknown", + "item": "unknown", + "previousItem": "unknown", + "nextItem": "unknown", + "numberOfPlayers": "unknown", + "quest": "(0..1)", + "gameItem": "unknown", + "character": "unknown", + "characterAttribute": "unknown", + "playMode": "unknown", + "translator": "unknown", + "softwareAddOn": "unknown", + "cheatCode": "unknown", + "softwareHelp": "unknown", + "gameTip": "unknown", + "gamePlatform": "(0..1)", + "serverStatus": "unknown", + "playersOnline": "unknown", + "game": "unknown", + "gameServer": "(0..1)", + "gameLocation": "unknown", + "albumProductionType": "unknown", + "albumReleaseType": "(0..1)", + "albumRelease": "unknown", + "track": "unknown", + "musicArrangement": "unknown", + "composer": "(0..1)", + "firstPerformance": "(0..1)", + "includedComposition": "unknown", + "iswcCode": "(0..1)", + "lyricist": "(0..1)", + "musicCompositionForm": "(0..1)", + "musicalKey": "(0..1)", + "recordedAs": "unknown", + "isrcCode": "(0..1)", + "recordingOf": "(0..1)", + "catalogNumber": "(0..1)", + "creditedTo": "(0..1)", + "musicReleaseFormat": "unknown", + "recordLabel": "(0..1)", + "releaseOf": "(0..1)", + "regionsAllowed": "(0..1)", + "releasedEvent": "(0..1)", + "foundingLocation": "(0..1)", + "birthPlace": "(0..1)", + "deathPlace": "(0..1)", + "sport": "unknown", + "coach": "unknown", + "athlete": "unknown", + "numberedPosition": "unknown", + "homeTeam": "(0..1)", + "awayTeam": "(0..1)", + "competitor": "unknown", + "amount": "(0..1)", + "currency": "(0..1)", + "artform": "unknown", + "material": "unknown", + "artMedium": "(0..1)", + "surface": "unknown", + "artworkSurface": "(0..1)", + "artEdition": "(0..1)", + "totalPaymentDue": "(0..1)", + "minimumPaymentDue": "(0..1)", + "accountId": "(0..1)", + "scheduledPaymentDate": "(0..1)", + "billingPeriod": "(0..1)", + "paymentStatus": "(0..1)", + "referencesOrder": "(0..*)", + "additionalProperty": "unknown", + "unitText": "unknown", + "propertyID": "unknown", + "broadcastAffiliateOf": "(0..*)", + "broadcastDisplayName": "(0..1)", + "broadcastOfEvent": "(0..1)", + "broadcastTimezone": "(0..1)", + "isLiveBroadcast": "(0..1)", + "broadcastChannelId": "(0..1)", + "inBroadcastLineup": "(0..1)", + "broadcastServiceTier": "(0..1)", + "providesBroadcastService": "(0..1)", + "numberOfDoors": "(0..*)", + "numberOfAirbags": "(0..1)", + "numberOfAxles": "(0..*)", + "vehicleEngine": "unknown", + "fuelConsumption": "(0..1)", + "fuelEfficiency": "(0..1)", + "numberOfForwardGears": "(0..*)", + "vehicleIdentificationNumber": "(0..1)", + "cargoVolume": "(0..*)", + "vehicleConfiguration": "unknown", + "knownVehicleDamages": "unknown", + "dateVehicleFirstRegistered": "(0..1)", + "driveWheelConfiguration": "(0..1)", + "fuelType": "(0..1)", + "vehicleInteriorColor": "(0..1)", + "vehicleInteriorType": "(0..1)", + "mileageFromOdometer": "(0..*)", + "vehicleModelDate": "(0..1)", + "numberOfPreviousOwners": "(0..*)", + "productionDate": "(0..1)", + "purchaseDate": "(0..1)", + "vehicleSeatingCapacity": "(0..*)", + "vehicleTransmission": "(0..*)", + "steeringPosition": "(0..1)", + "vehicleSpecialUsage": "unknown", + "interactionService": "(0..1)", + "interactionStatistic": "(0..1)", + "interactionType": "(0..1)", + "userInteractionCount": "(0..1)", + "sharedContent": "unknown", + "coverageStartTime": "(0..1)", + "coverageEndTime": "(0..1)", + "liveBlogUpdate": "unknown", + "reportNumber": "(0..1)", + "lyrics": "(0..1)", + "calories": "(0..1)", + "carbohydrateContent": "(0..1)", + "cholesterolContent": "(0..1)", + "fiberContent": "(0..1)", + "proteinContent": "(0..1)", + "saturatedFatContent": "(0..1)", + "servingSize": "(0..1)", + "sodiumContent": "(0..1)", + "sugarContent": "(0..1)", + "totalTime": "(0..1)", + "cookTime": "(0..1)", + "cookingMethod": "(0..1)", + "fatContent": "(0..1)", + "foodEstablishment": "unknown", + "foodEvent": "unknown", + "nutrition": "unknown", + "prepTime": "(0..1)", + "recipeCategory": "(0..1)", + "recipeCuisine": "(0..1)", + "ingredients": "unknown", + "recipeIngredient": "unknown", + "recipeInstructions": "unknown", + "recipeYield": "(0..1)", + "recipe": "unknown", + "transFatContent": "(0..1)", + "unsaturatedFatContent": "(0..1)", + "dataFeedElement": "unknown", + "referenceQuantity": "(0..1)", + "leiCode": "unknown", + "annualPercentageRate": "(0..1)", + "feesAndCommissionsSpecification": "unknown", + "interestRate": "(0..1)", + "loanTerm": "(0..1)", + "requiredCollateral": "unknown", + "dateRead": "(0..1)", + "dateReceived": "(0..1)", + "dateSent": "(0..1)", + "messageAttachment": "unknown", + "priceComponent": "unknown", + "hasDigitalDocumentPermission": "unknown", + "grantee": "(0..1)", + "permissionType": "(0..1)", + "amenityFeature": "unknown", + "typeOfBed": "(0..1)", + "bed": "(0..1)", + "numberOfRooms": "(0..*)", + "floorSize": "(0..*)", + "occupancy": "(0..*)", + "permittedUsage": "unknown", + "petsAllowed": "unknown", + "smokingAllowed": "unknown", + "numberOfBeds": "(0..1)", + "starRating": "unknown" +} + +JSON +, $commandTester->getDisplay()); + } +} diff --git a/tests/Command/GenerateTypesCommandTest.php b/tests/Command/GenerateTypesCommandTest.php new file mode 100644 index 00000000..995399e0 --- /dev/null +++ b/tests/Command/GenerateTypesCommandTest.php @@ -0,0 +1,56 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace ApiPlatform\SchemaGenerator\Tests; + +use ApiPlatform\SchemaGenerator\Command\GenerateTypesCommand; +use Symfony\Component\Console\Tester\CommandTester; +use Symfony\Component\Filesystem\Filesystem; + +/** + * @author Kévin Dunglas + */ +class GenerateTypesCommandTest extends \PHPUnit_Framework_TestCase +{ + /** + * @var Filesystem + */ + private $fs; + + public function setUp() + { + $this->fs = new Filesystem(); + $this->fs->remove(__DIR__.'/../../build/'); + } + + /** + * @dataProvider getArguments + */ + public function testCommand($output, $config) + { + $this->fs->mkdir($output); + + $commandTester = new CommandTester(new GenerateTypesCommand()); + $this->assertEquals(0, $commandTester->execute(['output' => $output, 'config' => $config])); + } + + public function getArguments() + { + return [ + [__DIR__.'/../../build/address-book/', __DIR__.'/../config/address-book.yml'], + [__DIR__.'/../../build/blog/', __DIR__.'/../config/blog.yml'], + [__DIR__.'/../../build/ecommerce/', __DIR__.'/../config/ecommerce.yml'], + [__DIR__.'/../../build/vgo/', __DIR__.'/../config/vgo.yml'], + [__DIR__.'/../../build/mongodb/address-book/', __DIR__.'/../config/mongodb/address-book.yml'], + [__DIR__.'/../../build/mongodb/ecommerce/', __DIR__.'/../config/mongodb/ecommerce.yml'], + ]; + } +} diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 0cb69a0f..f95256b9 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -9,7 +9,7 @@ * file that was distributed with this source code. */ -namespace ApiPlatform\SchemaGenerator\tests; +namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\TypesGenerator; @@ -102,6 +102,9 @@ private function getGraphs() ]; } + /** + * @return array + */ private function getCardinalities() { return [ @@ -116,6 +119,9 @@ private function getCardinalities() ]; } + /** + * @return array + */ private function getConfig() { return [ @@ -172,6 +178,9 @@ private function getConfig() ]; } + /** + * @return array + */ private function getClasses() { return [ @@ -355,6 +364,8 @@ private function getClasses() } /** + * @param array $class + * * @return \Closure */ private function getContextMatcher(array $class) diff --git a/tests/run-tests.sh b/tests/run-tests.sh deleted file mode 100755 index 0d8456bd..00000000 --- a/tests/run-tests.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash -e - -# Test commands -bin/schema dump-configuration -bin/schema extract-cardinalities - -# Build models -rm -Rf build/ -mkdir -p build/address-book/ build/blog/ build/ecommerce/ build/vgo/ -bin/schema generate-types build/address-book/ tests/config/address-book.yml -bin/schema generate-types build/blog/ tests/config/blog.yml -bin/schema generate-types build/ecommerce/ tests/config/ecommerce.yml -bin/schema generate-types build/vgo/ tests/config/vgo.yml - -mkdir -p build/mongodb/ecommerce/ build/mongodb/address-book/ -bin/schema generate-types build/mongodb/address-book/ tests/config/mongodb/address-book.yml -bin/schema generate-types build/mongodb/ecommerce/ tests/config/mongodb/ecommerce.yml - -# Check code CS -vendor/bin/php-cs-fixer --dry-run --diff -vvv fix src/ - -# Check CS of generated models CS -vendor/bin/php-cs-fixer --dry-run --diff -vvv fix build/ From d58c0b503fa449739346307b730ba4ea2916c24f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 26 Sep 2016 23:20:13 +0200 Subject: [PATCH 062/258] Fix deprecation --- .travis.yml | 8 ++++++-- composer.json | 2 +- src/TypesGenerator.php | 2 +- 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8a42dffe..6e70c872 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,10 +13,14 @@ matrix: - php: '5.5' - php: '5.6' - php: '7.0' - - php: 'hhvm' + # Use the newer stack for HHVM as HHVM does not support Precise anymore since a long time and so Precise has an outdated version + - php: hhvm-3.12 + sudo: required + dist: trusty + group: edge before_install: - - if [ "$TRAVIS_PHP_VERSION" != "hhvm" ]; then phpenv config-rm xdebug.ini; fi; + - if [ "$TRAVIS_PHP_VERSION" != "hhvm-3.12" ]; then phpenv config-rm xdebug.ini; fi; - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; install: diff --git a/composer.json b/composer.json index 13c4632f..ed1cb61f 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "psr/log": "^1.0", "easyrdf/easyrdf": "^0.9", "league/html-to-markdown": "^4.0", - "friendsofphp/php-cs-fixer": "^1.0" + "friendsofphp/php-cs-fixer": "^1.12" }, "require-dev": { "doctrine/orm": "^2.2", diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 9443739d..51a2c101 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -13,7 +13,7 @@ use ApiPlatform\SchemaGenerator\AnnotationGenerator\AnnotationGeneratorInterface; use Psr\Log\LoggerInterface; -use Symfony\CS\Config\Config; +use Symfony\CS\Config; use Symfony\CS\ConfigurationResolver; use Symfony\CS\Fixer; From 85bd370a7dbc16317deef44c91c4a78f1a2bed49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 27 Sep 2016 21:17:58 +0200 Subject: [PATCH 063/258] Update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 7df8d046..40ca7a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.1.2 + +* Fix a bug when generating enumerations + +## 1.1.1 + +* Use the new PHP CS Fixer package + ## 1.1.0 * MongoDB support From 35f533ffb2982d85d913e0520f91087209c9856d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 22 Nov 2016 16:03:25 +0100 Subject: [PATCH 064/258] Minor tweaks and fixes * Use HTTPS everywhere (fix the generation) * Default config matching the one of the API Platform distribution * Respect the order of properties defined in the config file --- CHANGELOG.md | 8 ++++++ src/TypesGenerator.php | 36 ++++++++++++++++--------- src/TypesGeneratorConfiguration.php | 11 ++++---- templates/class.php.twig | 2 ++ tests/Command/DumpConfigurationTest.php | 11 ++++---- tests/config/vgo.yml | 9 ++++--- 6 files changed, 51 insertions(+), 26 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 40ca7a35..b1d4c989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 1.2.0 + +* The default config now match the Symfony's and API Platform's Best Practices (namespaces) +* The API Platform's annotation generator is enabled by default +* Use HTTPS to retrieve vocabularies by default +* Properties are generated in the order of the config file +* Properties and constants are separated by an empty line + ## 1.1.2 * Fix a bug when generating enumerations diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 51a2c101..b7daf555 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -30,30 +30,36 @@ class TypesGenerator * @see https://github.com/myclabs/php-enum Used enum implementation */ const ENUM_USE = 'MyCLabs\Enum\Enum'; + /** * @var string * * @see https://github.com/doctrine/collections */ const DOCTRINE_COLLECTION_USE = 'Doctrine\Common\Collections\ArrayCollection'; + /** * @var string * * @see https://github.com/myclabs/php-enum Used enum implementation */ const ENUM_EXTENDS = 'Enum'; + /** * @var string */ const SCHEMA_ORG_NAMESPACE = 'http://schema.org/'; + /** * @var string */ const SCHEMA_ORG_ENUMERATION = 'http://schema.org/Enumeration'; + /** * @var string */ const SCHEMA_ORG_DOMAIN = 'schema:domainIncludes'; + /** * @var string */ @@ -147,7 +153,7 @@ public function generate(array $config) } if ($resource) { - $typesToGenerate[] = $resource; + $typesToGenerate[$typeName] = $resource; } else { $this->logger->warning('Type "{typeName}" cannot be found. Using "{guessFrom}" type to generate entity.', ['typeName' => $typeName, 'guessFrom' => $typeConfig['guessFrom']]); $type = $graph->resource($typeConfig['vocabularyNamespace'].$typeConfig['guessFrom'], 'rdfs:Class'); @@ -226,19 +232,25 @@ public function generate(array $config) } // Fields - foreach ($propertiesMap[$type->getUri()] as $property) { - // Ignore properties not set if using a config file - if ($typeConfig['allProperties'] || (is_array($typeConfig['properties']) && array_key_exists($property->localName(), $typeConfig['properties']))) { - $class = $this->generateField($config, $class, $type, $typeName, $property->localName(), $property); - } - } + if (!$typeConfig['allProperties'] && isset($typeConfig['properties']) && is_array($typeConfig['properties'])) { + foreach ($typeConfig['properties'] as $key => $value) { + foreach ($propertiesMap[$type->getUri()] as $property) { + if ($key !== $property->localName()) { + continue; + } - // Add custom fields (non schema.org) - if (isset($typeConfig['properties']) && is_array($typeConfig['properties'])) { - foreach (array_diff_key($typeConfig['properties'], $class['fields']) as $propertyName => $property) { - $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->localName())); + $class = $this->generateField($config, $class, $type, $typeName, $property->localName(), $property); + continue 2; + } - $class = $this->generateField($config, $class, $type, $typeName, $propertyName); + // Add custom fields (non schema.org) + $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $key, $type->localName())); + $class = $this->generateField($config, $class, $type, $typeName, $key); + } + } else { + // All properties + foreach ($propertiesMap[$type->getUri()] as $property) { + $class = $this->generateField($config, $class, $type, $typeName, $property->localName(), $property); } } diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 976e42d6..d7fd1a42 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -21,8 +21,8 @@ */ class TypesGeneratorConfiguration implements ConfigurationInterface { - const SCHEMA_ORG_RDFA_URL = 'http://schema.org/docs/schema_org_rdfa.html'; - const GOOD_RELATIONS_OWL_URL = 'http://purl.org/goodrelations/v1.owl'; + const SCHEMA_ORG_RDFA_URL = 'https://schema.org/docs/schema_org_rdfa.html'; + const GOOD_RELATIONS_OWL_URL = 'https://purl.org/goodrelations/v1.owl'; /** * {@inheritdoc} @@ -70,9 +70,9 @@ function ($rdfa) { ->addDefaultsIfNotSet() ->info('PHP namespaces') ->children() - ->scalarNode('entity')->defaultValue('SchemaOrg\Entity')->info('The namespace of the generated entities')->example('Acme\Entity')->end() - ->scalarNode('enum')->defaultValue('SchemaOrg\Enum')->info('The namespace of the generated enumerations')->example('Acme\Enum')->end() - ->scalarNode('interface')->defaultValue('SchemaOrg\Model')->info('The namespace of the generated interfaces')->example('Acme\Model')->end() + ->scalarNode('entity')->defaultValue('AppBundle\Entity')->info('The namespace of the generated entities')->example('Acme\Entity')->end() + ->scalarNode('enum')->defaultValue('AppBundle\Enum')->info('The namespace of the generated enumerations')->example('Acme\Enum')->end() + ->scalarNode('interface')->defaultValue('AppBundle\Model')->info('The namespace of the generated interfaces')->example('Acme\Model')->end() ->end() ->end() ->arrayNode('doctrine') @@ -161,6 +161,7 @@ function ($rdfa) { 'ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator', 'ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator', 'ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator', + 'ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator', ]) ->prototype('scalar')->end() ->end() diff --git a/templates/class.php.twig b/templates/class.php.twig index d3cd6887..a7cfa8ec 100644 --- a/templates/class.php.twig +++ b/templates/class.php.twig @@ -29,6 +29,7 @@ use {{ use }}; {% endfor %} */ const {{ constant.name }} = '{{ constant.value }}'; + {% endfor %} {% for field in class.fields %} @@ -38,6 +39,7 @@ use {{ use }}; {% endfor %} */ {{ config.fieldVisibility }} ${{ field.name }}{% if field.isArray and (field.isEnum or not field.typeHint or not config.doctrine.useCollection) %} = []{% endif %}; + {% endfor %} {% if config.doctrine.useCollection and class.hasConstructor %} diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index e8b1c321..b32bd8ee 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -30,7 +30,7 @@ public function testDumpConfiguration() rdfa: # RDFa URI to use - uri: 'http://schema.org/docs/schema_org_rdfa.html' # Example: http://schema.org/docs/schema_org_rdfa.html + uri: 'https://schema.org/docs/schema_org_rdfa.html' # Example: https://schema.org/docs/schema_org_rdfa.html # RDFa URI data format format: null # Example: rdfxml @@ -39,7 +39,7 @@ public function testDumpConfiguration() relations: # Default: - - http://purl.org/goodrelations/v1.owl + - https://purl.org/goodrelations/v1.owl # Debug mode debug: false @@ -60,13 +60,13 @@ public function testDumpConfiguration() namespaces: # The namespace of the generated entities - entity: SchemaOrg\Entity # Example: Acme\Entity + entity: AppBundle\Entity # Example: Acme\Entity # The namespace of the generated enumerations - enum: SchemaOrg\Enum # Example: Acme\Enum + enum: AppBundle\Enum # Example: Acme\Enum # The namespace of the generated interfaces - interface: SchemaOrg\Model # Example: Acme\Model + interface: AppBundle\Model # Example: Acme\Model # Doctrine doctrine: @@ -158,6 +158,7 @@ interface: null - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator + - ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator YAML diff --git a/tests/config/vgo.yml b/tests/config/vgo.yml index 2205d139..ec2d1dc7 100644 --- a/tests/config/vgo.yml +++ b/tests/config/vgo.yml @@ -1,18 +1,19 @@ - annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator + namespaces: entity: 'AppBundle\Entity' + types: Session: vocabularyNamespace: http://purl.org/net/VideoGameOntology# Thing: ~ + debug: true + rdfa: - - - uri: tests/data/vgo.rdf - format: ~ + - tests/data/vgo.rdf - tests/data/schema.rdfa From a7da023b984e5dc79caa1c93fd8acf1ca3871721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 26 Nov 2016 10:32:01 +0100 Subject: [PATCH 065/258] Fix links in README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 0e0713e6..7e7957f1 100644 --- a/README.md +++ b/README.md @@ -61,8 +61,9 @@ It opens the way to generic web API clients able to extract and process data fro ## Documentation -* [Getting Started](https://api-platform.com/doc/1.0/schema-generator/getting-started) -* [Configuration](https://api-platform.com/doc/1.0/schema-generator/configuration) +* [Introduction](https://api-platform.com/docs/schema-generator/) +* [Getting Started](https://api-platform.com/docs/schema-generator/getting-started) +* [Configuration](https://api-platform.com/docs/schema-generator/configuration) ## Credits From 4099d1b20a4cbe2febdba59b66357e6203b911bb Mon Sep 17 00:00:00 2001 From: Patrick Yi Date: Thu, 23 Mar 2017 10:11:05 -0700 Subject: [PATCH 066/258] Fix where cardinality (0..*) doesn't create an array field. --- src/TypesGenerator.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index b7daf555..37e141fd 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -610,6 +610,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t $ormColumn = isset($propertyConfig['ormColumn']) ? $propertyConfig['ormColumn'] : null; $isArray = in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_0_N, CardinalitiesExtractor::CARDINALITY_1_N, CardinalitiesExtractor::CARDINALITY_N_N, ]); From 6828292f64e28ed0a895c3be1978b65df3e10830 Mon Sep 17 00:00:00 2001 From: Pierre du Plessis Date: Sun, 16 Apr 2017 18:54:23 +0200 Subject: [PATCH 067/258] Support Twig 2 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index ed1cb61f..195d4e7a 100644 --- a/composer.json +++ b/composer.json @@ -23,7 +23,7 @@ "symfony/console": "^2.7 || ^3.0", "symfony/yaml": "^2.7 || ^3.0", "symfony/config": "^2.7 || ^3.0", - "twig/twig": "^1.0", + "twig/twig": "^1.0 || ^2.0", "psr/log": "^1.0", "easyrdf/easyrdf": "^0.9", "league/html-to-markdown": "^4.0", From caacdea9ae6d2dd46a5da0ba6faecbd74be1dff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 18 Aug 2017 14:33:49 +0200 Subject: [PATCH 068/258] Fix tests --- .travis.yml | 17 +++---- src/TypesGenerator.php | 4 +- ...ApiPlatformCoreAnnotationGeneratorTest.php | 3 +- tests/Command/DumpConfigurationTest.php | 18 +++++--- .../ExtractCardinalitiesCommandTest.php | 44 ++++++++++++++++--- tests/Command/GenerateTypesCommandTest.php | 3 +- tests/TypesGeneratorTest.php | 12 ++--- 7 files changed, 65 insertions(+), 36 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6e70c872..b28ec770 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,22 +13,19 @@ matrix: - php: '5.5' - php: '5.6' - php: '7.0' - # Use the newer stack for HHVM as HHVM does not support Precise anymore since a long time and so Precise has an outdated version - - php: hhvm-3.12 - sudo: required - dist: trusty - group: edge + - php: '7.1' before_install: - - if [ "$TRAVIS_PHP_VERSION" != "hhvm-3.12" ]; then phpenv config-rm xdebug.ini; fi; - - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; + - phpenv config-rm xdebug.ini + - wget https://phar.phpunit.de/phpunit-6.3.phar + - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; install: - composer update --no-interaction --prefer-dist - - if [ "$TRAVIS_PHP_VERSION" = "5.6" ]; then php box.phar build; fi; + - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then php box.phar build; fi; script: - - phpunit + - php phpunit-6.3.phar deploy: provider: releases @@ -39,4 +36,4 @@ deploy: on: tags: true repo: api-platform/schema-generator - php: '5.6' + php: '7.1' diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 37e141fd..0c02319b 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -104,7 +104,7 @@ class TypesGenerator */ public function __construct(\Twig_Environment $twig, LoggerInterface $logger, array $graphs, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge) { - if (empty($graphs)) { + if (!$graphs) { throw new \InvalidArgumentException('At least one graph must be injected.'); } @@ -648,7 +648,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t if ($isArray) { $class['hasConstructor'] = true; - if ($config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { + if (isset($config['doctrine']['useCollection']) && $config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { $class['uses'][] = self::DOCTRINE_COLLECTION_USE; } } diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index 57f0e393..f13e2a14 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -13,12 +13,13 @@ use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; use ApiPlatform\SchemaGenerator\TypesGenerator; +use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; /** * @author Kévin Dunglas */ -class ApiPlatformCoreAnnotationGeneratorTest extends \PHPUnit_Framework_TestCase +class ApiPlatformCoreAnnotationGeneratorTest extends TestCase { /** * @var ApiPlatformCoreAnnotationGenerator diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index b32bd8ee..c38562e1 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -12,12 +12,13 @@ namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\Command\DumpConfigurationCommand; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; /** * @author Kévin Dunglas */ -class DumpConfigurationTest extends \PHPUnit_Framework_TestCase +class DumpConfigurationTest extends TestCase { public function testDumpConfiguration() { @@ -29,11 +30,14 @@ public function testDumpConfiguration() # RDFa files rdfa: - # RDFa URI to use - uri: 'https://schema.org/docs/schema_org_rdfa.html' # Example: https://schema.org/docs/schema_org_rdfa.html + # Prototype + - + + # RDFa URI to use + uri: 'https://schema.org/docs/schema_org_rdfa.html' # Example: https://schema.org/docs/schema_org_rdfa.html - # RDFa URI data format - format: null # Example: rdfxml + # RDFa URI data format + format: null # Example: rdfxml # OWL relation files to use relations: @@ -51,7 +55,7 @@ public function testDumpConfiguration() useInterface: false # Emit a warning if a property is not derived from GoodRelations - checkIsGoodRelations: false + checkIsGoodRelations: false # A license or any text to use as header of generated files header: false # Example: // (c) Kévin Dunglas @@ -75,7 +79,7 @@ interface: AppBundle\Model # Example: Acme\Model useCollection: true # The Resolve Target Entity Listener config file pass - resolveTargetEntityConfigPath: null + resolveTargetEntityConfigPath: null # The value of the phpDoc's @author annotation author: false # Example: Kévin Dunglas diff --git a/tests/Command/ExtractCardinalitiesCommandTest.php b/tests/Command/ExtractCardinalitiesCommandTest.php index ccb565b2..16817632 100644 --- a/tests/Command/ExtractCardinalitiesCommandTest.php +++ b/tests/Command/ExtractCardinalitiesCommandTest.php @@ -12,23 +12,26 @@ namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\Command\ExtractCardinalitiesCommand; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; /** * @author Kévin Dunglas */ -class ExtractCardinalitiesCommandTest extends \PHPUnit_Framework_TestCase +class ExtractCardinalitiesCommandTest extends TestCase { public function testExtractCardinalities() { $commandTester = new CommandTester(new ExtractCardinalitiesCommand()); $this->assertEquals(0, $commandTester->execute([])); + $this->assertEquals(<<<'JSON' { "geoRadius": "unknown", "geoMidpoint": "unknown", "hasOfferCatalog": "unknown", "mapType": "unknown", + "touristType": "(0..*)", "orderQuantity": "(0..1)", "orderItemStatus": "(0..1)", "orderItemNumber": "(0..1)", @@ -101,6 +104,7 @@ public function testExtractCardinalities() "award": "unknown", "awards": "unknown", "baseSalary": "(0..1)", + "bccRecipient": "unknown", "benefits": "unknown", "jobBenefits": "unknown", "bestRating": "(0..1)", @@ -132,6 +136,7 @@ public function testExtractCardinalities() "includedDataCatalog": "unknown", "includedInDataCatalog": "unknown", "category": "(0..*)", + "ccRecipient": "unknown", "childMaxAge": "unknown", "childMinAge": "unknown", "children": "unknown", @@ -175,7 +180,7 @@ public function testExtractCardinalities() "customer": "unknown", "dataset": "unknown", "dateCreated": "(0..1)", - "dateline": "(0..1)", + "dateline": "unknown", "dateDeleted": "(0..1)", "dateModified": "(0..1)", "datePosted": "unknown", @@ -258,6 +263,7 @@ public function testExtractCardinalities() "foundingDate": "(0..1)", "free": "unknown", "isAccessibleForFree": "(0..1)", + "publicAccess": "unknown", "fromLocation": "unknown", "gender": "unknown", "genre": "unknown", @@ -342,6 +348,8 @@ public function testExtractCardinalities() "hasMap": "unknown", "map": "unknown", "maps": "unknown", + "maximumAttendeeCapacity": "(0..1)", + "remainingAttendeeCapacity": "(0..1)", "maxPrice": "(1..1)", "maxValue": "(0..1)", "member": "unknown", @@ -349,6 +357,7 @@ public function testExtractCardinalities() "members": "unknown", "memoryRequirements": "unknown", "mentions": "unknown", + "hasMenu": "unknown", "menu": "unknown", "merchant": "unknown", "minPrice": "(1..1)", @@ -442,7 +451,7 @@ public function testExtractCardinalities() "publication": "unknown", "publishedOn": "unknown", "publisher": "(0..1)", - "publishingPrinciples": "unknown", + "publishingPrinciples": "(0..1)", "qualifications": "unknown", "query": "unknown", "question": "unknown", @@ -554,6 +563,7 @@ public function testExtractCardinalities() "timeRequired": "unknown", "title": "(0..1)", "toLocation": "unknown", + "toRecipient": "unknown", "trackingNumber": "unknown", "trackingUrl": "unknown", "tracks": "unknown", @@ -827,14 +837,12 @@ public function testExtractCardinalities() "servingSize": "(0..1)", "sodiumContent": "(0..1)", "sugarContent": "(0..1)", - "totalTime": "(0..1)", "cookTime": "(0..1)", "cookingMethod": "(0..1)", "fatContent": "(0..1)", "foodEstablishment": "unknown", "foodEvent": "unknown", "nutrition": "unknown", - "prepTime": "(0..1)", "recipeCategory": "(0..1)", "recipeCuisine": "(0..1)", "ingredients": "unknown", @@ -870,7 +878,31 @@ public function testExtractCardinalities() "petsAllowed": "unknown", "smokingAllowed": "unknown", "numberOfBeds": "(0..1)", - "starRating": "unknown" + "starRating": "unknown", + "estimatedCost": "(0..1)", + "performTime": "(0..1)", + "prepTime": "(0..1)", + "supply": "unknown", + "steps": "(0..1)", + "tool": "unknown", + "totalTime": "(0..1)", + "yield": "(0..1)", + "afterMedia": "unknown", + "beforeMedia": "unknown", + "duringMedia": "unknown", + "requiredQuantity": "(0..*)", + "courseCode": "(0..1)", + "coursePrerequisites": "unknown", + "hasCourseInstance": "unknown", + "courseMode": "(0..1)", + "instructor": "unknown", + "identifier": "(0..1)", + "claimReviewed": "unknown", + "hasMenuItem": "unknown", + "hasMenuSection": "unknown", + "accessMode": "(0..1)", + "accessModeSufficient": "unknown", + "accessibilitySummary": "unknown" } JSON diff --git a/tests/Command/GenerateTypesCommandTest.php b/tests/Command/GenerateTypesCommandTest.php index 995399e0..e62ea2f8 100644 --- a/tests/Command/GenerateTypesCommandTest.php +++ b/tests/Command/GenerateTypesCommandTest.php @@ -12,13 +12,14 @@ namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\Command\GenerateTypesCommand; +use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Tester\CommandTester; use Symfony\Component\Filesystem\Filesystem; /** * @author Kévin Dunglas */ -class GenerateTypesCommandTest extends \PHPUnit_Framework_TestCase +class GenerateTypesCommandTest extends TestCase { /** * @var Filesystem diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index f95256b9..14225375 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -13,19 +13,19 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\TypesGenerator; +use PHPUnit\Framework\TestCase; use Prophecy\Argument; use Psr\Log\NullLogger; /** * @author Teoh Han Hui */ -class TypesGeneratorTest extends \PHPUnit_Framework_TestCase +class TypesGeneratorTest extends TestCase { public function testGenerate() { $twigProphecy = $this->prophesize('Twig_Environment'); - $classes = $this->getClasses(); - foreach ($classes as $class) { + foreach ($this->getClasses() as $class) { $twigProphecy->render('class.php.twig', Argument::that($this->getContextMatcher($class)))->willReturn()->shouldBeCalled(); } $twigProphecy->render('class.php.twig', Argument::type('array'))->willReturn(); @@ -390,12 +390,6 @@ private function getContextMatcher(array $class) return false; } - foreach ($class['fields'] as $fieldName => $field) { - if ($field != array_intersect_key($context['class']['fields'][$fieldName], $field)) { - return false; - } - } - return true; }; } From 37a7f57182fa57acabcbde615b54250560bb3f2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 18 Aug 2017 15:08:58 +0200 Subject: [PATCH 069/258] Bump minimum PHP version to 7 --- .travis.yml | 3 --- composer.json | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index b28ec770..e3073ca9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,9 +9,6 @@ cache: matrix: fast_finish: true include: - - php: '5.4' - - php: '5.5' - - php: '5.6' - php: '7.0' - php: '7.1' diff --git a/composer.json b/composer.json index 195d4e7a..be596512 100644 --- a/composer.json +++ b/composer.json @@ -18,7 +18,7 @@ "psr-4": { "ApiPlatform\\SchemaGenerator\\Tests\\": "tests/" } }, "require": { - "php": ">=5.4", + "php": ">=7.0", "ext-json": "*", "symfony/console": "^2.7 || ^3.0", "symfony/yaml": "^2.7 || ^3.0", From 55098a210600d73fe433b1478169f9a77860e34f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 18 Aug 2017 14:36:13 +0200 Subject: [PATCH 070/258] Allow Symfony 4 components --- composer.json | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/composer.json b/composer.json index be596512..ad565b26 100644 --- a/composer.json +++ b/composer.json @@ -20,9 +20,9 @@ "require": { "php": ">=7.0", "ext-json": "*", - "symfony/console": "^2.7 || ^3.0", - "symfony/yaml": "^2.7 || ^3.0", - "symfony/config": "^2.7 || ^3.0", + "symfony/console": "^2.7 || ^3.0 || ^4.0", + "symfony/yaml": "^2.7 || ^3.0 || ^4.0", + "symfony/config": "^2.7 || ^3.0 || ^4.0", "twig/twig": "^1.0 || ^2.0", "psr/log": "^1.0", "easyrdf/easyrdf": "^0.9", @@ -31,8 +31,8 @@ }, "require-dev": { "doctrine/orm": "^2.2", - "symfony/validator": "^2.7", - "symfony/filesystem": "^2.7" + "symfony/validator": "^2.7 || ^3.0 || ^4.0", + "symfony/filesystem": "^2.7 || ^3.0 || ^4.0" }, "suggest": { "myclabs/php-enum": "For enumerations", From a03354b7dc7077af1d0b957e591852bca254da1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 19 Aug 2017 18:53:33 +0200 Subject: [PATCH 071/258] Use PHP CS Fixer 2 --- composer.json | 2 +- src/Command/ExtractCardinalitiesCommand.php | 2 +- src/TypesGenerator.php | 55 +++++++++++---------- 3 files changed, 32 insertions(+), 27 deletions(-) diff --git a/composer.json b/composer.json index ad565b26..ddd50c4c 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "psr/log": "^1.0", "easyrdf/easyrdf": "^0.9", "league/html-to-markdown": "^4.0", - "friendsofphp/php-cs-fixer": "^1.12" + "friendsofphp/php-cs-fixer": "^2.4" }, "require-dev": { "doctrine/orm": "^2.2", diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 44c6429b..0990be99 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -19,7 +19,7 @@ use Symfony\Component\Console\Output\OutputInterface; /** - * Extract cardinality command. + * Extracts cardinalities. * * @author Kévin Dunglas */ diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 0c02319b..e55781b3 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -12,10 +12,14 @@ namespace ApiPlatform\SchemaGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\AnnotationGeneratorInterface; +use PhpCsFixer\Cache\NullCacheManager; +use PhpCsFixer\Differ\NullDiffer; +use PhpCsFixer\Error\ErrorsManager; +use PhpCsFixer\FixerFactory; +use PhpCsFixer\Linter\Linter; +use PhpCsFixer\RuleSet; +use PhpCsFixer\Runner\Runner; use Psr\Log\LoggerInterface; -use Symfony\CS\Config; -use Symfony\CS\ConfigurationResolver; -use Symfony\CS\Fixer; /** * Entities generator. @@ -874,30 +878,31 @@ private function namespaceToDir($config, $namespace) */ private function fixCs(array $files) { - $config = new Config(); - $fixer = new Fixer(); - $fixer->registerBuiltInConfigs(); - $fixer->registerBuiltInFixers(); - - $resolver = new ConfigurationResolver(); - $resolver - ->setAllFixers($fixer->getFixers()) - ->setConfig($config) - ->setOptions([ - 'level' => 'symfony', - 'fixers' => null, - 'progress' => false, - ]) - ->resolve(); - - $config->fixers($resolver->getFixers()); - - $finder = []; + $fileInfos = []; foreach ($files as $file) { - $finder[] = new \SplFileInfo($file); + $fileInfos[] = new \SplFileInfo($file); } - $config->finder(new \ArrayIterator($finder)); - $fixer->fix($config); + $fixers = (new FixerFactory()) + ->registerBuiltInFixers() + ->useRuleSet(new RuleSet([ + '@Symfony' => true, + 'array_syntax' => ['syntax' => 'short'], + 'phpdoc_order' => true, + 'declare_strict_types' => true, + ])) + ->getFixers(); + + $runner = new Runner( + new \ArrayIterator($fileInfos), + $fixers, + new NullDiffer(), + null, + new ErrorsManager(), + new Linter(), + false, + new NullCacheManager() + ); + $runner->fix(); } } From 9fbf15fed2372af68dd539f3a0567d5f690c0a57 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sun, 20 Aug 2017 22:04:20 +0200 Subject: [PATCH 072/258] Add typehints and use strict types --- .editorconfig | 71 +++++++++ .php_cs.dist | 61 +++++++ .travis.yml | 54 ++++--- composer.json | 6 +- .../AbstractAnnotationGenerator.php | 44 +++--- .../AnnotationGeneratorInterface.php | 76 ++------- .../ApiPlatformCoreAnnotationGenerator.php | 10 +- .../ConstraintAnnotationGenerator.php | 17 +- .../DoctrineMongoDBAnnotationGenerator.php | 31 ++-- .../DoctrineOrmAnnotationGenerator.php | 31 +--- .../DunglasApiAnnotationGenerator.php | 10 +- .../PhpDocAnnotationGenerator.php | 76 +++------ .../SerializerGroupsAnnotationGenerator.php | 8 +- src/CardinalitiesExtractor.php | 12 +- src/Command/DumpConfigurationCommand.php | 6 +- src/Command/ExtractCardinalitiesCommand.php | 6 +- src/Command/GenerateTypesCommand.php | 6 +- src/GoodRelationsBridge.php | 31 +--- src/TypesGenerator.php | 149 +++++------------- src/TypesGeneratorConfiguration.php | 4 +- templates/class.php.twig | 2 + templates/interface.php.twig | 2 + ...ApiPlatformCoreAnnotationGeneratorTest.php | 2 + tests/Command/DumpConfigurationTest.php | 2 + .../ExtractCardinalitiesCommandTest.php | 2 + tests/Command/GenerateTypesCommandTest.php | 2 + tests/TypesGeneratorTest.php | 39 ++--- tests/bootstrap.php | 2 + 28 files changed, 365 insertions(+), 397 deletions(-) create mode 100644 .editorconfig create mode 100644 .php_cs.dist diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..8f16257d --- /dev/null +++ b/.editorconfig @@ -0,0 +1,71 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + +[*] +# Change these settings to your own preference +indent_style = space +indent_size = 4 + +# We recommend you to keep these unchanged +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true + +[*.feature] +indent_style = space +indent_size = 2 + +[*.json] +indent_style = space +indent_size = 2 + +[*.md] +trim_trailing_whitespace = false + +[*.php] +indent_style = space +indent_size = 4 + +[*.xml] +indent_style = space +indent_size = 4 + +[*.yml] +indent_style = space +indent_size = 4 +trim_trailing_whitespace = false + +[.gitmodules] +indent_style = tab + +[.php_cs] +indent_style = space +indent_size = 4 + +[.styleci.yml] +indent_style = space +indent_size = 2 + +[.travis.yml] +indent_style = space +indent_size = 2 + +[appveyor.yml] +indent_style = space +indent_size = 2 + +[behat.yml] +indent_style = space +indent_size = 2 + +[composer.json] +indent_style = space +indent_size = 4 + +[phpunit.xml.dist] +indent_style = space +indent_size = 4 diff --git a/.php_cs.dist b/.php_cs.dist new file mode 100644 index 00000000..cb721540 --- /dev/null +++ b/.php_cs.dist @@ -0,0 +1,61 @@ + + +For the full copyright and license information, please view the LICENSE +file that was distributed with this source code. +HEADER; + +$finder = PhpCsFixer\Finder::create() + ->in(__DIR__) + ->exclude('tests/Fixtures/app/cache') +; + +return PhpCsFixer\Config::create() + ->setRiskyAllowed(true) + ->setRules([ + '@Symfony' => true, + '@Symfony:risky' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'braces' => [ + 'allow_single_line_closure' => true, + ], + 'declare_strict_types' => true, + 'header_comment' => [ + 'header' => $header, + 'location' => 'after_open', + ], + 'modernize_types_casting' => true, + // 'native_function_invocation' => true, + 'no_extra_consecutive_blank_lines' => [ + 'break', + 'continue', + 'curly_brace_block', + 'extra', + 'parenthesis_brace_block', + 'return', + 'square_brace_block', + 'throw', + 'use', + ], + 'no_unreachable_default_argument_value' => true, + 'no_useless_else' => true, + 'no_useless_return' => true, + 'ordered_imports' => true, + // 'phpdoc_add_missing_param_annotation' => [ + // 'only_untyped' => false, + // ], + 'phpdoc_order' => true, + 'psr4' => true, + 'semicolon_after_instruction' => true, + 'strict_comparison' => true, + 'strict_param' => true, + 'ternary_to_null_coalescing' => true, + ]) + ->setFinder($finder) +; diff --git a/.travis.yml b/.travis.yml index e3073ca9..de85782b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,34 +3,46 @@ language: php sudo: false cache: - directories: - - $HOME/.composer/cache + directories: + - $HOME/.composer/cache matrix: - fast_finish: true - include: - - php: '7.0' - - php: '7.1' + include: + - php: '7.1' + env: coverage=1 lint=1 + - php: '7.1' + env: deps='low' before_install: - - phpenv config-rm xdebug.ini - - wget https://phar.phpunit.de/phpunit-6.3.phar - - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; + - phpenv config-rm xdebug.ini || echo "xdebug not available" + - echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - wget https://phar.phpunit.de/phpunit-6.3.phar + - if [[ $coverage = 1 ]]; then mkdir -p build/logs; fi + - if [[ $coverage = 1 ]]; then wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar; fi + - if [[ $lint = 1 ]]; then wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.4.0/php-cs-fixer.phar; fi + - if [[ $TRAVIS_PHP_VERSION = "7.1" ]]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; install: - - composer update --no-interaction --prefer-dist - - if [ "$TRAVIS_PHP_VERSION" = "7.1" ]; then php box.phar build; fi; + - if [[ $coverage = 1 ]]; then composer require --dev --no-update 'phpunit/php-code-coverage:^4.0.1'; fi + - if [[ ! $deps ]]; then composer update --prefer-dist --no-progress --no-suggest --ansi; fi + - if [[ $deps = 'low' ]]; then composer update --prefer-dist --no-progress --no-suggest --prefer-stable --prefer-lowest --ansi; fi script: - - php phpunit-6.3.phar + - if [[ $coverage = 1 ]]; then phpdbg -qrr php phpunit-6.3.phar --coverage-closer build/logs/clover.xml; else php phpunit-6.3.phar; fi + - if [[ $lint = 1 ]]; then php php-cs-fixer.phar fix --dry-run --diff --no-ansi; fi + - if [[ ! $deps && $TRAVIS_PHP_VERSION = "7.1" ]]; then php box.phar build; fi; + +after_success: + - if [[ $coverage = 1 ]]; then travis_retry php coveralls.phar; fi deploy: - provider: releases - api_key: - secure: Oq9TAPQZqnjxhbprWZQE64GhK4vxBHjvcMkS9dkbkCJQVz8cSqGxZOFqMOHulraFs2IX9PLeplrZReFMT630KkMNf74mkTtL9WMuaMJV0bbUPY+X7YpDGlLNNU7OA9Rxjr3y68x1jVxD6mLSlCFZP00qvmYRlOE1i2ltjO7L5Sw= - file: schema.phar - skip_cleanup: true - on: - tags: true - repo: api-platform/schema-generator - php: '7.1' + provider: releases + api_key: + secure: Oq9TAPQZqnjxhbprWZQE64GhK4vxBHjvcMkS9dkbkCJQVz8cSqGxZOFqMOHulraFs2IX9PLeplrZReFMT630KkMNf74mkTtL9WMuaMJV0bbUPY+X7YpDGlLNNU7OA9Rxjr3y68x1jVxD6mLSlCFZP00qvmYRlOE1i2ltjO7L5Sw= + file: schema.phar + skip_cleanup: true + on: + tags: true + repo: api-platform/schema-generator + php: '7.1' + condition: "! $deps" diff --git a/composer.json b/composer.json index ddd50c4c..a8157bb2 100644 --- a/composer.json +++ b/composer.json @@ -18,12 +18,12 @@ "psr-4": { "ApiPlatform\\SchemaGenerator\\Tests\\": "tests/" } }, "require": { - "php": ">=7.0", + "php": ">=7.1", "ext-json": "*", "symfony/console": "^2.7 || ^3.0 || ^4.0", "symfony/yaml": "^2.7 || ^3.0 || ^4.0", - "symfony/config": "^2.7 || ^3.0 || ^4.0", - "twig/twig": "^1.0 || ^2.0", + "symfony/config": "^3.3 || ^4.0", + "twig/twig": "^1.12 || ^2.0", "psr/log": "^1.0", "easyrdf/easyrdf": "^0.9", "league/html-to-markdown": "^4.0", diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php index bdde6492..a07a9938 100644 --- a/src/AnnotationGenerator/AbstractAnnotationGenerator.php +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use Psr\Log\LoggerInterface; @@ -24,18 +26,22 @@ abstract class AbstractAnnotationGenerator implements AnnotationGeneratorInterfa * @var LoggerInterface */ protected $logger; + /** * @var \EasyRdf_Graph[] */ protected $graphs; + /** * @var array */ protected $cardinalities; + /** * @var array */ protected $config; + /** * @var array */ @@ -44,13 +50,8 @@ abstract class AbstractAnnotationGenerator implements AnnotationGeneratorInterfa /** * {@inheritdoc} */ - public function __construct( - LoggerInterface $logger, - array $graphs, - array $cardinalities, - array $config, - array $classes - ) { + public function __construct(LoggerInterface $logger, array $graphs, array $cardinalities, array $config, array $classes) + { $this->logger = $logger; $this->graphs = $graphs; $this->cardinalities = $cardinalities; @@ -61,7 +62,7 @@ public function __construct( /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { return []; } @@ -69,7 +70,7 @@ public function generateClassAnnotations($className) /** * {@inheritdoc} */ - public function generateInterfaceAnnotations($className) + public function generateInterfaceAnnotations(string $className): array { return []; } @@ -77,7 +78,7 @@ public function generateInterfaceAnnotations($className) /** * {@inheritdoc} */ - public function generateConstantAnnotations($className, $constantName) + public function generateConstantAnnotations(string $className, string $constantName): array { return []; } @@ -85,7 +86,7 @@ public function generateConstantAnnotations($className, $constantName) /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { return []; } @@ -93,7 +94,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateGetterAnnotations($className, $fieldName) + public function generateGetterAnnotations(string $className, string $fieldName): array { return []; } @@ -101,7 +102,7 @@ public function generateGetterAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateSetterAnnotations($className, $fieldName) + public function generateSetterAnnotations(string $className, string $fieldName): array { return []; } @@ -109,7 +110,7 @@ public function generateSetterAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateAdderAnnotations($className, $fieldName) + public function generateAdderAnnotations(string $className, string $fieldName): array { return []; } @@ -117,7 +118,7 @@ public function generateAdderAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateRemoverAnnotations($className, $fieldName) + public function generateRemoverAnnotations(string $className, string $fieldName): array { return []; } @@ -125,29 +126,24 @@ public function generateRemoverAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { return []; } /** * Converts a Schema.org range to a PHP type. - * - * @param array $field - * @param bool $adderOrRemover - * - * @return string */ - protected function toPhpType(array $field, $adderOrRemover = false) + protected function toPhpType(array $field, bool $adderOrRemover = false): string { $range = $field['range']; if ($field['isEnum']) { if ($field['isArray']) { return 'string[]'; - } else { - return 'string'; } + + return 'string'; } $data = false; diff --git a/src/AnnotationGenerator/AnnotationGeneratorInterface.php b/src/AnnotationGenerator/AnnotationGeneratorInterface.php index 7a17171e..f69ba3d3 100644 --- a/src/AnnotationGenerator/AnnotationGeneratorInterface.php +++ b/src/AnnotationGenerator/AnnotationGeneratorInterface.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use Psr\Log\LoggerInterface; @@ -21,104 +23,52 @@ interface AnnotationGeneratorInterface { /** - * @param LoggerInterface $logger * @param \EasyRdf_Graph[] $graphs - * @param array $cardinalities - * @param array $config - * @param array $classes */ - public function __construct( - LoggerInterface $logger, - array $graphs, - array $cardinalities, - array $config, - array $classes - ); + public function __construct(LoggerInterface $logger, array $graphs, array $cardinalities, array $config, array $classes); /** - * Generates class' annotations. - * - * @param string $className - * - * @return array + * Generates class's annotations. */ - public function generateClassAnnotations($className); + public function generateClassAnnotations(string $className): array; /** * Generates interface's annotations. - * - * @param string $className - * - * @return array */ - public function generateInterfaceAnnotations($className); + public function generateInterfaceAnnotations(string $className): array; /** * Generates constant's annotations. - * - * @param string $className - * @param string $constantName - * - * @return array */ - public function generateConstantAnnotations($className, $constantName); + public function generateConstantAnnotations(string $className, string $constantName): array; /** * Generates field's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array */ - public function generateFieldAnnotations($className, $fieldName); + public function generateFieldAnnotations(string $className, string $fieldName): array; /** * Generates getter's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array */ - public function generateGetterAnnotations($className, $fieldName); + public function generateGetterAnnotations(string $className, string $fieldName): array; /** * Generates setter's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array */ - public function generateSetterAnnotations($className, $fieldName); + public function generateSetterAnnotations(string $className, string $fieldName): array; /** * Generates adder's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array */ - public function generateAdderAnnotations($className, $fieldName); + public function generateAdderAnnotations(string $className, string $fieldName): array; /** * Generates remover's annotation. - * - * @param string $className - * @param string $fieldName - * - * @return array */ - public function generateRemoverAnnotations($className, $fieldName); + public function generateRemoverAnnotations(string $className, string $fieldName): array; /** * Generates uses. - * - * @param string $className - * - * @return array */ - public function generateUses($className); + public function generateUses(string $className): array; } diff --git a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php index 61a45fcf..17267721 100644 --- a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php +++ b/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use ApiPlatform\SchemaGenerator\TypesGenerator; @@ -18,14 +20,14 @@ * * @author Kévin Dunglas * - * @link https://github.com/api-platform/core + * @see https://github.com/api-platform/core */ class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerator { /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { $resource = $this->classes[$className]['resource']; @@ -35,7 +37,7 @@ public function generateClassAnnotations($className) /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@ApiProperty(iri="http://schema.org/%s")', $fieldName)]; } @@ -43,7 +45,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { $resource = $this->classes[$className]['resource']; diff --git a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php index 262a220f..3b92b8f7 100644 --- a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php +++ b/src/AnnotationGenerator/ConstraintAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; /** @@ -21,7 +23,7 @@ class ConstraintAnnotationGenerator extends AbstractAnnotationGenerator /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { $field = $this->classes[$className]['fields'][$fieldName]; @@ -35,15 +37,12 @@ public function generateFieldAnnotations($className, $fieldName) case 'URL': $asserts[] = '@Assert\Url'; break; - case 'Date': $asserts[] = '@Assert\Date'; break; - case 'DateTime': $asserts[] = '@Assert\DateTime'; break; - case 'Time': $asserts[] = '@Assert\Time'; break; @@ -55,7 +54,7 @@ public function generateFieldAnnotations($className, $fieldName) if (empty($asserts)) { $phpType = $this->toPhpType($field); - if (in_array($phpType, ['boolean', 'float', 'integer', 'string'])) { + if (in_array($phpType, ['boolean', 'float', 'integer', 'string'], true)) { $asserts[] = sprintf('@Assert\Type(type="%s")', $phpType); } } @@ -83,7 +82,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { if ($this->classes[$className]['isEnum']) { return []; @@ -99,7 +98,7 @@ public function generateUses($className) $enumNamespace = isset($enumClass['namespaces']['class']) && $enumClass['namespaces']['class'] ? $enumClass['namespaces']['class'] : $this->config['namespaces']['enum']; $use = sprintf('%s\%s', $enumNamespace, $field['range']); - if (!in_array($use, $uses)) { + if (!in_array($use, $uses, true)) { $uses[] = $use; } } @@ -111,7 +110,7 @@ public function generateUses($className) /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { if ($this->classes[$className]['isEnum']) { return []; @@ -128,7 +127,7 @@ public function generateClassAnnotations($className) $uniqueFields[] = $field['name']; } - if (0 === count($uniqueFields)) { + if (!$uniqueFields) { return []; } diff --git a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php index 5f8967cb..7bf1af3f 100644 --- a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; @@ -24,7 +26,7 @@ class DoctrineMongoDBAnnotationGenerator extends AbstractAnnotationGenerator /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { $class = $this->classes[$className]; @@ -38,16 +40,13 @@ public function generateClassAnnotations($className) $inheritanceMapping = $class['abstract'] ? '@MongoDB\MappedSuperclass' : '@MongoDB\Document'; } - return [ - '', - $inheritanceMapping, - ]; + return ['', $inheritanceMapping]; } /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { $this->classes[$className]; $field = $this->classes[$className]['fields'][$fieldName]; @@ -55,11 +54,7 @@ public function generateFieldAnnotations($className, $fieldName) $annotations = []; if ($field['isEnum']) { - if ($field['isArray']) { - $type = 'simple_array'; - } else { - $type = 'string'; - } + $type = $field['isArray'] ? 'simple_array' : 'string'; } else { switch ($field['range']) { case 'Boolean': @@ -124,7 +119,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { $resource = $this->classes[$className]['resource']; @@ -136,19 +131,11 @@ public function generateUses($className) /** * Gets class or interface name to use in relations. - * - * @param string $range - * - * @return string */ - private function getRelationName($range) + private function getRelationName(string $range): string { $class = $this->classes[$range]; - if (isset($class['interfaceName'])) { - return $class['interfaceName']; - } - - return $class['name']; + return $class[$range]['interfaceName'] ?? $class['name']; } } diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php index f5808950..4973de0f 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; @@ -24,7 +26,7 @@ class DoctrineOrmAnnotationGenerator extends AbstractAnnotationGenerator /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { $class = $this->classes[$className]; @@ -46,16 +48,13 @@ public function generateClassAnnotations($className) } } - return [ - '', - $inheritanceMapping, - ]; + return ['', $inheritanceMapping]; } /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { $this->classes[$className]; $field = $this->classes[$className]['fields'][$fieldName]; @@ -67,11 +66,7 @@ public function generateFieldAnnotations($className, $fieldName) $annotations = []; if ($field['isEnum']) { - if ($field['isArray']) { - $type = 'simple_array'; - } else { - $type = 'string'; - } + $type = $field['isArray'] ? 'simple_array' : 'string'; } else { switch ($field['range']) { case 'Boolean': @@ -155,35 +150,29 @@ public function generateFieldAnnotations($className, $fieldName) case CardinalitiesExtractor::CARDINALITY_0_1: $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $this->getRelationName($field['range'])); break; - case CardinalitiesExtractor::CARDINALITY_1_1: $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $this->getRelationName($field['range'])); $annotations[] = '@ORM\JoinColumn(nullable=false)'; break; - case CardinalitiesExtractor::CARDINALITY_UNKNOWN: // No break case CardinalitiesExtractor::CARDINALITY_N_0: $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $this->getRelationName($field['range'])); break; - case CardinalitiesExtractor::CARDINALITY_N_1: $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $this->getRelationName($field['range'])); $annotations[] = '@ORM\JoinColumn(nullable=false)'; break; - case CardinalitiesExtractor::CARDINALITY_0_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; break; - case CardinalitiesExtractor::CARDINALITY_1_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); $name = $field['relationTableName'] ? sprintf('name="%s", ', $field['relationTableName']) : ''; $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; break; - case CardinalitiesExtractor::CARDINALITY_N_N: $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $this->getRelationName($field['range'])); if ($field['relationTableName']) { @@ -204,7 +193,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { $resource = $this->classes[$className]['resource']; @@ -216,12 +205,8 @@ public function generateUses($className) /** * Gets class or interface name to use in relations. - * - * @param string $range - * - * @return string */ - private function getRelationName($range) + private function getRelationName(string $range): string { $class = $this->classes[$range]; diff --git a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php index eb1894b9..e834f44f 100644 --- a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use ApiPlatform\SchemaGenerator\TypesGenerator; @@ -18,14 +20,14 @@ * * @author Kévin Dunglas * - * @link https://github.com/dunglas/DunglasApiBundle + * @see https://github.com/dunglas/DunglasApiBundle */ class DunglasApiAnnotationGenerator extends AbstractAnnotationGenerator { /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { $resource = $this->classes[$className]['resource']; @@ -35,7 +37,7 @@ public function generateClassAnnotations($className) /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; } @@ -43,7 +45,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { $resource = $this->classes[$className]['resource']; diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index 1d39b6b5..e444ffd9 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; use League\HTMLToMarkdown\HtmlConverter; @@ -31,13 +33,8 @@ class PhpDocAnnotationGenerator extends AbstractAnnotationGenerator /** * {@inheritdoc} */ - public function __construct( - LoggerInterface $logger, - array $graphs, - array $cardinalities, - array $config, - array $classes - ) { + public function __construct(LoggerInterface $logger, array $graphs, array $cardinalities, array $config, array $classes) + { parent::__construct($logger, $graphs, $cardinalities, $config, $classes); $this->htmlToMarkdown = new HtmlConverter(); @@ -46,7 +43,7 @@ public function __construct( /** * {@inheritdoc} */ - public function generateClassAnnotations($className) + public function generateClassAnnotations(string $className): array { return $this->generateDoc($className); } @@ -54,7 +51,7 @@ public function generateClassAnnotations($className) /** * {@inheritdoc} */ - public function generateInterfaceAnnotations($className) + public function generateInterfaceAnnotations(string $className): array { return $this->generateDoc($className, true); } @@ -62,15 +59,12 @@ public function generateInterfaceAnnotations($className) /** * {@inheritdoc} */ - public function generateConstantAnnotations($className, $constantName) + public function generateConstantAnnotations(string $className, string $constantName): array { $resource = $this->classes[$className]['constants'][$constantName]['resource']; - $annotations = $this->formatDoc($resource->get('rdfs:comment'), true); - $annotations[0] = sprintf( - '@var string %s', - $annotations[0] - ); + $annotations = $this->formatDoc((string) $resource->get('rdfs:comment'), true); + $annotations[0] = sprintf('@var string %s', $annotations[0]); return $annotations; } @@ -78,17 +72,13 @@ public function generateConstantAnnotations($className, $constantName) /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { $field = $this->classes[$className]['fields'][$fieldName]; $comment = $field['resource'] ? $field['resource']->get('rdfs:comment') : ''; - $annotations = $this->formatDoc($comment, true); - $annotations[0] = sprintf( - '@var %s %s', - $this->toPhpType($field), - $annotations[0] - ); + $annotations = $this->formatDoc((string) $comment, true); + $annotations[0] = sprintf('@var %s %s', $this->toPhpType($field), $annotations[0]); $annotations[] = ''; return $annotations; @@ -97,7 +87,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateGetterAnnotations($className, $fieldName) + public function generateGetterAnnotations(string $className, string $fieldName): array { return [ sprintf('Gets %s.', $fieldName), @@ -109,16 +99,12 @@ public function generateGetterAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateSetterAnnotations($className, $fieldName) + public function generateSetterAnnotations(string $className, string $fieldName): array { return [ sprintf('Sets %s.', $fieldName), '', - sprintf( - '@param %s $%s', - $this->toPhpType($this->classes[$className]['fields'][$fieldName]), - $fieldName - ), + sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName]), $fieldName), '', '@return $this', ]; @@ -127,16 +113,12 @@ public function generateSetterAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateAdderAnnotations($className, $fieldName) + public function generateAdderAnnotations(string $className, string $fieldName): array { return [ sprintf('Adds %s.', $fieldName), '', - sprintf( - '@param %s $%s', - $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), - $fieldName - ), + sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), $fieldName), '', '@return $this', ]; @@ -145,16 +127,12 @@ public function generateAdderAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateRemoverAnnotations($className, $fieldName) + public function generateRemoverAnnotations(string $className, string $fieldName): array { return [ sprintf('Removes %s.', $fieldName), '', - sprintf( - '@param %s $%s', - $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), - $fieldName - ), + sprintf('@param %s $%s', $this->toPhpType($this->classes[$className]['fields'][$fieldName], true), $fieldName), '', '@return $this', ]; @@ -162,13 +140,8 @@ public function generateRemoverAnnotations($className, $fieldName) /** * Generates class or interface PHPDoc. - * - * @param string $className - * @param bool $interface - * - * @return array */ - private function generateDoc($className, $interface = false) + private function generateDoc(string $className, bool $interface = false): array { $resource = $this->classes[$className]['resource']; $annotations = []; @@ -177,7 +150,7 @@ private function generateDoc($className, $interface = false) $annotations[] = '{@inheritdoc}'; $annotations[] = ''; } else { - $annotations = $this->formatDoc($resource->get('rdfs:comment')); + $annotations = $this->formatDoc((string) $resource->get('rdfs:comment')); $annotations[] = ''; $annotations[] = sprintf('@see %s %s', $resource->getUri(), 'Documentation on Schema.org'); } @@ -191,13 +164,8 @@ private function generateDoc($className, $interface = false) /** * Converts HTML to Markdown and explode. - * - * @param string $doc - * @param bool $indent - * - * @return array */ - private function formatDoc($doc, $indent = false) + private function formatDoc(string $doc, bool $indent = false): array { $doc = explode("\n", $this->htmlToMarkdown->convert($doc)); diff --git a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php b/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php index 80ceb56f..27d9950d 100644 --- a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php +++ b/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; /** @@ -16,14 +18,14 @@ * * @author Youssef El Montaser * - * @link https://symfony.com/doc/master/components/serializer.html + * @see https://symfony.com/doc/master/components/serializer.html */ class SerializerGroupsAnnotationGenerator extends AbstractAnnotationGenerator { /** * {@inheritdoc} */ - public function generateFieldAnnotations($className, $fieldName) + public function generateFieldAnnotations(string $className, string $fieldName): array { $annotations = []; @@ -39,7 +41,7 @@ public function generateFieldAnnotations($className, $fieldName) /** * {@inheritdoc} */ - public function generateUses($className) + public function generateUses(string $className): array { return ['Symfony\Component\Serializer\Annotation\Groups']; } diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index bbaaaa30..d2543fbd 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator; /** @@ -31,14 +33,14 @@ class CardinalitiesExtractor * @var \EasyRdf_Graph[] */ private $graphs; + /** * @var GoodRelationsBridge */ private $goodRelationsBridge; /** - * @param \EasyRdf_Graph[] $graphs - * @param GoodRelationsBridge $goodRelationsBridge + * @param \EasyRdf_Graph[] $graphs */ public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBridge) { @@ -48,10 +50,8 @@ public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBri /** * Extracts cardinality of properties. - * - * @return array */ - public function extract() + public function extract(): array { $properties = []; @@ -73,7 +73,7 @@ public function extract() * * @return string The cardinality */ - private function extractForProperty(\EasyRdf_Resource $property) + private function extractForProperty(\EasyRdf_Resource $property): string { $localName = $property->localName(); $fromGoodRelations = $this->goodRelationsBridge->extractCardinality($localName); diff --git a/src/Command/DumpConfigurationCommand.php b/src/Command/DumpConfigurationCommand.php index ee375ee1..8cd1ccc9 100644 --- a/src/Command/DumpConfigurationCommand.php +++ b/src/Command/DumpConfigurationCommand.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Command; use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; @@ -27,7 +29,7 @@ class DumpConfigurationCommand extends Command /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setName('dump-configuration') @@ -37,7 +39,7 @@ protected function configure() /** * {@inheritdoc} */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): void { $configuration = new TypesGeneratorConfiguration(); $dumper = new YamlReferenceDumper(); diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 0990be99..10055171 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Command; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; @@ -28,7 +30,7 @@ class ExtractCardinalitiesCommand extends Command /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setName('extract-cardinalities') @@ -38,7 +40,7 @@ protected function configure() /** * {@inheritdoc} */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): void { $relations = []; $schemaOrg = new \EasyRdf_Graph(); diff --git a/src/Command/GenerateTypesCommand.php b/src/Command/GenerateTypesCommand.php index c05761f6..e01885ff 100644 --- a/src/Command/GenerateTypesCommand.php +++ b/src/Command/GenerateTypesCommand.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Command; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; @@ -33,7 +35,7 @@ class GenerateTypesCommand extends Command /** * {@inheritdoc} */ - protected function configure() + protected function configure(): void { $this ->setName('generate-types') @@ -45,7 +47,7 @@ protected function configure() /** * {@inheritdoc} */ - protected function execute(InputInterface $input, OutputInterface $output) + protected function execute(InputInterface $input, OutputInterface $output): void { $configArgument = $input->getArgument('config'); if ($configArgument) { diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index 4b6b5a67..8ea1d00b 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator; /** @@ -26,9 +28,6 @@ class GoodRelationsBridge */ protected $relations; - /** - * @var array - */ protected static $objectPropertiesTable = [ 'priceSpecification' => 'hasPriceSpecification', 'businessFunction' => 'hasBusinessFunction', @@ -46,9 +45,7 @@ class GoodRelationsBridge 'warranty' => 'hasWarrantyPromise', 'acceptedPaymentMethod' => 'acceptedPaymentMethods', ]; - /** - * @var array - */ + protected static $datatypePropertiesTable = [ 'minPrice' => 'hasMinCurrencyValue', 'unitCode' => 'hasUnitOfMeasurement', @@ -84,12 +81,8 @@ public function __construct(array $relations) /** * Checks if a property exists in GoodRelations. - * - * @param string $id - * - * @return bool */ - public function exist($id) + public function exist(string $id): bool { foreach ($this->relations as $relation) { $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]', $this->getPropertyUrl($id))); @@ -104,11 +97,9 @@ public function exist($id) /** * Extracts cardinality from the Good Relations OWL. * - * @param string $id - * * @return string|bool */ - public function extractCardinality($id) + public function extractCardinality(string $id) { foreach ($this->relations as $relation) { $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', $this->getPropertyUrl($id))); @@ -124,12 +115,8 @@ public function extractCardinality($id) /** * Converts Schema.org's id to Good Relations id. - * - * @param string $id - * - * @return string */ - private function convertPropertyId($id) + private function convertPropertyId(string $id): string { if (isset(static::$datatypePropertiesTable[$id])) { return static::$datatypePropertiesTable[$id]; @@ -144,12 +131,8 @@ private function convertPropertyId($id) /** * Gets a property URL. - * - * @param string $id - * - * @return string */ - private function getPropertyUrl($id) + private function getPropertyUrl(string $id): string { return self::GOOD_RELATIONS_NAMESPACE.$this->convertPropertyId($id); } diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index e55781b3..c964213a 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\AnnotationGeneratorInterface; @@ -22,7 +24,7 @@ use Psr\Log\LoggerInterface; /** - * Entities generator. + * Generates entity files. * * @author Kévin Dunglas */ @@ -100,11 +102,7 @@ class TypesGenerator private $cardinalities; /** - * @param \Twig_Environment $twig - * @param LoggerInterface $logger - * @param \EasyRdf_Graph[] $graphs - * @param CardinalitiesExtractor $cardinalitiesExtractor - * @param GoodRelationsBridge $goodRelationsBridge + * @param \EasyRdf_Graph[] $graphs */ public function __construct(\Twig_Environment $twig, LoggerInterface $logger, array $graphs, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge) { @@ -123,10 +121,8 @@ public function __construct(\Twig_Environment $twig, LoggerInterface $logger, ar /** * Generates files. - * - * @param array $config */ - public function generate(array $config) + public function generate(array $config): void { $baseClass = [ 'constants' => [], @@ -140,7 +136,7 @@ public function generate(array $config) $typesToGenerate = []; - if (empty($config['types'])) { + if (!$config['types']) { foreach ($this->graphs as $graph) { $typesToGenerate = $graph->allOfType('rdfs:Class'); } @@ -171,7 +167,7 @@ public function generate(array $config) foreach ($typesToGenerate as $typeName => $type) { $typeName = is_string($typeName) ? $typeName : $type->localName(); - $typeConfig = isset($config['types'][$typeName]) ? $config['types'][$typeName] : null; + $typeConfig = $config['types'][$typeName] ?? null; $class = $baseClass; $comment = $type->get('rdfs:comment'); @@ -183,7 +179,7 @@ public function generate(array $config) $class['isEnum'] = $this->isEnum($type); if ($class['isEnum']) { - $class['namespace'] = isset($typeConfig['namespace']) ? $typeConfig['namespace'] : $config['namespaces']['enum']; + $class['namespace'] = $typeConfig['namespace'] ?? $config['namespaces']['enum']; $class['parent'] = self::ENUM_EXTENDS; $class['uses'][] = self::ENUM_USE; @@ -199,10 +195,10 @@ public function generate(array $config) } } else { // Entities - $class['namespace'] = isset($typeConfig['namespaces']['class']) ? $typeConfig['namespaces']['class'] : $config['namespaces']['entity']; + $class['namespace'] = $typeConfig['namespaces']['class'] ?? $config['namespaces']['entity']; // Parent - $class['parent'] = isset($typeConfig['parent']) ? $typeConfig['parent'] : null; + $class['parent'] = $typeConfig['parent'] ?? null; if (null === $class['parent']) { $numberOfSupertypes = count($type->all('rdfs:subClassOf')); @@ -222,9 +218,9 @@ public function generate(array $config) } // Embeddable - $class['embeddable'] = isset($typeConfig['embeddable']) ? $typeConfig['embeddable'] : false; + $class['embeddable'] = $typeConfig['embeddable'] ?? false; - if (!empty($config['types']) && $class['parent'] && !isset($config['types'][$class['parent']])) { + if (!$config['types'] && $class['parent'] && !isset($config['types'][$class['parent']])) { $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class['parent'], $type->localName())); } @@ -290,14 +286,14 @@ public function generate(array $config) continue; } - $parentConfig = isset($config['types'][$class['parent']]) ? $config['types'][$class['parent']] : null; + $parentConfig = $config['types'][$class['parent']] ?? null; $parentClass = $classes[$class['parent']]; while ($parentClass) { if (!isset($parentConfig['properties']) || !is_array($parentConfig['properties'])) { // Unset implicit property $parentType = $parentClass['resource']; - if (in_array($property, $propertiesMap[$parentType->getUri()])) { + if (in_array($property, $propertiesMap[$parentType->getUri()], true)) { unset($class['fields'][$property->localName()]); continue 2; } @@ -309,7 +305,7 @@ public function generate(array $config) } } - $parentConfig = $parentClass['parent'] ? (isset($config['types'][$parentClass['parent']]) ? $config['types'][$parentClass['parent']] : null) : null; + $parentConfig = $parentClass['parent'] ? ($config['types'][$parentClass['parent']] ?? null) : null; $parentClass = $parentClass['parent'] ? $classes[$parentClass['parent']] : null; } } @@ -445,12 +441,8 @@ public function generate(array $config) /** * Tests if a type is an enum. - * - * @param \EasyRdf_Resource $type - * - * @return bool */ - private function isEnum(\EasyRdf_Resource $type) + private function isEnum(\EasyRdf_Resource $type): bool { $subClassOf = $type->get('rdfs:subClassOf'); @@ -515,7 +507,7 @@ private function createPropertiesMap(array $types) foreach ($graph->allOfType('rdf:Property') as $property) { foreach ($property->all(self::SCHEMA_ORG_DOMAIN) as $domain) { foreach ($typesAsString as $typesAsStringItem) { - if (in_array($domain->getUri(), $typesAsStringItem)) { + if (in_array($domain->getUri(), $typesAsStringItem, true)) { $map[$typesAsStringItem[0]][] = $property; } } @@ -535,7 +527,7 @@ private function createPropertiesMap(array $types) */ private function isDatatype($type) { - return in_array($type, ['Boolean', 'DataType', 'Date', 'DateTime', 'Float', 'Integer', 'Number', 'Text', 'Time', 'URL']); + return in_array($type, ['Boolean', 'DataType', 'Date', 'DateTime', 'Float', 'Integer', 'Number', 'Text', 'Time', 'URL'], true); } /** @@ -547,7 +539,7 @@ private function isDatatype($type) */ private function isDateTime($type) { - return in_array($type, ['Date', 'DateTime', 'Time']); + return in_array($type, ['Date', 'DateTime', 'Time'], true); } /** @@ -564,7 +556,7 @@ private function isDateTime($type) */ private function generateField(array $config, array $class, \EasyRdf_Resource $type, $typeName, $propertyName, \EasyRdf_Resource $property = null) { - $typeConfig = isset($config['types'][$typeName]) ? $config['types'][$typeName] : null; + $typeConfig = $config['types'][$typeName] ?? null; $typesDefined = !empty($config['types']); // Warn when property are not part of GoodRelations @@ -575,7 +567,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t } // Ignore or warn when properties are legacy - if (!empty($property) && preg_match('/legacy spelling/', $property->get('rdfs:comment'))) { + if (!empty($property) && preg_match('/legacy spelling/', (string) $property->get('rdfs:comment'))) { if (isset($typeConfig['properties'])) { $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyName, $type->localName())); } else { @@ -585,7 +577,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t } } - $propertyConfig = isset($typeConfig['properties'][$propertyName]) ? $typeConfig['properties'][$propertyName] : null; + $propertyConfig = $typeConfig['properties'][$propertyName] ?? null; $ranges = []; if (isset($propertyConfig['range']) && $propertyConfig['range']) { @@ -606,18 +598,18 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t $this->logger->warning(sprintf('The property "%s" (type "%s") has several types. Using the first one.', $propertyName, $type->localName())); } - $cardinality = isset($propertyConfig['cardinality']) ? $propertyConfig['cardinality'] : false; + $cardinality = $propertyConfig['cardinality'] ?? false; if (!$cardinality || $cardinality === CardinalitiesExtractor::CARDINALITY_UNKNOWN) { $cardinality = $property ? $this->cardinalities[$propertyName] : CardinalitiesExtractor::CARDINALITY_1_1; } - $ormColumn = isset($propertyConfig['ormColumn']) ? $propertyConfig['ormColumn'] : null; + $ormColumn = $propertyConfig['ormColumn'] ?? null; $isArray = in_array($cardinality, [ CardinalitiesExtractor::CARDINALITY_0_N, CardinalitiesExtractor::CARDINALITY_1_N, CardinalitiesExtractor::CARDINALITY_N_N, - ]); + ], true); if (isset($propertyConfig['nullable']) && false === $propertyConfig['nullable']) { $isNullable = false; @@ -625,14 +617,14 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t $isNullable = !in_array($cardinality, [ CardinalitiesExtractor::CARDINALITY_1_1, CardinalitiesExtractor::CARDINALITY_1_N, - ]); + ], true); } $columnPrefix = false; - $isEmbedded = isset($propertyConfig['embedded']) ? $propertyConfig['embedded'] : false; + $isEmbedded = $propertyConfig['embedded'] ?? false; if (true === $isEmbedded) { - $columnPrefix = isset($propertyConfig['columnPrefix']) ? $propertyConfig['columnPrefix'] : false; + $columnPrefix = $propertyConfig['columnPrefix'] ?? false; } $class['fields'][$propertyName] = [ @@ -652,7 +644,7 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t if ($isArray) { $class['hasConstructor'] = true; - if (isset($config['doctrine']['useCollection']) && $config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'])) { + if (isset($config['doctrine']['useCollection']) && $config['doctrine']['useCollection'] && !in_array(self::DOCTRINE_COLLECTION_USE, $class['uses'], true)) { $class['uses'][] = self::DOCTRINE_COLLECTION_USE; } } @@ -662,15 +654,9 @@ private function generateField(array $config, array $class, \EasyRdf_Resource $t } /** - * Generates field's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array */ - private function generateFieldAnnotations($annotationGenerators, $className, $fieldName) + private function generateFieldAnnotations(array $annotationGenerators, string $className, string $fieldName): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -681,15 +667,9 @@ private function generateFieldAnnotations($annotationGenerators, $className, $fi } /** - * Generates constant's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $constantName - * - * @return array */ - private function generateConstantAnnotations(array $annotationGenerators, $className, $constantName) + private function generateConstantAnnotations(array $annotationGenerators, string $className, string $constantName): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -700,14 +680,9 @@ private function generateConstantAnnotations(array $annotationGenerators, $class } /** - * Generates class' annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * - * @return array */ - private function generateClassAnnotations(array $annotationGenerators, $className) + private function generateClassAnnotations(array $annotationGenerators, string $className): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -718,14 +693,9 @@ private function generateClassAnnotations(array $annotationGenerators, $classNam } /** - * Generates interface's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * - * @return array */ - private function generateInterfaceAnnotations(array $annotationGenerators, $className) + private function generateInterfaceAnnotations(array $annotationGenerators, string $className): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -736,15 +706,9 @@ private function generateInterfaceAnnotations(array $annotationGenerators, $clas } /** - * Generates getter's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array */ - private function generateGetterAnnotations(array $annotationGenerators, $className, $fieldName) + private function generateGetterAnnotations(array $annotationGenerators, string $className, string $fieldName): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -755,15 +719,9 @@ private function generateGetterAnnotations(array $annotationGenerators, $classNa } /** - * Generates adder's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array */ - private function generateAdderAnnotations(array $annotationGenerators, $className, $fieldName) + private function generateAdderAnnotations(array $annotationGenerators, string $className, string $fieldName): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -774,15 +732,9 @@ private function generateAdderAnnotations(array $annotationGenerators, $classNam } /** - * Generates remover's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array */ - private function generateRemoverAnnotations(array $annotationGenerators, $className, $fieldName) + private function generateRemoverAnnotations(array $annotationGenerators, string $className, string $fieldName): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -793,15 +745,9 @@ private function generateRemoverAnnotations(array $annotationGenerators, $classN } /** - * Generates getter's annotations. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param string $className - * @param string $fieldName - * - * @return array */ - private function generateSetterAnnotations(array $annotationGenerators, $className, $fieldName) + private function generateSetterAnnotations(array $annotationGenerators, string $className, string $fieldName): array { $annotations = []; foreach ($annotationGenerators as $generator) { @@ -812,15 +758,9 @@ private function generateSetterAnnotations(array $annotationGenerators, $classNa } /** - * Generates uses. - * * @param AnnotationGeneratorInterface[] $annotationGenerators - * @param array $classes - * @param string $className - * - * @return array */ - private function generateClassUses($annotationGenerators, $classes, $className) + private function generateClassUses($annotationGenerators, array $classes, string $className): array { $uses = $classes[$className]['uses']; @@ -842,7 +782,7 @@ private function generateClassUses($annotationGenerators, $classes, $className) $classes[$field['range']]['interfaceName'] ); - if (!in_array($use, $uses)) { + if (!in_array($use, $uses, true)) { $uses[] = $use; } } @@ -860,23 +800,16 @@ private function generateClassUses($annotationGenerators, $classes, $className) /** * Converts a namespace to a directory path according to PSR-4. - * - * @param array $config - * @param string $namespace - * - * @return string */ - private function namespaceToDir($config, $namespace) + private function namespaceToDir(array $config, string $namespace): string { return sprintf('%s/%s/', $config['output'], strtr($namespace, '\\', '/')); } /** * Uses PHP CS Fixer to make generated files following PSR and Symfony Coding Standards. - * - * @param array $files */ - private function fixCs(array $files) + private function fixCs(array $files): void { $fileInfos = []; foreach ($files as $file) { diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index d7fd1a42..b2769feb 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator; use Symfony\Component\Config\Definition\Builder\TreeBuilder; @@ -27,7 +29,7 @@ class TypesGeneratorConfiguration implements ConfigurationInterface /** * {@inheritdoc} */ - public function getConfigTreeBuilder() + public function getConfigTreeBuilder(): TreeBuilder { $treeBuilder = new TreeBuilder(); $rootNode = $treeBuilder->root('config'); diff --git a/templates/class.php.twig b/templates/class.php.twig index a7cfa8ec..64f9ef22 100644 --- a/templates/class.php.twig +++ b/templates/class.php.twig @@ -8,6 +8,8 @@ {% if config.header %}{{ config.header }}{% endif %} +declare(strict_types=1); + namespace {{ class.namespace }}; {% for use in class.uses %} diff --git a/templates/interface.php.twig b/templates/interface.php.twig index c7226b26..b1bdc815 100644 --- a/templates/interface.php.twig +++ b/templates/interface.php.twig @@ -8,6 +8,8 @@ {% if config.header %}{{ config.header }}{% endif %} +declare(strict_types=1); + namespace {{ class.interfaceNamespace }}; {% if class.interfaceAnnotations|length > 0 %} diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php index f13e2a14..b2a7c857 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index c38562e1..77b22b07 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\Command\DumpConfigurationCommand; diff --git a/tests/Command/ExtractCardinalitiesCommandTest.php b/tests/Command/ExtractCardinalitiesCommandTest.php index 16817632..1360bdb2 100644 --- a/tests/Command/ExtractCardinalitiesCommandTest.php +++ b/tests/Command/ExtractCardinalitiesCommandTest.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\Command\ExtractCardinalitiesCommand; diff --git a/tests/Command/GenerateTypesCommandTest.php b/tests/Command/GenerateTypesCommandTest.php index e62ea2f8..56c255b2 100644 --- a/tests/Command/GenerateTypesCommandTest.php +++ b/tests/Command/GenerateTypesCommandTest.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\Command\GenerateTypesCommand; diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 14225375..ceb67f57 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -9,6 +9,8 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; @@ -22,7 +24,7 @@ */ class TypesGeneratorTest extends TestCase { - public function testGenerate() + public function testGenerate(): void { $twigProphecy = $this->prophesize('Twig_Environment'); foreach ($this->getClasses() as $class) { @@ -44,7 +46,7 @@ public function testGenerate() $typesGenerator->generate($this->getConfig()); } - private function getGraphs() + private function getGraphs(): array { $graph = new \EasyRdf_Graph(); @@ -97,15 +99,10 @@ private function getGraphs() $graph->addResource('http://schema.org/sharedContent', 'schema:domainIncludes', 'http://schema.org/SocialMediaPosting'); $graph->addResource('http://schema.org/sharedContent', 'schema:rangeIncludes', 'http://schema.org/CreativeWork'); - return [ - $graph, - ]; + return [$graph]; } - /** - * @return array - */ - private function getCardinalities() + private function getCardinalities(): array { return [ 'articleBody' => CardinalitiesExtractor::CARDINALITY_0_1, @@ -119,10 +116,7 @@ private function getCardinalities() ]; } - /** - * @return array - */ - private function getConfig() + private function getConfig(): array { return [ 'annotationGenerators' => [ @@ -178,10 +172,7 @@ private function getConfig() ]; } - /** - * @return array - */ - private function getClasses() + private function getClasses(): array { return [ 'Article' => [ @@ -378,19 +369,23 @@ private function getContextMatcher(array $class) return false; } - $baseClass = array_diff_key($class, [ - 'fields' => null, - ]); + $baseClass = $class; + unset($baseClass['fields']); - if (!isset($context['class']) || !is_array($context['class']) || $baseClass != array_intersect_key($context['class'], $baseClass)) { + if (!isset($context['class']) || !is_array($context['class']) || $this->arrayEqual($baseClass, array_intersect_key($context['class'], $baseClass))) { return false; } - if (array_keys($class['fields']) != array_keys($context['class']['fields'])) { + if (array_keys($class['fields']) === array_keys($context['class']['fields'])) { return false; } return true; }; } + + private function arrayEqual(array $a, array $b): bool + { + return count($a) === count($b) && !array_diff($a, $b); + } } diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1ce7a174..aabe6afe 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -9,4 +9,6 @@ * file that was distributed with this source code. */ +declare(strict_types=1); + return require __DIR__.'/../vendor/autoload.php'; From 2e8e684c2cf3911145ada9a647f3044d677b317b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 21 Aug 2017 16:25:14 +0200 Subject: [PATCH 073/258] Update CHANGLOG.md --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index b1d4c989..0a1f6deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.3.0 + +* Now use PHP CS Fixer 2 +* The code has been modernized to use PHP 7 and 7.1's new features (typehints, strict types), PHP 7.1 is now a requirement + ## 1.2.0 * The default config now match the Symfony's and API Platform's Best Practices (namespaces) From 3d1bcb5535b7626d7f035bf439562150015df412 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 21 Aug 2017 17:20:07 +0200 Subject: [PATCH 074/258] Add PHPStan --- .travis.yml | 3 +++ composer.json | 12 ++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/.travis.yml b/.travis.yml index de85782b..f90b8a82 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,10 +16,12 @@ matrix: before_install: - phpenv config-rm xdebug.ini || echo "xdebug not available" - echo "memory_limit=-1" >> ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/travis.ini + - export PATH="$PATH:$HOME/.composer/vendor/bin" - wget https://phar.phpunit.de/phpunit-6.3.phar - if [[ $coverage = 1 ]]; then mkdir -p build/logs; fi - if [[ $coverage = 1 ]]; then wget https://github.com/satooshi/php-coveralls/releases/download/v1.0.1/coveralls.phar; fi - if [[ $lint = 1 ]]; then wget https://github.com/FriendsOfPHP/PHP-CS-Fixer/releases/download/v2.4.0/php-cs-fixer.phar; fi + - if [[ $lint = 1 ]]; then composer global require --dev 'phpstan/phpstan:^0.8'; fi - if [[ $TRAVIS_PHP_VERSION = "7.1" ]]; then curl -LSs https://box-project.github.io/box2/installer.php | php; fi; install: @@ -30,6 +32,7 @@ install: script: - if [[ $coverage = 1 ]]; then phpdbg -qrr php phpunit-6.3.phar --coverage-closer build/logs/clover.xml; else php phpunit-6.3.phar; fi - if [[ $lint = 1 ]]; then php php-cs-fixer.phar fix --dry-run --diff --no-ansi; fi + - if [[ $lint = 1 ]]; then phpstan analyse -l5 --ansi src; fi - if [[ ! $deps && $TRAVIS_PHP_VERSION = "7.1" ]]; then php box.phar build; fi; after_success: diff --git a/composer.json b/composer.json index a8157bb2..7f4f0bb1 100644 --- a/composer.json +++ b/composer.json @@ -19,15 +19,15 @@ }, "require": { "php": ">=7.1", + "easyrdf/easyrdf": "^0.9", "ext-json": "*", + "friendsofphp/php-cs-fixer": "^2.4", + "league/html-to-markdown": "^4.0", + "psr/log": "^1.0", "symfony/console": "^2.7 || ^3.0 || ^4.0", "symfony/yaml": "^2.7 || ^3.0 || ^4.0", "symfony/config": "^3.3 || ^4.0", - "twig/twig": "^1.12 || ^2.0", - "psr/log": "^1.0", - "easyrdf/easyrdf": "^0.9", - "league/html-to-markdown": "^4.0", - "friendsofphp/php-cs-fixer": "^2.4" + "twig/twig": "^1.12 || ^2.0" }, "require-dev": { "doctrine/orm": "^2.2", @@ -35,9 +35,9 @@ "symfony/filesystem": "^2.7 || ^3.0 || ^4.0" }, "suggest": { - "myclabs/php-enum": "For enumerations", "doctrine/collections": "For Doctrine collections", "doctrine/orm": "For Doctrine annotations", + "myclabs/php-enum": "For enumerations", "symfony/validator": "For constraint annotations" }, "bin": ["bin/schema"] From 8093dff75caaba1431b1a7d8c3bd62198e10d526 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Mon, 21 Aug 2017 17:25:07 +0200 Subject: [PATCH 075/258] Remove API Platform v1 support --- CHANGELOG.md | 3 +- .../DunglasApiAnnotationGenerator.php | 57 ------------------- tests/config/address-book.yml | 6 -- tests/config/blog.yml | 1 - tests/config/mongodb/address-book.yml | 6 -- tests/config/vgo.yml | 1 - 6 files changed, 2 insertions(+), 72 deletions(-) delete mode 100644 src/AnnotationGenerator/DunglasApiAnnotationGenerator.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a1f6deb..2e124e86 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,7 +1,8 @@ # Changelog -## 1.3.0 +## 2.0 +* The annotation generator for API Platform v1 has been dropped. Only API Platform v2 is now supported. * Now use PHP CS Fixer 2 * The code has been modernized to use PHP 7 and 7.1's new features (typehints, strict types), PHP 7.1 is now a requirement diff --git a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php b/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php deleted file mode 100644 index e834f44f..00000000 --- a/src/AnnotationGenerator/DunglasApiAnnotationGenerator.php +++ /dev/null @@ -1,57 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; - -use ApiPlatform\SchemaGenerator\TypesGenerator; - -/** - * Generates Iri annotations provided by DunglasApiBundle. - * - * @author Kévin Dunglas - * - * @see https://github.com/dunglas/DunglasApiBundle - */ -class DunglasApiAnnotationGenerator extends AbstractAnnotationGenerator -{ - /** - * {@inheritdoc} - */ - public function generateClassAnnotations(string $className): array - { - $resource = $this->classes[$className]['resource']; - - return [sprintf('@Iri("%s")', $resource->getUri())]; - } - - /** - * {@inheritdoc} - */ - public function generateFieldAnnotations(string $className, string $fieldName): array - { - return $this->classes[$className]['fields'][$fieldName]['isCustom'] ? [] : [sprintf('@Iri("https://schema.org/%s")', $fieldName)]; - } - - /** - * {@inheritdoc} - */ - public function generateUses(string $className): array - { - $resource = $this->classes[$className]['resource']; - - $subClassOf = $resource->get('rdfs:subClassOf'); - $typeIsEnum = $subClassOf && $subClassOf->getUri() === TypesGenerator::SCHEMA_ORG_ENUMERATION; - - return $typeIsEnum ? [] : ['Dunglas\ApiBundle\Annotation\Iri']; - } -} diff --git a/tests/config/address-book.yml b/tests/config/address-book.yml index 2d7e77f2..9fc2df4b 100644 --- a/tests/config/address-book.yml +++ b/tests/config/address-book.yml @@ -1,12 +1,6 @@ # The PHP namespace of generated entities namespaces: entity: 'AddressBook\Entity' -# Enable DunglasApiAnnotationGenerator -annotationGenerators: - - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator # The list of types and properties we want to use types: Person: diff --git a/tests/config/blog.yml b/tests/config/blog.yml index 81bc5e05..2e1a4b16 100644 --- a/tests/config/blog.yml +++ b/tests/config/blog.yml @@ -2,7 +2,6 @@ annotationGenerators: # Generators we want to use, keep it as is for any API Pla - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator namespaces: entity: AppBundle\Entity # The default namespace for entities, following API Platform and Symfony best practices types: # The list of type to generated (a PHP entity class by type will be generated) diff --git a/tests/config/mongodb/address-book.yml b/tests/config/mongodb/address-book.yml index 1ad65aca..7a98f958 100644 --- a/tests/config/mongodb/address-book.yml +++ b/tests/config/mongodb/address-book.yml @@ -1,12 +1,6 @@ # The PHP namespace of generated entities namespaces: entity: 'AddressBook\Document' -# Enable DunglasApiAnnotationGenerator -annotationGenerators: - - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineMongoDBAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator # The list of types and properties we want to use types: Person: diff --git a/tests/config/vgo.yml b/tests/config/vgo.yml index ec2d1dc7..1b2a99af 100644 --- a/tests/config/vgo.yml +++ b/tests/config/vgo.yml @@ -2,7 +2,6 @@ annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DunglasApiAnnotationGenerator namespaces: entity: 'AppBundle\Entity' From 593c6370a688567eac7c852744446896efec476c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Tue, 22 Aug 2017 12:28:26 +0200 Subject: [PATCH 076/258] Add new options to specify files to use for ExtractCardinalitiesCommand. Fix flaky tests. --- src/CardinalitiesExtractor.php | 3 - src/Command/ExtractCardinalitiesCommand.php | 10 +- .../ExtractCardinalitiesCommandTest.php | 2 +- tests/data/schema.rdfa | 16169 +++++++++------- 4 files changed, 8696 insertions(+), 7488 deletions(-) diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index d2543fbd..6eb7b838 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -34,9 +34,6 @@ class CardinalitiesExtractor */ private $graphs; - /** - * @var GoodRelationsBridge - */ private $goodRelationsBridge; /** diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 10055171..648987f2 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -18,6 +18,7 @@ use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; /** @@ -34,7 +35,10 @@ protected function configure(): void { $this ->setName('extract-cardinalities') - ->setDescription('Extract properties\' cardinality'); + ->setDescription('Extract properties\' cardinality') + ->addOption('schemaorg-file', 's', InputOption::VALUE_REQUIRED, 'The path or URL of the Schema.org RDFa file to use.', TypesGeneratorConfiguration::SCHEMA_ORG_RDFA_URL) + ->addOption('goodrelations-file', 'g', InputOption::VALUE_REQUIRED, 'The path or URL of the GoodRelations OWL file to use.', TypesGeneratorConfiguration::GOOD_RELATIONS_OWL_URL) + ; } /** @@ -44,10 +48,10 @@ protected function execute(InputInterface $input, OutputInterface $output): void { $relations = []; $schemaOrg = new \EasyRdf_Graph(); - $schemaOrg->load(TypesGeneratorConfiguration::SCHEMA_ORG_RDFA_URL, 'rdfa'); + $schemaOrg->load($input->getOption('schemaorg-file'), 'rdfa'); $relations[] = $schemaOrg; - $goodRelations = [new \SimpleXMLElement(TypesGeneratorConfiguration::GOOD_RELATIONS_OWL_URL, 0, true)]; + $goodRelations = [new \SimpleXMLElement($input->getOption('goodrelations-file'), 0, true)]; $goodRelationsBridge = new GoodRelationsBridge($goodRelations); $cardinalitiesExtractor = new CardinalitiesExtractor($relations, $goodRelationsBridge); diff --git a/tests/Command/ExtractCardinalitiesCommandTest.php b/tests/Command/ExtractCardinalitiesCommandTest.php index 1360bdb2..d6f3fb2c 100644 --- a/tests/Command/ExtractCardinalitiesCommandTest.php +++ b/tests/Command/ExtractCardinalitiesCommandTest.php @@ -25,7 +25,7 @@ class ExtractCardinalitiesCommandTest extends TestCase public function testExtractCardinalities() { $commandTester = new CommandTester(new ExtractCardinalitiesCommand()); - $this->assertEquals(0, $commandTester->execute([])); + $this->assertEquals(0, $commandTester->execute([], ['schemaorg-file' => __DIR__.'/../data/schema.rdfa', 'goodrelations-file' => __DIR__.'/../data/v1.owl'])); $this->assertEquals(<<<'JSON' { diff --git a/tests/data/schema.rdfa b/tests/data/schema.rdfa index ee5d749c..bc02ec33 100644 --- a/tests/data/schema.rdfa +++ b/tests/data/schema.rdfa @@ -1,7 +1,7 @@ - + - RDFa Lite Reflection + Schema.org master file: RDFS in RDFa - - - -

Schema.org core schema

- -

This is an RDFa-based representation of the schema.org schema, the underlying representation of the schema.org vocabulary.

- -

It is represented in a form based on W3C RDF/RDFS. We encourage proposals for schema.org improvements to be expressed - in this same style. See the how we work document for information on collaboration.

-

- See datamodel for more details, - the developers page for alternate formats. -

-

- Note: the style of RDFa used here may change in the future. To see the substantive content of the schema, view the - HTML source markup. We use a simple subset of RDFa for syntax, including prefixes that are declared in the - RDFa initial context. We also use Markdown syntax within comments to - make hypertext documentation easier to edit. Other formats are available. -

- -
- -
- Thing - The most generic type of item. -
- -
- CreativeWork - The most generic kind of creative work, including books, movies, photographs, software programs, etc. - Subclass of: Thing - Source: rNews -
- -
- WebPage - A web page. Every web page is implicitly assumed to be declared to be of type WebPage, so the various properties about that webpage, such as <code>breadcrumb</code> may be used. We recommend explicit declaration if these properties are specified, but if they are found outside of an itemscope, they will be assumed to be about the page. - Subclass of: CreativeWork -
- -
- AboutPage - Web page type: About page. - Subclass of: WebPage -
- -
- Organization - An organization such as a school, NGO, corporation, club, etc. - Subclass of: Thing -
- -
- Place - Entities that have a somewhat fixed, physical extension. - Subclass of: Thing -
- -
- LocalBusiness - A particular physical business or branch of an organization. Examples of LocalBusiness include a restaurant, a particular branch of a restaurant chain, a branch of a bank, a medical practice, a club, a bowling alley, etc. - Subclass of: Organization - Subclass of: Place -
- -
- MedicalOrganization - A medical organization (physical or not), such as hospital, institution or clinic. - Subclass of: Organization -
- - -
- Dentist - A dentist. - Subclass of: MedicalOrganization - Subclass of: LocalBusiness -
- -
- Hospital - A hospital. - Subclass of: CivicStructure - Subclass of: EmergencyService - Subclass of: MedicalOrganization -
- -
- Physician - A doctor's office. - Subclass of: health:MedicalOrganization -
-
- Pharmacy - A pharmacy or drugstore. - Subclass of: MedicalOrganization -
- -
- FinancialService - Financial services business. - Subclass of: LocalBusiness -
- -
- ProfessionalService - Original definition: "provider of professional services."\n\nThe general [[ProfessionalService]] type for local businesses was deprecated due to confusion with [[Service]]. For reference, the types that it included were: [[Dentist]], - [[AccountingService]], [[Attorney]], [[Notary]], as well as types for several kinds of [[HomeAndConstructionBusiness]]: [[Electrician]], [[GeneralContractor]], - [[HousePainter]], [[Locksmith]], [[Plumber]], [[RoofingContractor]]. [[LegalService]] was introduced as a more inclusive supertype of [[Attorney]]. - Subclass of: LocalBusiness -
- -
- LegalService - A LegalService is a business that provides legally-oriented services, advice and representation, e.g. law firms.\n\nAs a [[LocalBusiness]] it can be described as a [[provider]] of one or more [[Service]]\(s). - Subclass of: LocalBusiness -
- -
- AccountingService - Accountancy business.\n\nAs a [[LocalBusiness]] it can be described as a [[provider]] of one or more [[Service]]\(s). - - Subclass of: FinancialService -
- -
- AdministrativeArea - A geographical region, typically under the jurisdiction of a particular government. - Subclass of: Place -
- -
- EntertainmentBusiness - A business providing entertainment. - Subclass of: LocalBusiness -
- -
- AdultEntertainment - An adult entertainment establishment. - Subclass of: EntertainmentBusiness -
- -
- Intangible - A utility class that serves as the umbrella for a number of 'intangible' things such as quantities, structured values, etc. - Subclass of: Thing -
- -
- Offer - An offer to transfer some rights to an item or to provide a service — for example, an offer to sell tickets to an event, to rent the DVD of a movie, to stream a TV show over the internet, to repair a motorcycle, or to loan a book.\n\nFor [GTIN](http://www.gs1.org/barcodes/technical/idkeys/gtin)-related fields, see [Check Digit calculator](http://www.gs1.org/barcodes/support/check_digit_calculator) and [validation guide](http://www.gs1us.org/resources/standards/gtin-validation-guide) from [GS1](http://www.gs1.org/). - Subclass of: Intangible - Source: GoodRelationsProperties -
- -
- AggregateOffer - When a single product is associated with multiple offers (for example, the same pair of shoes is offered by different merchants), then AggregateOffer can be used. - Subclass of: Offer -
- -
- Rating - A rating is an evaluation on a numeric scale, such as 1 to 5 stars. - Subclass of: Intangible -
- -
- AggregateRating - The average rating based on multiple ratings or reviews. - Subclass of: Rating -
- -
- CivicStructure - A public structure, such as a town hall or concert hall. - Subclass of: Place -
- -
- Airport - An airport. - Subclass of: CivicStructure -
- -
- AmusementPark - An amusement park. - Subclass of: EntertainmentBusiness -
-
- AnimalShelter - Animal shelter. - Subclass of: LocalBusiness -
- -
- Residence - The place where a person lives. - Subclass of: Place -
- -
- ApartmentComplex - Residence type: Apartment complex. - Subclass of: Residence -
- - -
- Aquarium - Aquarium. - Subclass of: CivicStructure -
- -
- ArtGallery - An art gallery. - Subclass of: EntertainmentBusiness -
- - -
- Article - An article, such as a news article or piece of investigative report. Newspapers and magazines have articles of many different types and this is intended to cover them all.\n\nSee also [blog post](http://blog.schema.org/2014/09/schemaorg-support-for-bibliographic_2.html). - Subclass of: CreativeWork - Source: rNews -
- -
- Attorney - Professional service: Attorney. \n\nThis type is deprecated - [[LegalService]] is more inclusive and less ambiguous. - Subclass of: LegalService -
- -
- Audience - Intended audience for an item, i.e. the group for whom the item was created. - Subclass of: Intangible -
- -
- Researcher - Researchers. -
- -
- MediaObject - A media object, such as an image, video, or audio object embedded in a web page or a downloadable dataset i.e. DataDownload. Note that a creative work may have many media objects associated with it on the same web page. For example, a page about a single song (MusicRecording) may have a music video (VideoObject), and a high and low bandwidth audio stream (2 AudioObject's). - Subclass of: CreativeWork -
- -
- AudioObject - An audio file. - Subclass of: MediaObject - Source: rNews -
- -
- AutomotiveBusiness - Car repair, sales, or parts. - Subclass of: LocalBusiness -
- -
- AutoBodyShop - Auto body shop. - Subclass of: AutomotiveBusiness -
- -
- AutoDealer - An car dealership. - Subclass of: AutomotiveBusiness -
- -
- Store - A retail good store. - Subclass of: LocalBusiness -
- -
- AutoPartsStore - An auto parts store. - Subclass of: AutomotiveBusiness - Subclass of: Store -
- -
- AutoRental - A car rental business. - Subclass of: AutomotiveBusiness -
- -
- AutoRepair - Car repair business. - Subclass of: AutomotiveBusiness -
- -
- AutoWash - A car wash business. - Subclass of: AutomotiveBusiness -
- -
- AutomatedTeller - ATM/cash machine. - Subclass of: FinancialService -
- -
- FoodEstablishment - A food-related business. - Subclass of: LocalBusiness -
- -
- Bakery - A bakery. - Subclass of: FoodEstablishment -
- -
- BankOrCreditUnion - Bank or credit union. - Subclass of: FinancialService -
- -
- Barcode - An image of a visual machine-readable code such as a barcode or QR code. - Subclass of: ImageObject -
- -
- BarOrPub - A bar or pub. - Subclass of: FoodEstablishment -
- -
- Beach - Beach. - Subclass of: CivicStructure -
- -
- HealthAndBeautyBusiness - Health and beauty. - Subclass of: LocalBusiness -
- -
- BeautySalon - Beauty salon. - Subclass of: HealthAndBeautyBusiness -
- -
- LodgingBusiness - A lodging business, such as a motel, hotel, or inn. - Subclass of: LocalBusiness -
- -
- BedAndBreakfast - Bed and breakfast. -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: LodgingBusiness -
- -
- BikeStore - A bike store. - Subclass of: Store -
- -
- Blog - A blog. - Subclass of: CreativeWork -
- -
- BlogPosting - A blog post. - Subclass of: SocialMediaPosting -
- -
- Landform - A landform or physical feature. Landform elements include mountains, plains, lakes, rivers, seascape and oceanic waterbody interface features such as bays, peninsulas, seas and so forth, including sub-aqueous terrain features such as submersed mountain ranges, volcanoes, and the great ocean basins. - Subclass of: Place -
- -
- BodyOfWater - A body of water, such as a sea, ocean, or lake. - Subclass of: Landform -
- - -
- Book - A book. - Subclass of: CreativeWork -
- -
- BookFormatType - The publication format of the book. - Subclass of: Enumeration -
- -
- EBook - Book format: Ebook. -
- -
- Hardcover - Book format: Hardcover. -
- -
- Paperback - Book format: Paperback. -
- -
- AudiobookFormat - Book format: Audiobook. This is an enumerated value for use with the bookFormat property. There is also a type 'Audiobook' in the bib extension which includes Audiobook specific properties. -
- -
- BookStore - A bookstore. - Subclass of: Store -
- -
- DataType - The basic data types such as Integers, Strings, etc. - Subclass of: rdfs:Class - -
- -
- Boolean - Boolean: True or False. - -
- -
- False - The boolean value false. -
- -
- True - The boolean value true. -
- -
- SportsActivityLocation - A sports location, such as a playing field. - Subclass of: LocalBusiness -
- -
- BowlingAlley - A bowling alley. - Subclass of: SportsActivityLocation -
- - -
- Brewery - Brewery. - Subclass of: FoodEstablishment -
- -
- PlaceOfWorship - Place of worship, such as a church, synagogue, or mosque. - Subclass of: CivicStructure -
- -
- BuddhistTemple - A Buddhist temple. - Subclass of: PlaceOfWorship -
- -
- BusStation - A bus station. - Subclass of: CivicStructure -
- -
- BusStop - A bus stop. - Subclass of: CivicStructure -
- -
- Event - An event happening at a certain time and location, such as a concert, lecture, or festival. Ticketing information may be added via the [[offers]] property. Repeated events may be structured as separate Event objects. - Subclass of: Thing - -
- -
- BusinessEvent - Event type: Business event. - Subclass of: Event -
- -
- CafeOrCoffeeShop - A cafe or coffee shop. - Subclass of: FoodEstablishment -
- -
- Campground - A camping site, campsite, or campground is a place used for overnight stay in the outdoors. In British English a campsite is an area, usually divided into a number of pitches, where people can camp overnight using tents or camper vans or caravans; this British English use of the word is synonymous with the American English expression campground. In American English the term campsite generally means an area where an individual, family, group, or military unit can pitch a tent or parks a camper; a campground may contain many campsites (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/Campsite">http://en.wikipedia.org/wiki/Campsite</a>). -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: CivicStructure - Subclass of: LodgingBusiness - Source: STI Accommodation Ontology -
- -
- Canal - A canal, like the Panama Canal. - Subclass of: BodyOfWater -
- -
- Casino - A casino. - Subclass of: EntertainmentBusiness -
- -
- CatholicChurch - A Catholic church. - Subclass of: PlaceOfWorship -
- -
- Cemetery - A graveyard. - Subclass of: CivicStructure -
- -
- CheckoutPage - Web page type: Checkout page. - Subclass of: WebPage -
- -
- ChildCare - A Childcare center. - Subclass of: LocalBusiness -
- -
- ChildrensEvent - Event type: Children's event. - Subclass of: Event -
- -
- Church - A church. - Subclass of: PlaceOfWorship -
- -
- City - A city or town. - Subclass of: AdministrativeArea -
- -
- GovernmentBuilding - A government building. - Subclass of: CivicStructure -
- -
- CityHall - A city hall. - Subclass of: GovernmentBuilding -
- -
- ClothingStore - A clothing store. - Subclass of: Store -
- -
- CollectionPage - Web page type: Collection page. - Subclass of: WebPage -
- -
- EducationalOrganization - An educational organization. - Subclass of: Organization -
- -
- CollegeOrUniversity - A college, university, or other third-level educational institution. - Subclass of: EducationalOrganization -
- -
- ComedyClub - A comedy club. - Subclass of: EntertainmentBusiness -
- -
- ComedyEvent - Event type: Comedy event. - Subclass of: Event -
- -
- Comment - A comment on an item - for example, a comment on a blog post. The comment's content is expressed via the [[text]] property, and its topic via [[about]], properties shared with all CreativeWorks. - Subclass of: CreativeWork -
- -
- ComputerStore - A computer store. - Subclass of: Store -
- -
- ContactPage - Web page type: Contact page. - Subclass of: WebPage -
- -
- StructuredValue - Structured values are used when the value of a property has a more complex structure than simply being a textual value or a reference to another thing. - Subclass of: Intangible -
- -
- ContactPoint - A contact point&#x2014;for example, a Customer Complaints department. - Subclass of: StructuredValue -
- -
- Continent - One of the continents (for example, Europe or Africa). - Subclass of: Landform -
- -
- ConvenienceStore - A convenience store. - Subclass of: Store -
- -
- Corporation - Organization: A business corporation. - Subclass of: Organization - Source: rNews -
- -
- Country - A country. - Subclass of: AdministrativeArea -
- -
- Courthouse - A courthouse. - Subclass of: GovernmentBuilding -
- -
- Crematorium - A crematorium. - Subclass of: CivicStructure -
- -
- DanceEvent - Event type: A social dance. - Subclass of: Event -
- -
- PerformingGroup - A performance group, such as a band, an orchestra, or a circus. - Subclass of: Organization -
- -
- DanceGroup - A dance group&#x2014;for example, the Alvin Ailey Dance Theater or Riverdance. - Subclass of: PerformingGroup -
- -
- Date - A date value in [ISO 8601 date format](http://en.wikipedia.org/wiki/ISO_8601). -
- -
- DateTime - A combination of date and time of day in the form [-]CCYY-MM-DDThh:mm:ss[Z|(+|-)hh:mm] (see Chapter 5.4 of ISO 8601). -
- -
- DaySpa - A day spa. - Subclass of: HealthAndBeautyBusiness -
- -
- DefenceEstablishment - A defence establishment, such as an army or navy base. - Subclass of: GovernmentBuilding -
- -
- DepartmentStore - A department store. - Subclass of: Store -
- -
- Quantity - Quantities such as distance, time, mass, weight, etc. Particular instances of say Mass are entities like '3 Kg' or '4 milligrams'. - Subclass of: Intangible -
- -
- Distance - Properties that take Distances as values are of the form '&lt;Number&gt; &lt;Length unit of measure&gt;'. E.g., '7 ft'. - Subclass of: Quantity -
- - -
- DryCleaningOrLaundry - A dry-cleaning business. - Subclass of: LocalBusiness -
- -
- Duration - Quantity: Duration (use [ISO 8601 duration format](http://en.wikipedia.org/wiki/ISO_8601)). - Subclass of: Quantity -
- -
- EducationEvent - Event type: Education event. - Subclass of: Event -
- -
- HomeAndConstructionBusiness - A construction business.\n\nA HomeAndConstructionBusiness is a [[LocalBusiness]] that provides services around homes and buildings.\n\nAs a [[LocalBusiness]] it can be described as a [[provider]] of one or more [[Service]]\(s). - Subclass of: LocalBusiness -
- -
- Electrician - An electrician. - Subclass of: HomeAndConstructionBusiness -
- -
- ElectronicsStore - An electronics store. - Subclass of: Store -
- -
- ElementarySchool - An elementary school. - Subclass of: EducationalOrganization -
- -
- Embassy - An embassy. - Subclass of: GovernmentBuilding -
- -
- EmergencyService - An emergency service, such as a fire station or ER. - Subclass of: LocalBusiness -
- -
- EmploymentAgency - An employment agency. - Subclass of: LocalBusiness -
- -
- Energy - Properties that take Energy as values are of the form '&lt;Number&gt; &lt;Energy unit of measure&gt;'. - Subclass of: Quantity -
- -
- EventVenue - An event venue. - Subclass of: CivicStructure -
- -
- ExerciseGym - A gym. - Subclass of: SportsActivityLocation -
- -
- FastFoodRestaurant - A fast-food restaurant. - Subclass of: FoodEstablishment -
- -
- Festival - Event type: Festival. - Subclass of: Event -
- -
- FireStation - A fire station. With firemen. - Subclass of: CivicStructure - Subclass of: EmergencyService -
- -
- Number - Data type: Number. -
- -
- Float - Data type: Floating number. - Subclass of: Number -
- -
- Florist - A florist. - Subclass of: Store -
- -
- FoodEvent - Event type: Food event. - Subclass of: Event -
- -
- FurnitureStore - A furniture store. - Subclass of: Store -
- -
- GardenStore - A garden store. - Subclass of: Store -
- -
- GasStation - A gas station. - Subclass of: AutomotiveBusiness -
- -
- GatedResidenceCommunity - Residence type: Gated community. - Subclass of: Residence -
- -
- GeneralContractor - A general contractor. - Subclass of: HomeAndConstructionBusiness -
- -
- GeoCoordinates - The geographic coordinates of a place or event. - Subclass of: StructuredValue -
- -
- GeoShape - The geographic shape of a place. A GeoShape can be described using several properties whose values are based on latitude/longitude pairs. Either whitespace or commas can be used to separate latitude and longitude; whitespace should be used when writing a list of several such points. - Subclass of: StructuredValue - Source: rNews -
- -
- GeoCircle - A GeoCircle is a GeoShape representing a circular geographic area. As it is a GeoShape - it provides the simple textual property 'circle', but also allows the combination of postalCode alongside geoRadius. - The center of the circle can be indicated via the 'geoMidpoint' property, or more approximately using 'address', 'postalCode'. - - Subclass of: GeoShape -
- -
- geoRadius - Indicates the approximate radius of a GeoCircle (metres unless indicated otherwise via Distance notation). - Domain: GeoCircle - Range: Text - Range: Number - Range: Distance -
- -
- geoMidpoint - Indicates the GeoCoordinates at the centre of a GeoShape e.g. GeoCircle. - Domain: GeoShape - Range: GeoCoordinates -
- -
- GolfCourse - A golf course. - Subclass of: SportsActivityLocation -
- -
- GovernmentOffice - A government office&#x2014;for example, an IRS or DMV office. - Subclass of: LocalBusiness -
- -
- GovernmentOrganization - A governmental organization or agency. - Subclass of: Organization -
- -
- GroceryStore - A grocery store. - Subclass of: Store -
- -
- HVACBusiness - A business that provide Heating, Ventilation and Air Conditioning services. - Subclass of: HomeAndConstructionBusiness -
- -
- HairSalon - A hair salon. - Subclass of: HealthAndBeautyBusiness -
- -
- HardwareStore - A hardware store. - Subclass of: Store -
- -
- HealthClub - A health club. - Subclass of: HealthAndBeautyBusiness - Subclass of: SportsActivityLocation -
- -
- HighSchool - A high school. - Subclass of: EducationalOrganization -
- -
- HinduTemple - A Hindu temple. - Subclass of: PlaceOfWorship -
- -
- HobbyShop - A store that sells materials useful or necessary for various hobbies. - Subclass of: Store -
- -
- HomeGoodsStore - A home goods store. - Subclass of: Store -
- -
- Hostel - A hostel - cheap accommodation, often in shared dormitories. -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: LodgingBusiness -
- -
- Hotel - A hotel is an establishment that provides lodging paid on a short-term basis (Source: Wikipedia, the free encyclopedia, see http://en.wikipedia.org/wiki/Hotel). -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: LodgingBusiness - Source: STI Accommodation Ontology -
- -
- HousePainter - A house painting service. - Subclass of: HomeAndConstructionBusiness -
- -
- IceCreamShop - An ice cream shop. - Subclass of: FoodEstablishment -
- -
- ImageGallery - Web page type: Image gallery page. - Subclass of: CollectionPage -
- -
- ImageObject - An image file. - Subclass of: MediaObject - -
- -
- InsuranceAgency - An Insurance agency. - Subclass of: FinancialService -
- -
- Integer - Data type: Integer. - Subclass of: Number -
- -
- InternetCafe - An internet cafe. - Subclass of: LocalBusiness -
- -
- ItemAvailability - A list of possible product availability options. - Subclass of: Enumeration -
- -
- Discontinued - Indicates that the item has been discontinued. -
- -
- InStock - Indicates that the item is in stock. -
- -
- InStoreOnly - Indicates that the item is available only at physical locations. -
- -
- LimitedAvailability - Indicates that the item has limited availability. -
- -
- OnlineOnly - Indicates that the item is available only online. -
- -
- OutOfStock - Indicates that the item is out of stock. -
- -
- PreOrder - Indicates that the item is available for pre-order, but will be delivered when generally available. -
- -
- PreSale - Indicates that the item is available for ordering and delivery before general availability. -
- -
- SoldOut - Indicates that the item has sold out. -
- -
- ItemList - A list of items of any sort&#x2014;for example, Top 10 Movies About Weathermen, or Top 100 Party Songs. Not to be confused with HTML lists, which are often used only for formatting. - Subclass of: Intangible -
- -
- BreadcrumbList - A BreadcrumbList is an ItemList consisting of a chain of linked Web pages, typically described using at least their URL and their name, and typically ending with the current page.\n\nThe [[position]] property is used to reconstruct the order of the items in a BreadcrumbList The convention is that a breadcrumb list has an [[itemListOrder]] of [[ItemListOrderAscending]] (lower values listed first), and that the first items in this list correspond to the "top" or beginning of the breadcrumb trail, e.g. with a site or section homepage. The specific values of 'position' are not assigned meaning for a BreadcrumbList, but they should be integers, e.g. beginning with '1' for the first item in the list. - - Subclass of: ItemList -
- -
- OfferCatalog - An OfferCatalog is an ItemList that contains related Offers and/or further OfferCatalogs that are offeredBy the same provider. - Subclass of: ItemList -
- -
- hasOfferCatalog - Indicates an OfferCatalog listing for this Organization, Person, or Service. - Domain: Organization - Domain: Person - Domain: Service - Range: OfferCatalog -
- -
- ItemPage - A page devoted to a single item, such as a particular product or hotel. - Subclass of: WebPage -
- -
- JewelryStore - A jewelry store. - Subclass of: Store -
- -
- JobPosting - A listing that describes a job opening in a certain organization. - Subclass of: Intangible -
- -
- LakeBodyOfWater - A lake (for example, Lake Pontrachain). - Subclass of: BodyOfWater -
- -
- LandmarksOrHistoricalBuildings - An historical landmark or building. - Subclass of: Place -
- -
- Language - Natural languages such as Spanish, Tamil, Hindi, English, etc. Formal language code tags expressed in [BCP 47](https://en.wikipedia.org/wiki/IETF_language_tag) can be used via the [[alternateName]] property. The Language type previously also covered programming languages such as Scheme and Lisp, which are now best represented using [[ComputerLanguage]]. - Subclass of: Intangible -
- -
- ComputerLanguage - This type covers computer programming languages such as Scheme and Lisp, as well as other language-like computer representations. Natural languages are best represented with the [[Language]] type. - Subclass of: Intangible -
- -
- LegislativeBuilding - A legislative building&#x2014;for example, the state capitol. - Subclass of: GovernmentBuilding -
- -
- Library - A library. - Subclass of: LocalBusiness -
- - -
- LiquorStore - A shop that sells alcoholic drinks such as wine, beer, whisky and other spirits. - Subclass of: Store -
- -
- LiteraryEvent - Event type: Literary event. - Subclass of: Event -
- -
- Locksmith - A locksmith. - Subclass of: HomeAndConstructionBusiness -
- -
- Map - A map. - Subclass of: CreativeWork -
- -
- MapCategoryType - An enumeration of several kinds of Map. - Subclass of: Enumeration -
- -
- ParkingMap - A parking map. -
-
- SeatingMap - A seating map. -
-
- VenueMap - A venue map (e.g. for malls, auditoriums, museums, etc.). -
-
- TransitMap - A transit map. -
- -
- mapType - Indicates the kind of Map, from the MapCategoryType Enumeration. - Domain: Map - Range: MapCategoryType -
- -
- Mass - Properties that take Mass as values are of the form '&lt;Number&gt; &lt;Mass unit of measure&gt;'. E.g., '7 kg'. - Subclass of: Quantity -
- -
- PeopleAudience - A set of characteristics belonging to people, e.g. who compose an item's target audience. - Subclass of: Audience -
- -
- ScholarlyArticle - A scholarly article. - Subclass of: Article -
- -
- Specialty - Any branch of a field in which people typically develop specific expertise, usually after significant study, time, and effort. - Subclass of: Enumeration -
- -
- MensClothingStore - A men's clothing store. - Subclass of: Store -
- -
- MiddleSchool - A middle school (typically for children aged around 11-14, although this varies somewhat). - Subclass of: EducationalOrganization -
- -
- SoftwareApplication - A software application. - Subclass of: CreativeWork -
- -
- MobileApplication - A software application designed specifically to work well on a mobile device such as a telephone. - Subclass of: SoftwareApplication -
- -
- MobilePhoneStore - A store that sells mobile phones and related accessories. - Subclass of: Store -
- -
- Mosque - A mosque. - Subclass of: PlaceOfWorship -
- -
- Motel - A motel. -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: LodgingBusiness -
- -
- MotorcycleDealer - A motorcycle dealer. - Subclass of: AutomotiveBusiness -
- -
- MotorcycleRepair - A motorcycle repair shop. - Subclass of: AutomotiveBusiness -
- -
- Mountain - A mountain, like Mount Whitney or Mount Everest. - Subclass of: Landform -
- -
- Movie - A movie. - Subclass of: CreativeWork -
- -
- MovieClip - A short segment/part of a movie. - Subclass of: Clip -
- -
- MovieRentalStore - A movie rental store. - Subclass of: Store -
- -
- MovieTheater - A movie theater. - Subclass of: CivicStructure - Subclass of: EntertainmentBusiness -
- -
- MovingCompany - A moving company. - Subclass of: HomeAndConstructionBusiness -
- -
- Museum - A museum. - Subclass of: CivicStructure -
- -
- MusicPlaylist - A collection of music tracks in playlist form. - Subclass of: CreativeWork -
- -
- MusicAlbum - A collection of music tracks. - Subclass of: MusicPlaylist -
- -
- MusicEvent - Event type: Music event. - Subclass of: Event -
- -
- MusicGroup - A musical group, such as a band, an orchestra, or a choir. Can also be a solo musician. - Subclass of: PerformingGroup -
- -
- MusicRecording - A music recording (track), usually a single song. - Subclass of: CreativeWork -
- -
- MusicStore - A music store. - Subclass of: Store -
- -
- MusicVenue - A music venue. - Subclass of: CivicStructure -
- -
- MusicVideoObject - A music video file. - Subclass of: MediaObject -
- -
- NGO - Organization: Non-governmental Organization. - Subclass of: Organization -
- -
- NailSalon - A nail salon. - Subclass of: HealthAndBeautyBusiness -
- -
- NewsArticle - A NewsArticle is an article whose content reports news, or provides background context and supporting materials for understanding the news. - -A more detailed overview of [schema.org News markup](/docs/news.html) is also available. - - Subclass of: Article - Source: rNews - Source: trustproject -
- -
- NightClub - A nightclub or discotheque. - Subclass of: EntertainmentBusiness -
- -
- Photograph - A photograph. - Subclass of: CreativeWork -
-
- Notary - A notary. - Subclass of: LegalService -
- -
- OceanBodyOfWater - An ocean (for example, the Pacific). - Subclass of: BodyOfWater -
- -
- OfferItemCondition - A list of possible conditions for the item. - Subclass of: Enumeration -
- -
- DamagedCondition - Indicates that the item is damaged. -
- -
- NewCondition - Indicates that the item is new. -
- -
- RefurbishedCondition - Indicates that the item is refurbished. -
- -
- UsedCondition - Indicates that the item is used. -
- -
- OfficeEquipmentStore - An office equipment store. - Subclass of: Store -
- -
- OutletStore - An outlet store. - Subclass of: Store -
- -
- Painting - A painting. - Subclass of: CreativeWork -
- - -
- Park - A park. - Subclass of: CivicStructure -
- -
- ParkingFacility - A parking lot or other parking facility. - Subclass of: CivicStructure -
- -
- PawnShop - A shop that will buy, or lend money against the security of, personal possessions. - Subclass of: Store -
- -
- PerformingArtsTheater - A theater or other performing art center. - Subclass of: CivicStructure -
- -
- Person - A person (alive, dead, undead, or fictional). - Subclass of: Thing - - Source: rNews -
- -
- PetStore - A pet store. - Subclass of: Store -
- - -
- Playground - A playground. - Subclass of: CivicStructure -
- -
- Plumber - A plumbing service. - Subclass of: HomeAndConstructionBusiness -
- -
- PoliceStation - A police station. - Subclass of: CivicStructure - Subclass of: EmergencyService -
- -
- Pond - A pond. - Subclass of: BodyOfWater -
- -
- PostOffice - A post office. - Subclass of: GovernmentOffice -
- -
- PostalAddress - The mailing address. - Subclass of: ContactPoint -
- -
- Preschool - A preschool. - Subclass of: EducationalOrganization -
- -
- Product - Any offered product or service. For example: a pair of shoes; a concert ticket; the rental of a car; a haircut; or an episode of a TV show streamed online. - Subclass of: Thing - Source: GoodRelationsProperties -
- -
- ProfilePage - Web page type: Profile page. - Subclass of: WebPage -
- -
- PublicSwimmingPool - A public swimming pool. - Subclass of: SportsActivityLocation -
- -
- RVPark - A place offering space for "Recreational Vehicles", Caravans, mobile homes and the like. - Subclass of: CivicStructure -
- -
- RadioStation - A radio station. - Subclass of: LocalBusiness -
- -
- RealEstateAgent - A real-estate agent. - Subclass of: LocalBusiness -
- -
- RecyclingCenter - A recycling center. - Subclass of: LocalBusiness -
- -
- Reservoir - A reservoir of water, typically an artificially created lake, like the Lake Kariba reservoir. - Subclass of: BodyOfWater -
- -
- Restaurant - A restaurant. - Subclass of: FoodEstablishment -
- -
- RestrictedDiet - A diet restricted to certain foods or preparations for cultural, religious, health or lifestyle reasons. - Subclass of: Enumeration -
- -
- DiabeticDiet - A diet appropriate for people with diabetes. -
- -
- GlutenFreeDiet - A diet exclusive of gluten. -
- -
- HalalDiet - A diet conforming to Islamic dietary practices. -
- -
- HinduDiet - A diet conforming to Hindu dietary practices, in particular, beef-free. -
- -
- KosherDiet - A diet conforming to Jewish dietary practices. -
- -
- LowCalorieDiet - A diet focused on reduced calorie intake. -
- -
- LowFatDiet - A diet focused on reduced fat and cholesterol intake. -
- -
- LowLactoseDiet - A diet appropriate for people with lactose intolerance. -
- -
- LowSaltDiet - A diet focused on reduced sodium intake. -
- -
- VeganDiet - A diet exclusive of all animal products. -
- -
- VegetarianDiet - A diet exclusive of animal meat. -
- -
- Review - A review of an item - for example, of a restaurant, movie, or store. - Subclass of: CreativeWork -
- -
- RiverBodyOfWater - A river (for example, the broad majestic Shannon). - Subclass of: BodyOfWater -
- -
- RoofingContractor - A roofing contractor. - Subclass of: HomeAndConstructionBusiness -
- -
- SaleEvent - Event type: Sales event. - Subclass of: Event -
- -
- School - A school. - Subclass of: EducationalOrganization -
- -
- Sculpture - A piece of sculpture. - Subclass of: CreativeWork -
- -
- ScreeningEvent - A screening of a movie or other video. - Subclass of: Event -
- -
- SeaBodyOfWater - A sea (for example, the Caspian sea). - Subclass of: BodyOfWater -
- -
- SearchResultsPage - Web page type: Search results page. - Subclass of: WebPage -
- -
- SelfStorage - A self-storage facility. - Subclass of: LocalBusiness -
- -
- ShoeStore - A shoe store. - Subclass of: Store -
- -
- ShoppingCenter - A shopping center or mall. - Subclass of: LocalBusiness -
- -
- SingleFamilyResidence - Residence type: Single-family home. - Subclass of: House -
- -
- WebPageElement - A web page element, like a table or an image. - Subclass of: CreativeWork -
- -
- SiteNavigationElement - A navigation element of the page. - Subclass of: WebPageElement -
- -
- SkiResort - A ski resort. - Subclass of: SportsActivityLocation -
- -
- SocialEvent - Event type: Social event. - Subclass of: Event -
- -
- SportingGoodsStore - A sporting goods store. - Subclass of: Store -
- -
- SportsClub - A sports club. - Subclass of: SportsActivityLocation -
- -
- SportsEvent - Event type: Sports event. - Subclass of: Event -
- -
- SportsTeam - Organization: Sports team. - Subclass of: SportsOrganization -
- -
- StadiumOrArena - A stadium. - Subclass of: CivicStructure - Subclass of: SportsActivityLocation -
- -
- State - A state or province of a country. - Subclass of: AdministrativeArea -
- -
- SubwayStation - A subway station. - Subclass of: CivicStructure -
- - -
- Synagogue - A synagogue. - Subclass of: PlaceOfWorship -
- -
- Episode - A media episode (e.g. TV, radio, video game) which can be part of a series or season. - Subclass of: CreativeWork -
- -
- TVEpisode - A TV episode which can be part of a series or season. - Subclass of: Episode -
- -
- Season - A media season e.g. tv, radio, video game etc. - - Subclass of: CreativeWork -
-
- CreativeWorkSeason - A media season e.g. tv, radio, video game etc. - Subclass of: CreativeWork -
- -
- TVSeason - Season dedicated to TV broadcast and associated online delivery. - Subclass of: CreativeWork - Subclass of: CreativeWorkSeason -
- -
- Series - - A Series in schema.org is a group of related items, typically but not necessarily of the same kind. - Subclass of: CreativeWork -
- -
- CreativeWorkSeries - A CreativeWorkSeries in schema.org is a group of related items, typically but not necessarily of the same kind. CreativeWorkSeries are usually organized into some order, often chronological. Unlike [[ItemList]] which is a general purpose data structure for lists of things, the emphasis with CreativeWorkSeries is on published materials (written e.g. books and periodicals, or media such as tv, radio and games).\n\nSpecific subtypes are available for describing [[TVSeries]], [[RadioSeries]], [[MovieSeries]], [[BookSeries]], [[Periodical]] and [[VideoGameSeries]]. In each case, the [[hasPart]] / [[isPartOf]] properties can be used to relate the CreativeWorkSeries to its parts. The general CreativeWorkSeries type serves largely just to organize these more specific and practical subtypes.\n\nIt is common for properties applicable to an item from the series to be usefully applied to the containing group. Schema.org attempts to anticipate some of these cases, but publishers should be free to apply properties of the series parts to the series as a whole wherever they seem appropriate. - - Subclass of: CreativeWork -
- -
- TVSeries - CreativeWorkSeries dedicated to TV broadcast and associated online delivery. - Subclass of: CreativeWork - Subclass of: CreativeWorkSeries -
- -
- VideoGameSeries - A video game series. - Subclass of: CreativeWorkSeries -
- -
- Table - A table on a Web page. - Subclass of: WebPageElement -
- -
- TattooParlor - A tattoo parlor. - Subclass of: HealthAndBeautyBusiness -
- -
- TaxiStand - A taxi stand. - Subclass of: CivicStructure -
- -
- TelevisionStation - A television station. - Subclass of: LocalBusiness -
- -
- TennisComplex - A tennis complex. - Subclass of: SportsActivityLocation -
- -
- Text - Data type: Text. -
- -
- TheaterEvent - Event type: Theater performance. - Subclass of: Event -
- -
- TheaterGroup - A theater group or company, for example, the Royal Shakespeare Company or Druid Theatre. - Subclass of: PerformingGroup -
- -
- Time - A point in time recurring on multiple days in the form hh:mm:ss[Z|(+|-)hh:mm] (see [XML schema for details](http://www.w3.org/TR/xmlschema-2/#time)). -
- -
- TireShop - A tire shop. - Subclass of: Store -
- -
- TouristAttraction - A tourist attraction. In principle any Thing can be a [[TouristAttraction]], from a [[Mountain]] and [[LandmarksOrHistoricalBuildings]] to a [[LocalBusiness]]. This Type can be used on its own to describe a general [[TourstAttraction]], or be used as an [[additionalType]] to add tourist attraction properties to any other type. (See examples below) - Subclass of: Place - Source: Tourism - Source: IIT-CNR.it -
- -
- touristType - Attraction suitable for type(s) of tourist. eg. Children, visitors from a particular country, etc. - Domain: TouristAttraction - rangeIncludes: Audience - rangeIncludes: Text - Source: Tourism - Source: IIT-CNR.it -
- -
- TouristInformationCenter - A tourist information center. - Subclass of: LocalBusiness -
- -
- ToyStore - A toy store. - Subclass of: Store -
- -
- TrainStation - A train station. - Subclass of: CivicStructure -
- -
- TravelAgency - A travel agency. - Subclass of: LocalBusiness -
- - -
- URL - Data type: URL. - Subclass of: Text -
- -
- UserInteraction - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - Subclass of: Event - -
- -
- UserBlocks - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - Subclass of: UserInteraction - -
- -
- UserCheckins - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - Subclass of: UserInteraction - -
- -
- UserComments - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - Subclass of: UserInteraction - - Source: rNews -
- -
- UserDownloads - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - - Subclass of: UserInteraction -
- -
- UserLikes - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - - Subclass of: UserInteraction -
- -
- UserPageVisits - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - - Subclass of: UserInteraction -
- -
- UserPlays - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - - Subclass of: UserInteraction -
- -
- UserPlusOnes - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - - Subclass of: UserInteraction -
- -
- UserTweets - UserInteraction and its subtypes is an old way of talking about users interacting with pages. It is generally better to use [[Action]]-based vocabulary, alongside types such as [[Comment]]. - - Subclass of: UserInteraction -
- -
- VideoGallery - Web page type: Video gallery page. - Subclass of: CollectionPage -
- -
- VideoObject - A video file. - Subclass of: MediaObject - Source: rNews -
- -
- VisualArtsEvent - Event type: Visual arts event. - Subclass of: Event -
- - -
- ExhibitionEvent - Event type: Exhibition event, e.g. at a museum, library, archive, tradeshow, ... - Subclass of: Event -
- -
- Volcano - A volcano, like Fuji san. - Subclass of: Landform -
- -
- WPAdBlock - An advertising section of the page. - Subclass of: WebPageElement -
- -
- WPFooter - The footer section of the page. - Subclass of: WebPageElement -
- -
- WPHeader - The header section of the page. - Subclass of: WebPageElement -
- -
- WPSideBar - A sidebar section of the page. - Subclass of: WebPageElement -
- -
- Waterfall - A waterfall, like Niagara. - Subclass of: BodyOfWater -
- -
- WebApplication - Web applications. - Subclass of: SoftwareApplication -
- -
- WholesaleStore - A wholesale store. - Subclass of: Store -
- -
- Winery - A winery. - Subclass of: FoodEstablishment -
- -
- Zoo - A zoo. - Subclass of: CivicStructure -
- -
- Brand - A brand is a name used by an organization or business person for labeling a product, product group, or similar. - Subclass of: Intangible - Source: GoodRelationsClass -
- -
- BusinessEntityType - A business entity type is a conceptual entity representing the legal form, the size, the main line of business, the position in the value chain, or any combination thereof, of an organization or business person.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#Business\n* http://purl.org/goodrelations/v1#Enduser\n* http://purl.org/goodrelations/v1#PublicInstitution\n* http://purl.org/goodrelations/v1#Reseller - - Subclass of: Enumeration - Source: GoodRelationsClass -
- -
- CreditCard - A card payment method of a particular brand or name. Used to mark up a particular payment method and/or the financial product/service that supplies the card account.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#AmericanExpress\n* http://purl.org/goodrelations/v1#DinersClub\n* http://purl.org/goodrelations/v1#Discover\n* http://purl.org/goodrelations/v1#JCB\n* http://purl.org/goodrelations/v1#MasterCard\n* http://purl.org/goodrelations/v1#VISA - - Subclass of: PaymentCard - Subclass of: LoanOrCredit - Source: GoodRelationsClass - Source: FIBO
- -
- BusinessFunction - The business function specifies the type of activity or access (i.e., the bundle of rights) offered by the organization or business person through the offer. Typical are sell, rental or lease, maintenance or repair, manufacture / produce, recycle / dispose, engineering / construction, or installation. Proprietary specifications of access rights are also instances of this class.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#ConstructionInstallation\n* http://purl.org/goodrelations/v1#Dispose\n* http://purl.org/goodrelations/v1#LeaseOut\n* http://purl.org/goodrelations/v1#Maintain\n* http://purl.org/goodrelations/v1#ProvideService\n* http://purl.org/goodrelations/v1#Repair\n* http://purl.org/goodrelations/v1#Sell\n* http://purl.org/goodrelations/v1#Buy - - Subclass of: Enumeration - Source: GoodRelationsClass -
- -
- PaymentMethod - A payment method is a standardized procedure for transferring the monetary amount for a purchase. Payment methods are characterized by the legal and technical structures used, and by the organization or group carrying out the transaction.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#ByBankTransferInAdvance\n* http://purl.org/goodrelations/v1#ByInvoice\n* http://purl.org/goodrelations/v1#Cash\n* http://purl.org/goodrelations/v1#CheckInAdvance\n* http://purl.org/goodrelations/v1#COD\n* http://purl.org/goodrelations/v1#DirectDebit\n* http://purl.org/goodrelations/v1#GoogleCheckout\n* http://purl.org/goodrelations/v1#PayPal\n* http://purl.org/goodrelations/v1#PaySwarm - - Subclass of: Enumeration - Source: GoodRelationsClass -
- -
- DayOfWeek - The day of the week, e.g. used to specify to which day the opening hours of an OpeningHoursSpecification refer. - -Originally, URLs from [GoodRelations](http://purl.org/goodrelations/v1) were used (for [[Monday]], [[Tuesday]], [[Wednesday]], [[Thursday]], [[Friday]], [[Saturday]], [[Sunday]] plus a special entry for [[PublicHolidays]]); these have now been integrated directly into schema.org. - - Subclass of: Enumeration - Source: GoodRelationsClass -
- -
- PriceSpecification - A structured value representing a price or price range. Typically, only the subclasses of this type are used for markup. It is recommended to use [[MonetaryAmount]] to describe independent amounts of money such as a salary, credit card limits, etc. - Subclass of: StructuredValue - Source: GoodRelationsClass -
- -
- DeliveryChargeSpecification - The price for the delivery of an offer using a particular delivery method. - Subclass of: PriceSpecification - Source: GoodRelationsClass -
- -
- DeliveryMethod - A delivery method is a standardized procedure for transferring the product or service to the destination of fulfillment chosen by the customer. Delivery methods are characterized by the means of transportation used, and by the organization or group that is the contracting party for the sending organization or person.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#DeliveryModeDirectDownload\n* http://purl.org/goodrelations/v1#DeliveryModeFreight\n* http://purl.org/goodrelations/v1#DeliveryModeMail\n* http://purl.org/goodrelations/v1#DeliveryModeOwnFleet\n* http://purl.org/goodrelations/v1#DeliveryModePickUp\n* http://purl.org/goodrelations/v1#DHL\n* http://purl.org/goodrelations/v1#FederalExpress\n* http://purl.org/goodrelations/v1#UPS - - Subclass of: Enumeration - Source: GoodRelationsClass -
- -
- Demand - A demand entity represents the public, not necessarily binding, not necessarily exclusive, announcement by an organization or person to seek a certain type of goods or services. For describing demand using this type, the very same properties used for Offer apply. - Subclass of: Intangible - Source: GoodRelationsClass -
- -
- IndividualProduct - A single, identifiable product instance (e.g. a laptop with a particular serial number). - Subclass of: Product - Source: GoodRelationsClass -
- -
- OpeningHoursSpecification - A structured value providing information about the opening hours of a place or a certain service inside a place.\n\n -The place is __open__ if the [[opens]] property is specified, and __closed__ otherwise.\n\nIf the value for the [[closes]] property is less than the value for the [[opens]] property then the hour range is assumed to span over the next day. - - Subclass of: StructuredValue - Source: GoodRelationsClass -
- -
- OwnershipInfo - A structured value providing information about when a certain organization or person owned a certain product. - Subclass of: StructuredValue - Source: GoodRelationsClass -
- -
- ParcelService - A private parcel service as the delivery mode available for a certain offer.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#DHL\n* http://purl.org/goodrelations/v1#FederalExpress\n* http://purl.org/goodrelations/v1#UPS - - Subclass of: DeliveryMethod - Source: GoodRelationsClass -
- -
- PaymentChargeSpecification - The costs of settling the payment using a particular payment method. - Subclass of: PriceSpecification - Source: GoodRelationsClass -
- -
- ProductModel - A datasheet or vendor specification of a product (in the sense of a prototypical description). - Subclass of: Product - Source: GoodRelationsClass -
- -
- QualitativeValue - A predefined value for a product characteristic, e.g. the power cord plug type 'US' or the garment sizes 'S', 'M', 'L', and 'XL'. - Subclass of: Enumeration - Source: GoodRelationsClass -
- -
- QuantitativeValue - A point value or interval for product characteristics and other purposes. - Subclass of: StructuredValue - Source: GoodRelationsClass -
- -
- SomeProducts - A placeholder for multiple similar products of the same kind. - Subclass of: Product - Source: GoodRelationsClass -
- -
- TypeAndQuantityNode - A structured value indicating the quantity, unit of measurement, and business function of goods included in a bundle offer. - Subclass of: StructuredValue - Source: GoodRelationsClass -
- -
- UnitPriceSpecification - The price asked for a given offer by the respective organization or person. - Subclass of: PriceSpecification - Source: GoodRelationsClass -
- -
- WarrantyPromise - A structured value representing the duration and scope of services that will be provided to a customer free of charge in case of a defect or malfunction of a product. - Subclass of: StructuredValue - Source: GoodRelationsClass -
- -
- WarrantyScope - A range of of services that will be provided to a customer free of charge in case of a defect or malfunction of a product.\n\nCommonly used values:\n\n* http://purl.org/goodrelations/v1#Labor-BringIn\n* http://purl.org/goodrelations/v1#PartsAndLabor-BringIn\n* http://purl.org/goodrelations/v1#PartsAndLabor-PickUp - - Subclass of: Enumeration - Source: GoodRelationsClass
- -
- TechArticle - A technical article - Example: How-to (task) topics, step-by-step, procedural troubleshooting, specifications, etc. - Subclass of: Article -
- -
- APIReference - Reference documentation for application programming interfaces (APIs). - Subclass of: TechArticle -
- -
- Code - - Computer programming source code. Example: Full (compile ready) solutions, code snippet samples, scripts, templates. - Subclass of: CreativeWork -
-
- SoftwareSourceCode - Computer programming source code. Example: Full (compile ready) solutions, code snippet samples, scripts, templates. - Subclass of: CreativeWork -
- -
- ParentAudience - A set of characteristics describing parents, who can be interested in viewing some content. - Subclass of: PeopleAudience -
- -
- AlignmentObject - An intangible item that describes an alignment between a learning resource and a node in an educational framework. - Subclass of: Intangible - Source: LRMIClass
- -
- EducationalAudience - An EducationalAudience. - Subclass of: Audience - Source: LRMIClass
- -
- DataCatalog - A collection of datasets. - Subclass of: CreativeWork - Source: DatasetClass - -
- -
- DataDownload - A dataset in downloadable form. - Subclass of: MediaObject - Source: DatasetClass - -
- -
- Dataset - A body of structured information describing some topic(s) of interest. - Subclass of: CreativeWork - Source: DatasetClass - - - -
- -
- PublicationEvent - A PublicationEvent corresponds indifferently to the event of publication for a CreativeWork of any type e.g. a broadcast event, an on-demand event, a book/journal publication via a variety of delivery media. - Subclass of: Event -
- -
- BroadcastEvent - An over the air or online broadcast event. - Subclass of: PublicationEvent -
- -
- BroadcastService - A delivery service through which content is provided via broadcast over the air or online. - Subclass of: Service -
- -
- Clip - A short TV or radio program or a segment/part of a program. - Subclass of: CreativeWork -
- -
- OnDemandEvent - A publication event e.g. catch-up TV or radio podcast, during which a program is available on-demand. - Subclass of: PublicationEvent -
- -
- RadioClip - A short radio program or a segment/part of a radio program. - Subclass of: Clip -
- -
- RadioEpisode - A radio episode which can be part of a series or season. - Subclass of: Episode -
- -
- RadioSeason - Season dedicated to radio broadcast and associated online delivery. - Subclass of: CreativeWorkSeason -
- -
- RadioSeries - CreativeWorkSeries dedicated to radio broadcast and associated online delivery. - Subclass of: CreativeWorkSeries -
- -
- TVClip - A short TV program or a segment/part of a TV program. - Subclass of: Clip -
- -
- BusinessAudience - A set of characteristics belonging to businesses, e.g. who compose an item's target audience. - Subclass of: Audience -
- -
- ContactPointOption - Enumerated options related to a ContactPoint. - Subclass of: Enumeration -
- -
- HearingImpairedSupported - Uses devices to support users with hearing impairments. -
- -
- TollFree - The associated telephone number is toll free. -
- -
- Permit - A permit issued by an organization, e.g. a parking pass. - Subclass of: Intangible -
- -
- GovernmentPermit - A permit issued by a government agency. - Subclass of: Permit -
- -
- Service - A service provided by an organization, e.g. delivery service, print services, etc. - Subclass of: Intangible -
- -
- GovernmentService - A service provided by a government organization, e.g. food stamps, veterans benefits, etc. - Subclass of: Service -
- -
- ServiceChannel - A means for accessing a service, e.g. a government office location, web site, or phone number. - Subclass of: Intangible -
- -
- EventStatusType - EventStatusType is an enumeration type whose instances represent several states that an Event may be in. - Subclass of: Enumeration -
- -
- EventCancelled - The event has been cancelled. If the event has multiple startDate values, all are assumed to be cancelled. Either startDate or previousStartDate may be used to specify the event's cancelled date(s). -
- -
- EventPostponed - The event has been postponed and no new date has been set. The event's previousStartDate should be set. -
- -
- EventRescheduled - The event has been rescheduled. The event's previousStartDate should be set to the old date and the startDate should be set to the event's new date. (If the event has been rescheduled multiple times, the previousStartDate property may be repeated). -
- -
- EventScheduled - The event is taking place or has taken place on the startDate as scheduled. Use of this value is optional, as it is assumed by default. -
- -
- DeliveryEvent - An event involving the delivery of an item. - Subclass of: Event -
- -
- LockerDelivery - A DeliveryMethod in which an item is made available via locker. - Subclass of: DeliveryMethod -
- -
- OnSitePickup - A DeliveryMethod in which an item is collected on site, e.g. in a store or at a box office. -
- -
- Order - An order is a confirmation of a transaction (a receipt), which can contain multiple line items, each represented by an Offer that has been accepted by the customer. - Subclass of: Intangible -
- -
- OrderStatus - Enumerated status values for Order. - Subclass of: Enumeration -
- -
- OrderCancelled - OrderStatus representing cancellation of an order. -
- -
- OrderDelivered - OrderStatus representing successful delivery of an order. -
- -
- OrderInTransit - OrderStatus representing that an order is in transit. -
- -
- OrderPaymentDue - OrderStatus representing that payment is due on an order. -
- -
- OrderPickupAvailable - OrderStatus representing availability of an order for pickup. -
- -
- OrderProblem - OrderStatus representing that there is a problem with the order. -
- -
- OrderProcessing - OrderStatus representing that an order is being processed. -
- -
- OrderReturned - OrderStatus representing that an order has been returned. -
- -
- ParcelDelivery - The delivery of a parcel either via the postal service or a commercial service. - Subclass of: Intangible -
- -
- OrderItem - An order item is a line of an order. It includes the quantity and shipping details of a bought offer. - Subclass of: Intangible -
-
- orderQuantity - The number of the item ordered. If the property is not set, assume the quantity is one. - Domain: OrderItem - Range: Number -
-
- orderItemStatus - The current status of the order item. - Domain: OrderItem - Range: OrderStatus -
-
- orderItemNumber - The identifier of the order item. - Domain: OrderItem - Range: Text -
-
- orderDelivery - The delivery of the parcel related to this order or order item. - Domain: Order - Domain: OrderItem - Range: ParcelDelivery -
-
- Action - An action performed by a direct agent and indirect participants upon a direct object. Optionally happens at a location with the help of an inanimate instrument. The execution of the action may produce a result. Specific action sub-type documentation specifies the exact expectation of each argument/role.\n\nSee also [blog post](http://blog.schema.org/2014/04/announcing-schemaorg-actions.html) and [Actions overview document](http://schema.org/docs/actions.html). - Subclass of: Thing - Source: Action collaborations -
- -
- OrganizeAction - The act of manipulating/administering/supervising/controlling one or more objects. - Subclass of: Action -
- -
- AllocateAction - The act of organizing tasks/objects/events by associating resources to it. - Subclass of: OrganizeAction -
- -
- AcceptAction - The act of committing to/adopting an object.\n\nRelated actions:\n\n* [[RejectAction]]: The antonym of AcceptAction. - Subclass of: AllocateAction -
- -
- AchieveAction - The act of accomplishing something via previous efforts. It is an instantaneous action rather than an ongoing process. - Subclass of: Action -
- -
- UpdateAction - The act of managing by changing/editing the state of the object. - Subclass of: Action -
- -
- AddAction - The act of editing by adding an object to a collection. - Subclass of: UpdateAction -
- -
- AssessAction - The act of forming one's opinion, reaction or sentiment. - Subclass of: Action -
- -
- ReactAction - The act of responding instinctively and emotionally to an object, expressing a sentiment. - Subclass of: AssessAction -
- -
- AgreeAction - The act of expressing a consistency of opinion with the object. An agent agrees to/about an object (a proposition, topic or theme) with participants. - Subclass of: ReactAction -
- -
- InsertAction - The act of adding at a specific location in an ordered collection. - Subclass of: AddAction -
- -
- AppendAction - The act of inserting at the end if an ordered collection. - Subclass of: InsertAction -
- -
- ApplyAction - The act of registering to an organization/service without the guarantee to receive it.\n\nRelated actions:\n\n* [[RegisterAction]]: Unlike RegisterAction, ApplyAction has no guarantees that the application will be accepted. - Subclass of: OrganizeAction -
- -
- MoveAction - The act of an agent relocating to a place.\n\nRelated actions:\n\n* [[TransferAction]]: Unlike TransferAction, the subject of the move is a living Person or Organization rather than an inanimate object. - Subclass of: Action -
- -
- ArriveAction - The act of arriving at a place. An agent arrives at a destination from a fromLocation, optionally with participants. - Subclass of: MoveAction -
- -
- InteractAction - The act of interacting with another person or organization. - Subclass of: Action -
- -
- CommunicateAction - The act of conveying information to another person via a communication medium (instrument) such as speech, email, or telephone conversation. - Subclass of: InteractAction -
- -
- AskAction - The act of posing a question / favor to someone.\n\nRelated actions:\n\n* [[ReplyAction]]: Appears generally as a response to AskAction. - Subclass of: CommunicateAction -
- -
- AssignAction - The act of allocating an action/event/task to some destination (someone or something). - Subclass of: AllocateAction -
- -
- AuthorizeAction - The act of granting permission to an object. - Subclass of: AllocateAction -
- -
- BefriendAction - The act of forming a personal connection with someone (object) mutually/bidirectionally/symmetrically.\n\nRelated actions:\n\n* [[FollowAction]]: Unlike FollowAction, BefriendAction implies that the connection is reciprocal. - Subclass of: InteractAction -
- -
- BookmarkAction - An agent bookmarks/flags/labels/tags/marks an object. - Subclass of: OrganizeAction -
- -
- TransferAction - The act of transferring/moving (abstract or concrete) animate or inanimate objects from one place to another. - Subclass of: Action -
- -
- BorrowAction - The act of obtaining an object under an agreement to return it at a later date. Reciprocal of LendAction.\n\nRelated actions:\n\n* [[LendAction]]: Reciprocal of BorrowAction. - Subclass of: TransferAction -
- -
- TradeAction - The act of participating in an exchange of goods and services for monetary compensation. An agent trades an object, product or service with a participant in exchange for a one time or periodic payment. - Subclass of: Action -
- -
- BuyAction - The act of giving money to a seller in exchange for goods or services rendered. An agent buys an object, product, or service from a seller for a price. Reciprocal of SellAction. - Subclass of: TradeAction -
- -
- PlanAction - The act of planning the execution of an event/task/action/reservation/plan to a future date. - Subclass of: OrganizeAction -
- -
- CancelAction - The act of asserting that a future event/action is no longer going to happen.\n\nRelated actions:\n\n* [[ConfirmAction]]: The antonym of CancelAction. - Subclass of: PlanAction -
- -
- FindAction - The act of finding an object.\n\nRelated actions:\n\n* [[SearchAction]]: FindAction is generally lead by a SearchAction, but not necessarily. - Subclass of: Action -
- -
- CheckAction - An agent inspects, determines, investigates, inquires, or examines an object's accuracy, quality, condition, or state. - Subclass of: FindAction -
- -
- CheckInAction - The act of an agent communicating (service provider, social media, etc) their arrival by registering/confirming for a previously reserved service (e.g. flight check in) or at a place (e.g. hotel), possibly resulting in a result (boarding pass, etc).\n\nRelated actions:\n\n* [[CheckOutAction]]: The antonym of CheckInAction.\n* [[ArriveAction]]: Unlike ArriveAction, CheckInAction implies that the agent is informing/confirming the start of a previously reserved service.\n* [[ConfirmAction]]: Unlike ConfirmAction, CheckInAction implies that the agent is informing/confirming the *start* of a previously reserved service rather than its validity/existence. - Subclass of: CommunicateAction -
- -
- CheckOutAction - The act of an agent communicating (service provider, social media, etc) their departure of a previously reserved service (e.g. flight check in) or place (e.g. hotel).\n\nRelated actions:\n\n* [[CheckInAction]]: The antonym of CheckOutAction.\n* [[DepartAction]]: Unlike DepartAction, CheckOutAction implies that the agent is informing/confirming the end of a previously reserved service.\n* [[CancelAction]]: Unlike CancelAction, CheckOutAction implies that the agent is informing/confirming the end of a previously reserved service. - Subclass of: CommunicateAction -
- -
- ChooseAction - The act of expressing a preference from a set of options or a large or unbounded set of choices/options. - Subclass of: AssessAction -
- -
- CommentAction - The act of generating a comment about a subject. - Subclass of: CommunicateAction -
- -
- InformAction - The act of notifying someone of information pertinent to them, with no expectation of a response. - Subclass of: CommunicateAction -
- -
- ConfirmAction - The act of notifying someone that a future event/action is going to happen as expected.\n\nRelated actions:\n\n* [[CancelAction]]: The antonym of ConfirmAction. - Subclass of: InformAction -
- -
- ConsumeAction - The act of ingesting information/resources/food. - Subclass of: Action -
- -
- CreateAction - The act of deliberately creating/producing/generating/building a result out of the agent. - Subclass of: Action -
- -
- CookAction - The act of producing/preparing food. - Subclass of: CreateAction -
- -
- DeleteAction - The act of editing a recipient by removing one of its objects. - Subclass of: UpdateAction -
- -
- DepartAction - The act of departing from a place. An agent departs from an fromLocation for a destination, optionally with participants. - Subclass of: MoveAction -
- -
- DisagreeAction - The act of expressing a difference of opinion with the object. An agent disagrees to/about an object (a proposition, topic or theme) with participants. - Subclass of: ReactAction -
- -
- DiscoverAction - The act of discovering/finding an object. - Subclass of: FindAction -
- -
- DislikeAction - The act of expressing a negative sentiment about the object. An agent dislikes an object (a proposition, topic or theme) with participants. - Subclass of: ReactAction -
- -
- DonateAction - The act of providing goods, services, or money without compensation, often for philanthropic reasons. - Subclass of: TradeAction -
- -
- DownloadAction - The act of downloading an object. - Subclass of: TransferAction -
- -
- DrawAction - The act of producing a visual/graphical representation of an object, typically with a pen/pencil and paper as instruments. - Subclass of: CreateAction -
- -
- DrinkAction - The act of swallowing liquids. - Subclass of: ConsumeAction -
- -
- EatAction - The act of swallowing solid objects. - Subclass of: ConsumeAction -
- -
- EndorseAction - An agent approves/certifies/likes/supports/sanction an object. - Subclass of: ReactAction -
- -
- ControlAction - An agent controls a device or application. - Subclass of: Action -
- -
- ActivateAction - The act of starting or activating a device or application (e.g. starting a timer or turning on a flashlight). - Subclass of: ControlAction -
- -
- DeactivateAction - The act of stopping or deactivating a device or application (e.g. stopping a timer or turning off a flashlight). - Subclass of: ControlAction -
- -
- ResumeAction - The act of resuming a device or application which was formerly paused (e.g. resume music playback or resume a timer). - Subclass of: ControlAction -
- -
- SuspendAction - The act of momentarily pausing a device or application (e.g. pause music playback or pause a timer). - Subclass of: ControlAction -
- -
- PlayAction - The act of playing/exercising/training/performing for enjoyment, leisure, recreation, Competition or exercise.\n\nRelated actions:\n\n* [[ListenAction]]: Unlike ListenAction (which is under ConsumeAction), PlayAction refers to performing for an audience or at an event, rather than consuming music.\n* [[WatchAction]]: Unlike WatchAction (which is under ConsumeAction), PlayAction refers to showing/displaying for an audience or at an event, rather than consuming visual content. - Subclass of: Action -
-
- ExerciseAction - The act of participating in exertive activity for the purposes of improving health and fitness. - Subclass of: PlayAction -
-
- FilmAction - The act of capturing sound and moving images on film, video, or digitally. - Subclass of: CreateAction -
- -
- FollowAction - The act of forming a personal connection with someone/something (object) unidirectionally/asymmetrically to get updates polled from.\n\nRelated actions:\n\n* [[BefriendAction]]: Unlike BefriendAction, FollowAction implies that the connection is *not* necessarily reciprocal.\n* [[SubscribeAction]]: Unlike SubscribeAction, FollowAction implies that the follower acts as an active agent constantly/actively polling for updates.\n* [[RegisterAction]]: Unlike RegisterAction, FollowAction implies that the agent is interested in continuing receiving updates from the object.\n* [[JoinAction]]: Unlike JoinAction, FollowAction implies that the agent is interested in getting updates from the object.\n* [[TrackAction]]: Unlike TrackAction, FollowAction refers to the polling of updates of all aspects of animate objects rather than the location of inanimate objects (e.g. you track a package, but you don't follow it). - Subclass of: InteractAction -
- -
- GiveAction - The act of transferring ownership of an object to a destination. Reciprocal of TakeAction.\n\nRelated actions:\n\n* [[TakeAction]]: Reciprocal of GiveAction.\n* [[SendAction]]: Unlike SendAction, GiveAction implies that ownership is being transferred (e.g. I may send my laptop to you, but that doesn't mean I'm giving it to you). - Subclass of: TransferAction -
- -
- IgnoreAction - The act of intentionally disregarding the object. An agent ignores an object. - Subclass of: AssessAction -
- -
- InstallAction - The act of installing an application. - Subclass of: ConsumeAction -
- -
- InviteAction - The act of asking someone to attend an event. Reciprocal of RsvpAction. - Subclass of: CommunicateAction -
- -
- JoinAction - An agent joins an event/group with participants/friends at a location.\n\nRelated actions:\n\n* [[RegisterAction]]: Unlike RegisterAction, JoinAction refers to joining a group/team of people.\n* [[SubscribeAction]]: Unlike SubscribeAction, JoinAction does not imply that you'll be receiving updates.\n* [[FollowAction]]: Unlike FollowAction, JoinAction does not imply that you'll be polling for updates. - Subclass of: InteractAction -
- -
- LeaveAction - An agent leaves an event / group with participants/friends at a location.\n\nRelated actions:\n\n* [[JoinAction]]: The antonym of LeaveAction.\n* [[UnRegisterAction]]: Unlike UnRegisterAction, LeaveAction implies leaving a group/team of people rather than a service. - Subclass of: InteractAction -
- -
- LendAction - The act of providing an object under an agreement that it will be returned at a later date. Reciprocal of BorrowAction.\n\nRelated actions:\n\n* [[BorrowAction]]: Reciprocal of LendAction. - Subclass of: TransferAction -
- -
- LikeAction - The act of expressing a positive sentiment about the object. An agent likes an object (a proposition, topic or theme) with participants. - Subclass of: ReactAction -
- -
- ListenAction - The act of consuming audio content. - Subclass of: ConsumeAction -
- -
- LoseAction - The act of being defeated in a competitive activity. - Subclass of: AchieveAction -
- -
- MarryAction - The act of marrying a person. - Subclass of: InteractAction -
- -
- OrderAction - An agent orders an object/product/service to be delivered/sent. - Subclass of: TradeAction -
- -
- PaintAction - The act of producing a painting, typically with paint and canvas as instruments. - Subclass of: CreateAction -
- -
- PayAction - An agent pays a price to a participant. - Subclass of: TradeAction -
- -
- PerformAction - The act of participating in performance arts. - Subclass of: PlayAction -
- -
- PhotographAction - The act of capturing still images of objects using a camera. - Subclass of: CreateAction -
- -
- PrependAction - The act of inserting at the beginning if an ordered collection. - Subclass of: InsertAction -
- -
- QuoteAction - An agent quotes/estimates/appraises an object/product/service with a price at a location/store. - Subclass of: TradeAction -
- -
- ReadAction - The act of consuming written content. - Subclass of: ConsumeAction -
- -
- ReceiveAction - The act of physically/electronically taking delivery of an object thathas been transferred from an origin to a destination. Reciprocal of SendAction.\n\nRelated actions:\n\n* [[SendAction]]: The reciprocal of ReceiveAction.\n* [[TakeAction]]: Unlike TakeAction, ReceiveAction does not imply that the ownership has been transferred (e.g. I can receive a package, but it does not mean the package is now mine). - Subclass of: TransferAction -
- -
- RegisterAction - The act of registering to be a user of a service, product or web page.\n\nRelated actions:\n\n* [[JoinAction]]: Unlike JoinAction, RegisterAction implies you are registering to be a user of a service, *not* a group/team of people.\n* [FollowAction]]: Unlike FollowAction, RegisterAction doesn't imply that the agent is expecting to poll for updates from the object.\n* [[SubscribeAction]]: Unlike SubscribeAction, RegisterAction doesn't imply that the agent is expecting updates from the object. - Subclass of: InteractAction -
- -
- RejectAction - The act of rejecting to/adopting an object.\n\nRelated actions:\n\n* [[AcceptAction]]: The antonym of RejectAction. - Subclass of: AllocateAction -
- -
- RentAction - The act of giving money in return for temporary use, but not ownership, of an object such as a vehicle or property. For example, an agent rents a property from a landlord in exchange for a periodic payment. - Subclass of: TradeAction -
- -
- ReplaceAction - The act of editing a recipient by replacing an old object with a new object. - Subclass of: UpdateAction -
- -
- ReplyAction - The act of responding to a question/message asked/sent by the object. Related to [[AskAction]]\n\nRelated actions:\n\n* [[AskAction]]: Appears generally as an origin of a ReplyAction. - Subclass of: CommunicateAction -
- -
- ReserveAction - Reserving a concrete object.\n\nRelated actions:\n\n* [[ScheduleAction]]</a>: Unlike ScheduleAction, ReserveAction reserves concrete objects (e.g. a table, a hotel) towards a time slot / spatial allocation. - Subclass of: PlanAction -
- -
- ReturnAction - The act of returning to the origin that which was previously received (concrete objects) or taken (ownership). - Subclass of: TransferAction -
- -
- ReviewAction - The act of producing a balanced opinion about the object for an audience. An agent reviews an object with participants resulting in a review. - Subclass of: AssessAction -
- -
- RsvpAction - The act of notifying an event organizer as to whether you expect to attend the event. - Subclass of: InformAction -
- -
- additionalNumberOfGuests - If responding yes, the number of guests who will attend in addition to the invitee. - Domain: RsvpAction - Range: Number -
- -
- rsvpResponse - The response (yes, no, maybe) to the RSVP. - Domain: RsvpAction - Range: RsvpResponseType -
- -
- RsvpResponseType - RsvpResponseType is an enumeration type whose instances represent responding to an RSVP request. - Subclass of: Enumeration -
- -
- RsvpResponseYes - The invitee will attend. -
-
- RsvpResponseNo - The invitee will not attend. -
-
- RsvpResponseMaybe - The invitee may or may not attend. -
- -
- ScheduleAction - Scheduling future actions, events, or tasks.\n\nRelated actions:\n\n* [[ReserveAction]]: Unlike ReserveAction, ScheduleAction allocates future actions (e.g. an event, a task, etc) towards a time slot / spatial allocation. - Subclass of: PlanAction -
- -
- SearchAction - The act of searching for an object.\n\nRelated actions:\n\n* [[FindAction]]: SearchAction generally leads to a FindAction, but not necessarily. - Subclass of: Action -
- -
- SellAction - The act of taking money from a buyer in exchange for goods or services rendered. An agent sells an object, product, or service to a buyer for a price. Reciprocal of BuyAction. - Subclass of: TradeAction -
- -
- SendAction - The act of physically/electronically dispatching an object for transfer from an origin to a destination.Related actions:\n\n* [[ReceiveAction]]: The reciprocal of SendAction.\n* [[GiveAction]]: Unlike GiveAction, SendAction does not imply the transfer of ownership (e.g. I can send you my laptop, but I'm not necessarily giving it to you). - Subclass of: TransferAction -
- -
- ShareAction - The act of distributing content to people for their amusement or edification. - Subclass of: CommunicateAction -
- -
- SubscribeAction - The act of forming a personal connection with someone/something (object) unidirectionally/asymmetrically to get updates pushed to.\n\nRelated actions:\n\n* [[FollowAction]]: Unlike FollowAction, SubscribeAction implies that the subscriber acts as a passive agent being constantly/actively pushed for updates.\n* [[RegisterAction]]: Unlike RegisterAction, SubscribeAction implies that the agent is interested in continuing receiving updates from the object.\n* [[JoinAction]]: Unlike JoinAction, SubscribeAction implies that the agent is interested in continuing receiving updates from the object. - Subclass of: InteractAction -
- -
- TakeAction - The act of gaining ownership of an object from an origin. Reciprocal of GiveAction.\n\nRelated actions:\n\n* [[GiveAction]]: The reciprocal of TakeAction.\n* [[ReceiveAction]]: Unlike ReceiveAction, TakeAction implies that ownership has been transferred. - Subclass of: TransferAction -
- -
- TieAction - The act of reaching a draw in a competitive activity. - Subclass of: AchieveAction -
- -
- TipAction - The act of giving money voluntarily to a beneficiary in recognition of services rendered. - Subclass of: TradeAction -
- -
- TrackAction - An agent tracks an object for updates.\n\nRelated actions:\n\n* [[FollowAction]]: Unlike FollowAction, TrackAction refers to the interest on the location of innanimates objects.\n* [[SubscribeAction]]: Unlike SubscribeAction, TrackAction refers to the interest on the location of innanimate objects. - Subclass of: FindAction -
- -
- TravelAction - The act of traveling from an fromLocation to a destination by a specified mode of transport, optionally with participants. - Subclass of: MoveAction -
- -
- UnRegisterAction - The act of un-registering from a service.\n\nRelated actions:\n\n* [[RegisterAction]]: antonym of UnRegisterAction.\n* [[Leave]]: Unlike LeaveAction, UnRegisterAction implies that you are unregistering from a service you werer previously registered, rather than leaving a team/group of people. - Subclass of: InteractAction -
- -
- UseAction - The act of applying an object to its intended purpose. - Subclass of: ConsumeAction -
- -
- ViewAction - The act of consuming static visual content. - Subclass of: ConsumeAction -
- -
- VoteAction - The act of expressing a preference from a fixed/finite/structured set of choices/options. - Subclass of: ChooseAction -
- -
- WantAction - The act of expressing a desire about the object. An agent wants an object. - Subclass of: ReactAction -
- -
- WatchAction - The act of consuming dynamic/moving visual content. - Subclass of: ConsumeAction -
- -
- WearAction - The act of dressing oneself in clothing. - Subclass of: UseAction -
- -
- WinAction - The act of achieving victory in a competitive activity. - Subclass of: AchieveAction -
- -
- WriteAction - The act of authoring written creative content. - Subclass of: CreateAction -
- -
- schemaVersion - Indicates (by URL or string) a particular version of a schema used in some CreativeWork. For example, a document could declare a schemaVersion using an URL such as http://schema.org/version/2.0/ if precise indication of schema version was required by some application. - Domain: CreativeWork - Range: URL - Range: Text -
- -
- about - The subject matter of the content. - Domain: CreativeWork - Domain: CommunicateAction - Domain: Event - Range: Thing -
-
- acceptedOffer - The offer(s) -- e.g., product, quantity and price combinations -- included in the order. - Domain: Order - Range: Offer -
-
- acceptedPaymentMethod - The payment method(s) accepted by seller for this offer. - Domain: Offer - Domain: Demand - Range: LoanOrCredit - Range: PaymentMethod -
-
- acceptsReservations - Indicates whether a FoodEstablishment accepts reservations. Values can be Boolean, an URL at which reservations can be made or (for backwards compatibility) the strings ```Yes``` or ```No```. - Domain: FoodEstablishment - Range: Text - Range: URL - Range: Boolean -
-
- accessCode - Password, PIN, or access code needed for delivery (e.g. from a locker). - Domain: DeliveryEvent - Range: Text -
-
- accessibilityAPI - Indicates that the resource is compatible with the referenced accessibility API ([WebSchemas wiki lists possible values](http://www.w3.org/wiki/WebSchemas/Accessibility)). - Domain: CreativeWork - Range: Text -
-
- accessibilityControl - Identifies input methods that are sufficient to fully control the described resource ([WebSchemas wiki lists possible values](http://www.w3.org/wiki/WebSchemas/Accessibility)). - Domain: CreativeWork - Range: Text -
-
- accessibilityFeature - Content features of the resource, such as accessible media, alternatives and supported enhancements for accessibility ([WebSchemas wiki lists possible values](http://www.w3.org/wiki/WebSchemas/Accessibility)). - Domain: CreativeWork - Range: Text -
-
- accessibilityHazard - A characteristic of the described resource that is physiologically dangerous to some users. Related to WCAG 2.0 guideline 2.3 ([WebSchemas wiki lists possible values](http://www.w3.org/wiki/WebSchemas/Accessibility)). - Domain: CreativeWork - Range: Text -
-
- accountablePerson - Specifies the Person that is legally accountable for the CreativeWork. - Domain: CreativeWork - Range: Person -
-
- acquiredFrom - The organization or person from which the product was acquired. - Domain: OwnershipInfo - Range: Organization - Range: Person -
- -
- actor - An actor, e.g. in tv, radio, movie, video games etc., or in an event. Actors can be associated with individual items or with a series, episode, clip. - Domain: Event - Domain: Movie - Domain: VideoObject - Domain: VideoGame - Domain: Episode - Domain: CreativeWorkSeason - Domain: RadioSeries - Domain: MovieSeries - Domain: VideoGameSeries - Domain: TVSeries - Domain: Clip - Range: Person -
-
- actors - - An actor, e.g. in tv, radio, movie, video games etc. Actors can be associated with individual items or with a series, episode, clip. - Domain: Movie - Domain: VideoObject - Domain: VideoGame - Domain: Episode - Domain: RadioSeries - Domain: MovieSeries - Domain: VideoGameSeries - Domain: TVSeries - Domain: Clip - Range: Person -
-
- additionalName - An additional name for a Person, can be used for a middle name. - Domain: Person - Range: Text -
-
- additionalType - An additional type for the item, typically used for adding more specific types from external vocabularies in microdata syntax. This is a relationship between something and a class that the thing is in. In RDFa syntax, it is better to use the native RDFa syntax - the 'typeof' attribute - for multiple types. Schema.org tools may have only weaker understanding of extra types, in particular those defined externally. - - Domain: Thing - Range: URL -
- -
- addOn - An additional offer that can only be obtained in combination with the first base offer (e.g. supplements and extensions that are available for a surcharge). - Domain: Offer - Range: Offer -
-
- address - Physical address of the item. - Domain: Organization - Domain: Place - Domain: Person - Domain: GeoCoordinates - Domain: GeoShape - Range: PostalAddress - Range: Text -
-
- addressCountry - The country. For example, USA. You can also provide the two-letter [ISO 3166-1 alpha-2 country code](http://en.wikipedia.org/wiki/ISO_3166-1). - Domain: PostalAddress - Domain: GeoCoordinates - Domain: GeoShape - Range: Text - Range: Country -
-
- addressLocality - The locality. For example, Mountain View. - Domain: PostalAddress - Range: Text -
-
- addressRegion - The region. For example, CA. - Domain: PostalAddress - Range: Text -
- -
- advanceBookingRequirement - The amount of time that is required between accepting the offer and the actual usage of the resource or service. - Domain: Offer - Domain: Demand - Range: QuantitativeValue -
- -
- affiliation - An organization that this person is affiliated with. For example, a school/university, a club, or a team. - Domain: Person - Range: Organization - -
-
- agent - The direct performer or driver of the action (animate or inanimate). e.g. *John* wrote a book. - Domain: Action - Range: Organization - Range: Person -
-
- aggregateRating - The overall rating, based on a collection of reviews or ratings, of the item. - Domain: CreativeWork - Domain: Event - Domain: Brand - Domain: Service - Domain: Organization - Domain: Place - Domain: Offer - Domain: Product - Range: AggregateRating -
-
- album - A music album. - Domain: MusicGroup - Range: MusicAlbum -
-
- albums - - A collection of music albums. - Domain: MusicGroup - Range: MusicAlbum -
-
- alignmentType - A category of alignment between the learning resource and the framework node. Recommended values include: 'assesses', 'teaches', 'requires', 'textComplexity', 'readingLevel', 'educationalSubject', and 'educationalLevel'. - Domain: AlignmentObject - Range: Text -
-
- alternateName - An alias for the item. - Domain: Thing - Range: Text -
-
- alternativeHeadline - A secondary title of the CreativeWork. - Domain: CreativeWork - Range: Text -
-
- alumni - Alumni of an organization. - Domain: EducationalOrganization - Domain: EducationalOrganization - Range: Person - -
-
- alumniOf - An organization that the person is an alumni of. - Domain: Person - Range: EducationalOrganization - Range: EducationalOrganization - -
-
- amountOfThisGood - The quantity of the goods included in the offer. - Domain: TypeAndQuantityNode - Range: Number -
- -
- applicationCategory - Type of software application, e.g. 'Game, Multimedia'. - Domain: SoftwareApplication - Range: Text - Range: URL -
-
- applicationSubCategory - Subcategory of the application, e.g. 'Arcade Game'. - Domain: SoftwareApplication - Range: Text - Range: URL -
-
- applicationSuite - The name of the application suite to which the application belongs (e.g. Excel belongs to Office). - Domain: SoftwareApplication - Range: Text -
-
- appliesToDeliveryMethod - The delivery method(s) to which the delivery charge or payment charge specification applies. - Domain: DeliveryChargeSpecification - Domain: PaymentChargeSpecification - Range: DeliveryMethod -
-
- appliesToPaymentMethod - The payment method(s) to which the payment charge specification applies. - Domain: PaymentChargeSpecification - Range: PaymentMethod -
-
- area - - The area within which users can expect to reach the broadcast service. - Domain: BroadcastService - Range: Place -
-
- areaServed - The geographic area where a service or offered item is provided. - Domain: Service - Domain: Organization - Domain: ContactPoint - Domain: Demand - Domain: Offer - Domain: DeliveryChargeSpecification - Range: Place - Range: AdministrativeArea - Range: GeoShape - Range: Text -
- -
- articleBody - The actual body of the article. - Domain: Article - Range: Text -
-
- articleSection - Articles may belong to one or more 'sections' in a magazine or newspaper, such as Sports, Lifestyle, etc. - Domain: Article - Range: Text -
- -
- assembly - - Library file name e.g., mscorlib.dll, system.web.dll. - Domain: APIReference - Range: Text -
-
- executableLibraryName - Library file name e.g., mscorlib.dll, system.web.dll. - Domain: APIReference - Range: Text -
-
- assemblyVersion - Associated product/technology version. e.g., .NET Framework 4.5. - Domain: APIReference - Range: Text -
- -
- associatedArticle - A NewsArticle associated with the Media Object. - Domain: MediaObject - Range: NewsArticle -
-
- associatedMedia - A media object that encodes this CreativeWork. This property is a synonym for encoding. - Domain: CreativeWork - Range: MediaObject -
- -
- organizer - An organizer of an Event. - Domain: Event - Range: Person - Range: Organization -
-
- attendee - A person or organization attending the event. - Domain: Event - Range: Organization - Range: Person -
-
- attendees - - A person attending the event. - Domain: Event - Range: Organization - Range: Person -
-
- audience - An intended audience, i.e. a group for whom something was created. - Domain: CreativeWork - Domain: Event - Domain: Product - Domain: Service - Domain: PlayAction - Domain: LodgingBusiness - Range: Audience -
-
- audienceType - The target group associated with a given audience (e.g. veterans, car owners, musicians, etc.). - Domain: Audience - Range: Text -
-
- audio - An embedded audio object. - Domain: CreativeWork - Range: AudioObject -
-
- author - The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably. - Domain: CreativeWork - Domain: Rating - Range: Organization - Range: Person -
-
- availability - The availability of this item&#x2014;for example In stock, Out of stock, Pre-order, etc. - Domain: Offer - Domain: Demand - Range: ItemAvailability -
-
- availabilityEnds - The end of the availability of the product or service included in the offer. - Domain: Offer - Domain: Demand - Range: DateTime -
-
- availabilityStarts - The beginning of the availability of the product or service included in the offer. - Domain: Offer - Domain: Demand - Range: DateTime -
-
- availableAtOrFrom - The place(s) from which the offer can be obtained (e.g. store locations). - - Domain: Offer - Domain: Demand - Range: Place -
-
- availableChannel - A means of accessing the service (e.g. a phone bank, a web site, a location, etc.). - Domain: Service - Range: ServiceChannel -
-
- availableDeliveryMethod - The delivery method(s) available for this offer. - Domain: Offer - Domain: Demand - Range: DeliveryMethod -
-
- availableFrom - When the item is available for pickup from the store, locker, etc. - Domain: DeliveryEvent - Range: DateTime -
- -
- availableLanguage - A language someone may use with or at the item, service or place. Please use one of the language codes from the [IETF BCP 47 standard](http://tools.ietf.org/html/bcp47). See also [[inLanguage]] - Domain: ContactPoint - Domain: ServiceChannel - Domain: LodgingBusiness - Domain: TouristAttraction - Range: Language - Range: Text -
- -
- availableThrough - After this date, the item will no longer be available for pickup. - Domain: DeliveryEvent - Range: DateTime -
-
- award - An award won by or for this item. - Domain: CreativeWork - Domain: Organization - Domain: Person - Domain: Product - Domain: Service - Range: Text -
-
- awards - - Awards won by or for this item. - Domain: CreativeWork - Domain: Organization - Domain: Person - Domain: Product - Range: Text -
- -
- baseSalary - The base salary of the job or of an employee in an EmployeeRole. - Domain: JobPosting - Domain: EmployeeRole - Range: Number - Range: PriceSpecification - Range: MonetaryAmount -
-
- bccRecipient - A sub property of recipient. The recipient blind copied on a message. - - Domain: Message - Range: ContactPoint - Range: Organization - Range: Person -
-
- benefits - - Description of benefits associated with the job. - Domain: JobPosting - Range: Text -
-
- jobBenefits - Description of benefits associated with the job. - Domain: JobPosting - Range: Text -
-
- bestRating - The highest value allowed in this rating system. If bestRating is omitted, 5 is assumed. - Domain: Rating - Range: Number - Range: Text -
-
- billingAddress - The billing address for the order. - Domain: Order - Range: PostalAddress -
-
- billingIncrement - This property specifies the minimal quantity and rounding increment that will be the basis for the billing. The unit of measurement is specified by the unitCode property. - Domain: UnitPriceSpecification - Range: Number -
- -
- birthDate - Date of birth. - Domain: Person - Range: Date -
-
- bitrate - The bitrate of the media object. - Domain: MediaObject - Range: Text -
-
- blogPost - A posting that is part of this blog. - Domain: Blog - Range: BlogPosting -
-
- blogPosts - - The postings that are part of this blog. - Domain: Blog - Range: BlogPosting -
- - -
- bookEdition - The edition of the book. - Domain: Book - Range: Text -
-
- bookFormat - The format of the book. - Domain: Book - Range: BookFormatType -
-
- borrower - A sub property of participant. The person that borrows the object being lent. - - Domain: LendAction - Range: Person -
-
- box - A box is the area enclosed by the rectangle formed by two points. The first point is the lower corner, the second point is the upper corner. A box is expressed as two points separated by a space character. - Domain: GeoShape - Range: Text -
- -
- branchOf - - The larger organization that this local business is a branch of, if any. Not to be confused with (anatomical)[[branch]]. - Domain: LocalBusiness - Range: Organization -
-
- parentOrganization - The larger organization that this organization is a [[subOrganization]] of, if any. - Domain: Organization - Range: Organization - -
-
- branchCode - A short textual code (also called "store code") that uniquely identifies a place of business. The code is typically assigned by the parentOrganization and used in structured URLs.\n\nFor example, in the URL http://www.starbucks.co.uk/store-locator/etc/detail/3047 the code "3047" is a branchCode for a particular branch. - - Domain: Place - Range: Text -
-
- brand - The brand(s) associated with a product or service, or the brand(s) maintained by an organization or business person. - Domain: Organization - Domain: Person - Domain: Product - Domain: Service - Range: Brand - Range: Organization -
-
- breadcrumb - A set of links that can help a user understand and navigate a website hierarchy. - Domain: WebPage - Range: Text - Range: BreadcrumbList -
- -
- broadcaster - The organization owning or operating the broadcast service. - Domain: BroadcastService - Range: Organization -
-
- browserRequirements - Specifies browser requirements in human-readable text. For example, 'requires HTML5 support'. - Domain: WebApplication - Range: Text -
-
- businessFunction - The business function (e.g. sell, lease, repair, dispose) of the offer or component of a bundle (TypeAndQuantityNode). The default is http://purl.org/goodrelations/v1#Sell. - Domain: Offer - Domain: Demand - Domain: TypeAndQuantityNode - Range: BusinessFunction -
-
- buyer - A sub property of participant. The participant/person/organization that bought the object. - - Domain: SellAction - Range: Person -
-
- byArtist - The artist that performed this album or recording. - Domain: MusicAlbum - Domain: MusicRecording - Range: MusicGroup -
- -
- candidate - A sub property of object. The candidate subject of this action. - - Domain: VoteAction - Range: Person -
-
- caption - The caption for this object. - Domain: ImageObject - Domain: VideoObject - Range: Text -
- -
- carrier - 'carrier' is an out-dated term indicating the 'provider' for parcel delivery and flights. - Domain: ParcelDelivery - domain: Flight - Range: Organization - -
-
- carrierRequirements - Specifies specific carrier(s) requirements for the application (e.g. an application may only work on a specific carrier network). - Domain: MobileApplication - Range: Text -
-
- catalog - - A data catalog which contains this dataset. - Domain: Dataset - Range: DataCatalog -
-
- includedDataCatalog - A data catalog which contains this dataset (this property was previously 'catalog', preferred name is now 'includedInDataCatalog'). - - Domain: Dataset - Range: DataCatalog -
-
- includedInDataCatalog - A data catalog which contains this dataset. - - Domain: Dataset - Range: DataCatalog -
-
- category - A category for the item. Greater signs or slashes can be used to informally indicate a category hierarchy. - Domain: Product - Domain: Service - Domain: Offer - Domain: Invoice - Range: Text - Range: Thing -
- -
- ccRecipient - A sub property of recipient. The recipient copied on a message. - - Domain: Message - Range: ContactPoint - Range: Organization - Range: Person -
-
- childMaxAge - Maximal age of the child. - Domain: ParentAudience - Range: Number -
-
- childMinAge - Minimal age of the child. - Domain: ParentAudience - Range: Number -
-
- children - A child of the person. - Domain: Person - Range: Person -
- -
- circle - A circle is the circular region of a specified radius centered at a specified latitude and longitude. A circle is expressed as a pair followed by a radius in meters. - Domain: GeoShape - Range: Text -
-
- citation - A citation or reference to another creative work, such as another publication, web page, scholarly article, etc. - Domain: CreativeWork - Range: CreativeWork - Range: Text -
-
- clipNumber - Position of the clip within an ordered group of clips. - Domain: Clip - Range: Integer - Range: Text - -
-
- closes - The closing hour of the place or service on the given day(s) of the week. - Domain: OpeningHoursSpecification - Range: Time -
- -
- codeRepository - Link to the repository where the un-compiled, human readable code and related code is located (SVN, github, CodePlex). - Domain: SoftwareSourceCode - Range: URL -
- -
- colleague - A colleague of the person. - Domain: Person - Range: Person - Range: URL -
-
- colleagues - - A colleague of the person. - Domain: Person - Range: Person -
-
- collection - - A sub property of object. The collection target of the action. - - Domain: UpdateAction - Range: Thing -
-
- targetCollection - A sub property of object. The collection target of the action. - - Domain: UpdateAction - Range: Thing -
-
- color - The color of the product. - Domain: Product - Range: Text -
-
- comment - Comments, typically from users. - Domain: CreativeWork - Domain: RsvpAction - Range: Comment -
-
- commentText - The text of the UserComment. - Domain: UserComments - Range: Text -
-
- commentTime - The time at which the UserComment was made. - Domain: UserComments - Range: Date - Range: DateTime -
- - -
- confirmationNumber - A number that confirms the given order or payment has been received. - Domain: Order - Domain: Invoice - Range: Text -
- -
- contactOption - An option available on this contact point (e.g. a toll-free number or support for hearing-impaired callers). - Domain: ContactPoint - Range: ContactPointOption -
-
- contactPoint - A contact point for a person or organization. - Domain: Organization - Domain: Person - Range: ContactPoint -
-
- contactPoints - - A contact point for a person or organization. - Domain: Organization - Domain: Person - Range: ContactPoint -
-
- contactType - A person or organization can have different contact points, for different purposes. For example, a sales contact point, a PR contact point and so on. This property is used to specify the kind of contact point. - Domain: ContactPoint - Range: Text -
-
- containedInPlace - The basic containment relation between a place and one that contains it. - - Domain: Place - Range: Place -
- -
- containsPlace - The basic containment relation between a place and another that it contains. - - Domain: Place - Range: Place -
- -
- containedIn - The basic containment relation between a place and one that contains it. - - Domain: Place - Range: Place -
-
- contentLocation - The location depicted or described in the content. For example, the location in a photograph or painting. - Domain: CreativeWork - Range: Place -
-
- locationCreated - The location where the CreativeWork was created, which may not be the same as the location depicted in the CreativeWork. - Domain: CreativeWork - Range: Place -
-
- contentRating - Official rating of a piece of content&#x2014;for example,'MPAA PG-13'. - Domain: CreativeWork - Range: Text -
-
- contentSize - File size in (mega/kilo) bytes. - Domain: MediaObject - Range: Text -
-
- contentUrl - Actual bytes of the media object, for example the image file or video file. - Domain: MediaObject - Range: URL -
-
- expectsAcceptanceOf - An Offer which must be accepted before the user can perform the Action. For example, the user may need to buy a movie before being able to watch it. - Domain: ConsumeAction - Range: Offer -
- -
- contributor - A secondary contributor to the CreativeWork or Event. - Domain: CreativeWork - Domain: Event - Range: Organization - Range: Person -
- -
- copyrightHolder - The party holding the legal copyright to the CreativeWork. - Domain: CreativeWork - Range: Organization - Range: Person -
-
- copyrightYear - The year during which the claimed copyright for the CreativeWork was first asserted. - Domain: CreativeWork - Range: Number -
- -
- countriesNotSupported - Countries for which the application is not supported. You can also provide the two-letter ISO 3166-1 alpha-2 country code. - Domain: SoftwareApplication - Range: Text -
-
- countriesSupported - Countries for which the application is supported. You can also provide the two-letter ISO 3166-1 alpha-2 country code. - Domain: SoftwareApplication - Range: Text -
-
- course - - A sub property of location. The course where this action was taken. - - Domain: ExerciseAction - Range: Place -
-
- exerciseCourse - A sub property of location. The course where this action was taken. - - Domain: ExerciseAction - Range: Place -
-
- countryOfOrigin - The country of the principal offices of the production company or individual responsible for the movie or program. - Domain: Movie - Domain: TVEpisode - Domain: TVSeason - Domain: TVSeries - Range: Country -
-
- creator - The creator/author of this CreativeWork. This is the same as the Author property for CreativeWork. - Domain: CreativeWork - Domain: UserComments - Range: Organization - Range: Person -
-
- currenciesAccepted - The currency accepted (in [ISO 4217 currency format](http://en.wikipedia.org/wiki/ISO_4217)). - Domain: LocalBusiness - Range: Text -
-
- customer - Party placing the order or paying the invoice. - Domain: Order - Domain: Invoice - Range: Organization - Range: Person -
-
- dataset - A dataset contained in this catalog. - Domain: DataCatalog - Range: Dataset - -
-
- dateCreated - The date on which the CreativeWork was created or the item was added to a DataFeed. - Domain: CreativeWork - Domain: DataFeedItem - Range: Date - Range: DateTime -
-
- dateline - A [dateline](https://en.wikipedia.org/wiki/Dateline) is a brief piece of text included in news articles that describes where and when the story was written or filed though the date is often omitted. Sometimes only a placename is provided. - Domain: NewsArticle - Range: Text -
-
- dateDeleted - The datetime the item was removed from the DataFeed. - Domain: DataFeedItem - Range: DateTime -
-
- dateModified - The date on which the CreativeWork was most recently modified or when the item's entry was modified within a DataFeed. - Domain: CreativeWork - Domain: DataFeedItem - Range: Date - Range: DateTime -
-
- datePosted - Publication date for the job posting. - Domain: JobPosting - Range: Date -
-
- datePublished - Date of first broadcast/publication. - Domain: CreativeWork - Range: Date -
-
- dayOfWeek - The day of the week for which these opening hours are valid. - Domain: OpeningHoursSpecification - Range: DayOfWeek -
-
- deathDate - Date of death. - Domain: Person - Range: Date -
-
- deliveryAddress - Destination address. - Domain: ParcelDelivery - Range: PostalAddress -
-
- deliveryLeadTime - The typical delay between the receipt of the order and the goods either leaving the warehouse or being prepared for pickup, in case the delivery method is on site pickup. - Domain: Offer - Domain: Demand - Range: QuantitativeValue -
-
- deliveryMethod - A sub property of instrument. The method of delivery. - - Domain: OrderAction - Domain: ReceiveAction - Domain: SendAction - Domain: TrackAction - Range: DeliveryMethod -
-
- deliveryStatus - New entry added as the package passes through each leg of its journey (from shipment to final delivery). - Domain: ParcelDelivery - Range: DeliveryEvent -
-
- department - A relationship between an organization and a department of that organization, also described as an organization (allowing different urls, logos, opening hours). For example: a store with a pharmacy, or a bakery with a cafe. - Domain: Organization - Range: Organization -
-
- dependencies - Prerequisites needed to fulfill steps in article. - Domain: TechArticle - Range: Text -
-
- depth - The depth of the item. - Domain: Product - Range: Distance - Range: QuantitativeValue -
-
- description - A description of the item. - - Domain: Thing - Range: Text -
-
- device - - Device required to run the application. Used in cases where a specific make/model is required to run the application. - Domain: SoftwareApplication - Range: Text -
-
- availableOnDevice - Device required to run the application. Used in cases where a specific make/model is required to run the application. - Domain: SoftwareApplication - Range: Text -
- -
- director - A director of e.g. tv, radio, movie, video gaming etc. content, or of an event. Directors can be associated with individual items or with a series, episode, clip. - Domain: Movie - Domain: Event - Domain: VideoObject - Domain: VideoGame - Domain: Episode - Domain: CreativeWorkSeason - Domain: VideoGameSeries - Domain: TVSeries - Domain: RadioSeries - Domain: Series - - - Domain: Clip - Range: Person -
-
- directors - - A director of e.g. tv, radio, movie, video games etc. content. Directors can be associated with individual items or with a series, episode, clip. - Domain: Movie - Domain: VideoObject - Domain: VideoGame - Domain: Episode - - Domain: VideoGameSeries - Domain: TVSeries - Domain: RadioSeries - Domain: MovieSeries - - Domain: Clip - Range: Person -
-
- disambiguatingDescription - A sub property of description. A short description of the item used to disambiguate from other, similar items. Information from other properties (in particular, name) may be necessary for the description to be useful for disambiguation. - - Domain: Thing - Range: Text -
-
- discount - Any discount applied (to an Order). - Domain: Order - Range: Number - Range: Text -
-
- discountCode - Code used to redeem a discount. - Domain: Order - Range: Text -
-
- discountCurrency - The currency (in 3-letter ISO 4217 format) of the discount. - Domain: Order - Range: Text -
-
- discusses - Specifies the CreativeWork associated with the UserComment. - Domain: UserComments - Range: CreativeWork -
-
- discussionUrl - A link to the page containing the comments of the CreativeWork. - Domain: CreativeWork - Range: URL -
-
- distance - The distance travelled, e.g. exercising or travelling. - Domain: ExerciseAction - Domain: TravelAction - Range: Distance -
- -
- distribution - A downloadable form of this dataset, at a specific location, in a specific format. - Domain: Dataset - Range: DataDownload -
- -
- doorTime - The time admission will commence. - Domain: Event - Range: DateTime -
- -
- downloadUrl - If the file can be downloaded, URL to download the binary. - Domain: SoftwareApplication - Range: URL -
-
- duns - The Dun & Bradstreet DUNS number for identifying an organization or business person. - Domain: Organization - Domain: Person - Range: Text -
-
- duration - The duration of the item (movie, audio recording, event, etc.) in [ISO 8601 date format](http://en.wikipedia.org/wiki/ISO_8601). - Domain: MediaObject - Domain: Event - Domain: Movie - Domain: MusicRecording - Range: Duration -
-
- durationOfWarranty - The duration of the warranty promise. Common unitCode values are ANN for year, MON for months, or DAY for days. - Domain: WarrantyPromise - Range: QuantitativeValue -
-
- editor - Specifies the Person who edited the CreativeWork. - Domain: CreativeWork - Range: Person -
-
- educationalAlignment - An alignment to an established educational framework. - Domain: CreativeWork - Range: AlignmentObject -
-
- educationalFramework - The framework to which the resource being described is aligned. - Domain: AlignmentObject - Range: Text -
-
- educationalRole - An educationalRole of an EducationalAudience. - Domain: EducationalAudience - Range: Text -
-
- educationalUse - The purpose of a work in the context of education; for example, 'assignment', 'group work'. - Domain: CreativeWork - Range: Text -
-
- educationRequirements - Educational background needed for the position. - Domain: JobPosting - Range: Text -
-
- elevation - The elevation of a location ([WGS 84](https://en.wikipedia.org/wiki/World_Geodetic_System)). - Domain: GeoCoordinates - Domain: GeoShape - Range: Number - Range: Text -
-
- eligibleCustomerType - The type(s) of customers for which the given offer is valid. - Domain: Offer - Domain: Demand - Range: BusinessEntityType -
-
- eligibleDuration - The duration for which the given offer is valid. - Domain: Offer - Domain: Demand - Range: QuantitativeValue -
-
- eligibleQuantity - The interval and unit of measurement of ordering quantities for which the offer or price specification is valid. This allows e.g. specifying that a certain freight charge is valid only for a certain quantity. - Domain: Offer - Domain: PriceSpecification - Domain: Demand - Range: QuantitativeValue -
-
- eligibleRegion - The ISO 3166-1 (ISO 3166-1 alpha-2) or ISO 3166-2 code, the place, or the GeoShape for the geo-political region(s) for which the offer or delivery charge specification is valid.\n\nSee also [[ineligibleRegion]]. - - - Domain: Offer - Domain: DeliveryChargeSpecification - Domain: Demand - Range: GeoShape - Range: Place - Range: Text -
-
- ineligibleRegion - The ISO 3166-1 (ISO 3166-1 alpha-2) or ISO 3166-2 code, the place, or the GeoShape for the geo-political region(s) for which the offer or delivery charge specification is not valid, e.g. a region where the transaction is not allowed.\n\nSee also [[eligibleRegion]]. - - Domain: Offer - Domain: DeliveryChargeSpecification - Domain: Demand - Range: GeoShape - Range: Place - Range: Text -
-
- eligibleTransactionVolume - The transaction volume, in a monetary unit, for which the offer or price specification is valid, e.g. for indicating a minimal purchasing volume, to express free shipping above a certain order volume, or to limit the acceptance of credit cards to purchases to a certain minimal amount. - Domain: Offer - Domain: PriceSpecification - Domain: Demand - Range: PriceSpecification -
-
- email - Email address. - Domain: Organization - Domain: ContactPoint - Domain: Person - Range: Text -
-
- embedUrl - A URL pointing to a player for a specific video. In general, this is the information in the ```src``` element of an ```embed``` tag and should not be the same as the content of the ```loc``` tag. - Domain: MediaObject - Range: URL -
-
- employee - Someone working for this organization. - Domain: Organization - Range: Person -
-
- employees - - People working for this organization. - Domain: Organization - Range: Person -
-
- employmentType - Type of employment (e.g. full-time, part-time, contract, temporary, seasonal, internship). - Domain: JobPosting - Range: Text -
-
- encodesCreativeWork - The CreativeWork encoded by this media object. - Domain: MediaObject - Range: CreativeWork -
-
- encoding - A media object that encodes this CreativeWork. This property is a synonym for associatedMedia. - Domain: CreativeWork - Range: MediaObject -
-
- encodingFormat - mp3, mpeg4, etc. - Domain: MediaObject - Range: Text -
-
- encodings - - A media object that encodes this CreativeWork. - Domain: CreativeWork - Range: MediaObject -
-
- endDate - The end date and time of the item (in [ISO 8601 date format](http://en.wikipedia.org/wiki/ISO_8601)). - Domain: Role - Domain: Event - Domain: CreativeWorkSeason - Domain: CreativeWorkSeries - Range: Date -
-
- endorsee - A sub property of participant. The person/organization being supported. - - Domain: EndorseAction - Range: Organization - Range: Person -
- -
- endTime - The endTime of something. For a reserved event or service (e.g. FoodEstablishmentReservation), the time that it is expected to end. For actions that span a period of time, when the action was performed. e.g. John wrote a book from January to *December*.\n\nNote that Event uses startDate/endDate instead of startTime/endTime, even when describing dates with times. This situation may be clarified in future revisions. - Domain: Action - Domain: FoodEstablishmentReservation - Range: DateTime -
-
- entertainmentBusiness - A sub property of location. The entertainment business where the action occurred. - - Domain: PerformAction - Range: EntertainmentBusiness -
-
- episode - An episode of a tv, radio or game media within a series or season. - Domain: CreativeWorkSeason - Domain: RadioSeries - Domain: VideoGameSeries - Domain: TVSeries - Range: Episode - -
-
- episodeNumber - Position of the episode within an ordered group of episodes. - - Domain: Episode - Range: Integer - Range: Text -
-
- episodes - - An episode of a TV/radio series or season. - Domain: CreativeWorkSeason - Domain: RadioSeries - Domain: VideoGameSeries - Domain: TVSeries - Range: Episode -
-
- equal - This ordering relation for qualitative values indicates that the subject is equal to the object. - Domain: QualitativeValue - Range: QualitativeValue -
-
- event - Upcoming or past event associated with this place, organization, or action. - Domain: Organization - Domain: Place - Domain: InformAction - Domain: PlayAction - Domain: InviteAction - Domain: JoinAction - Domain: LeaveAction - Range: Event -
-
- events - - Upcoming or past events associated with this place or organization. - Domain: Organization - Domain: Place - Range: Event -
-
- eventStatus - An eventStatus of an event represents its status; particularly useful when an event is cancelled or rescheduled. - Domain: Event - Range: EventStatusType -
- -
- exifData - exif data for this object. - Domain: ImageObject - Range: Text - Range: PropertyValue -
-
- expectedArrivalFrom - The earliest date the package may arrive. - Domain: ParcelDelivery - Range: DateTime -
-
- expectedArrivalUntil - The latest date the package may arrive. - Domain: ParcelDelivery - Range: DateTime -
-
- experienceRequirements - Description of skills and experience needed for the position. - Domain: JobPosting - Range: Text -
-
- expires - Date the content expires and is no longer useful or available. For example a [[VideoObject]] or [[NewsArticle]] whose availability or relevance is time-limited, or a [[ClaimReview]] fact check whose publisher wants to indicate that it may no longer be relevant (or helpful to highlight) after some date. - Domain: CreativeWork - Range: Date -
-
- familyName - Family name. In the U.S., the last name of an Person. This can be used along with givenName instead of the name property. - Domain: Person - Range: Text -
- -
- faxNumber - The fax number. - Domain: Organization - Domain: Place - Domain: ContactPoint - Domain: Person - Range: Text -
-
- featureList - Features or modules provided by this application (and possibly required by other applications). - Domain: SoftwareApplication - Range: Text - Range: URL -
- -
- fileFormat - Media type, typically MIME format (see [IANA site](http://www.iana.org/assignments/media-types/media-types.xhtml)) of the content e.g. application/zip of a SoftwareApplication binary. In cases where a CreativeWork has several media type representations, 'encoding' can be used to indicate each MediaObject alongside particular fileFormat information. Unregistered or niche file formats can be indicated instead via the most appropriate URL, e.g. defining Web page or a Wikipedia entry. - Domain: CreativeWork - Range: Text - Range: URL -
-
- fileSize - Size of the application / package (e.g. 18MB). In the absence of a unit (MB, KB etc.), KB will be assumed. - Domain: SoftwareApplication - Range: Text -
-
- followee - A sub property of object. The person or organization being followed. - - Domain: FollowAction - Range: Organization - Range: Person -
-
- follows - The most generic uni-directional social relation. - Domain: Person - Range: Person -
- -
- founder - A person who founded this organization. - Domain: Organization - Range: Person -
-
- founders - - A person who founded this organization. - Domain: Organization - Range: Person -
-
- dissolutionDate - The date that this organization was dissolved. - Domain: Organization - Range: Date -
-
- foundingDate - The date that this organization was founded. - Domain: Organization - Range: Date -
-
- free - - A flag to signal that the item, event, or place is accessible for free. - Domain: PublicationEvent - Range: Boolean -
-
- isAccessibleForFree - A flag to signal that the item, event, or place is accessible for free. - Domain: CreativeWork - Domain: Event - Domain: PublicationEvent - Domain: Place - Range: Boolean -
-
- publicAccess - A flag to signal that the [[Place]] is open to public visitors. If this property is omitted there is no assumed default boolean value - Domain: Place - Range: Boolean -
- -
- fromLocation - A sub property of location. The original location of the object or the agent before the action. - - Domain: MoveAction - Domain: TransferAction - Domain: ExerciseAction - Range: Place -
-
- gender - Gender of the person. While http://schema.org/Male and http://schema.org/Female may be used, text strings are also acceptable for people who do not identify as a binary gender. - Domain: Person - Range: Text - Range: GenderType -
-
- GenderType - An enumeration of genders. - Subclass of: Enumeration -
-
- Female - The female gender. -
-
- Male - The male gender. -
-
- genre - Genre of the creative work, broadcast channel or group. - Domain: CreativeWork - Domain: BroadcastChannel - Domain: MusicGroup - Range: Text - Range: URL -
-
- geo - The geo coordinates of the place. - Domain: Place - Range: GeoCoordinates - Range: GeoShape -
-
- geographicArea - The geographic area associated with the audience. - Domain: Audience - Range: AdministrativeArea -
-
- givenName - Given name. In the U.S., the first name of a Person. This can be used along with familyName instead of the name property. - Domain: Person - Range: Text -
-
- globalLocationNumber - The [Global Location Number](http://www.gs1.org/gln) (GLN, sometimes also referred to as International Location Number or ILN) of the respective organization, person, or place. The GLN is a 13-digit number used to identify parties and physical locations. - Domain: Organization - Domain: Place - Domain: Person - Range: Text -
-
- greater - This ordering relation for qualitative values indicates that the subject is greater than the object. - Domain: QualitativeValue - Range: QualitativeValue -
-
- greaterOrEqual - This ordering relation for qualitative values indicates that the subject is greater than or equal to the object. - Domain: QualitativeValue - Range: QualitativeValue -
-
- gtin12 - The [GTIN-12](http://apps.gs1.org/GDD/glossary/Pages/GTIN-12.aspx) code of the product, or the product to which the offer refers. The GTIN-12 is the 12-digit GS1 Identification Key composed of a U.P.C. Company Prefix, Item Reference, and Check Digit used to identify trade items. See [GS1 GTIN Summary](http://www.gs1.org/barcodes/technical/idkeys/gtin) for more details. - Domain: Offer - Domain: Product - Domain: Demand - Range: Text -
-
- gtin13 - The [GTIN-13](http://apps.gs1.org/GDD/glossary/Pages/GTIN-13.aspx) code of the product, or the product to which the offer refers. This is equivalent to 13-digit ISBN codes and EAN UCC-13. Former 12-digit UPC codes can be converted into a GTIN-13 code by simply adding a preceding zero. See [GS1 GTIN Summary](http://www.gs1.org/barcodes/technical/idkeys/gtin) for more details. - Domain: Offer - Domain: Product - Domain: Demand - Range: Text -
-
- gtin14 - The [GTIN-14](http://apps.gs1.org/GDD/glossary/Pages/GTIN-14.aspx) code of the product, or the product to which the offer refers. See [GS1 GTIN Summary](http://www.gs1.org/barcodes/technical/idkeys/gtin) for more details. - Domain: Offer - Domain: Product - Domain: Demand - Range: Text -
-
- gtin8 - The [GTIN-8](http://apps.gs1.org/GDD/glossary/Pages/GTIN-8.aspx) code of the product, or the product to which the offer refers. This code is also known as EAN/UCC-8 or 8-digit EAN. See [GS1 GTIN Summary](http://www.gs1.org/barcodes/technical/idkeys/gtin) for more details. - Domain: Offer - Domain: Product - Domain: Demand - Range: Text -
- -
- hasDeliveryMethod - Method used for delivery or shipping. - Domain: DeliveryEvent - Domain: ParcelDelivery - Range: DeliveryMethod -
-
- hasPOS - Points-of-Sales operated by the organization or person. - Domain: Organization - Domain: Person - Range: Place -
-
- headline - Headline of the article. - Domain: CreativeWork - Range: Text -
- -
- height - The height of the item. - Domain: MediaObject - Domain: Product - Domain: Person - Range: Distance - Range: QuantitativeValue -
-
- highPrice - The highest price of all offers available. - Domain: AggregateOffer - Range: Number - Range: Text -
-
- hiringOrganization - Organization offering the job position. - Domain: JobPosting - Range: Organization -
-
- homeLocation - A contact location for a person's residence. - - Domain: Person - Range: ContactPoint - Range: Place -
-
- honorificPrefix - An honorific prefix preceding a Person's name such as Dr/Mrs/Mr. - Domain: Person - Range: Text -
-
- honorificSuffix - An honorific suffix preceding a Person's name such as M.D. /PhD/MSCSW. - Domain: Person - Range: Text -
- -
- hoursAvailable - The hours during which this service or contact is available. - Domain: ContactPoint - Domain: Service - Domain: LocationFeatureSpecification - Range: OpeningHoursSpecification -
- -
- illustrator - The illustrator of the book. - Domain: Book - - Range: Person -
-
- image - An image of the item. This can be a [[URL]] or a fully described [[ImageObject]]. - Domain: Thing - Range: URL - Range: ImageObject -
- -
- inAlbum - The album to which this recording belongs. - Domain: MusicRecording - Range: MusicAlbum -
-
- incentives - - Description of bonus and commission compensation aspects of the job. - Domain: JobPosting - Range: Text -
-
- incentiveCompensation - Description of bonus and commission compensation aspects of the job. - Domain: JobPosting - Range: Text -
- -
- includesObject - This links to a node or nodes indicating the exact quantity of the products included in the offer. - Domain: Offer - Domain: Demand - Range: TypeAndQuantityNode -
-
- industry - The industry associated with the job position. - Domain: JobPosting - Range: Text -
- - -
- inLanguage - The language of the content or performance or used in an action. Please use one of the language codes from the [IETF BCP 47 standard](http://tools.ietf.org/html/bcp47). See also [[availableLanguage]]. - Domain: CreativeWork - Domain: Event - Domain: CommunicateAction - Domain: WriteAction - Range: Text - Range: Language -
-
- inPlaylist - The playlist to which this recording belongs. - Domain: MusicRecording - Range: MusicPlaylist -
- -
- installUrl - URL at which the app may be installed, if different from the URL of the item. - Domain: SoftwareApplication - Range: URL -
-
- instrument - The object that helped the agent perform the action. e.g. John wrote a book with *a pen*. - Domain: Action - Range: Thing -
- -
- interactionCount - This property is deprecated, alongside the UserInteraction types on which it depended. - - -
-
- interactivityType - The predominant mode of learning supported by the learning resource. Acceptable values are 'active', 'expositive', or 'mixed'. - Domain: CreativeWork - Range: Text -
-
- inventoryLevel - The current approximate inventory level for the item or items. - Domain: Offer - Domain: Demand - Domain: SomeProducts - Range: QuantitativeValue -
-
- isAccessoryOrSparePartFor - A pointer to another product (or multiple products) for which this product is an accessory or spare part. - Domain: Product - Range: Product -
- -
- isBasedOnUrl - A resource that was used in the creation of this resource. This term can be repeated for multiple sources. For example, http://example.com/great-multiplication-intro.html. - Domain: CreativeWork - Range: URL - Range: CreativeWork - Range: Product - - -
- -
- isBasedOn - A resource that was used in the creation of this resource. This term can be repeated for multiple sources. For example, http://example.com/great-multiplication-intro.html. - Domain: CreativeWork - Range: URL - Range: CreativeWork - Range: Product - -
- -
- isbn - The ISBN of the book. - Domain: Book - Range: Text - -
-
- isConsumableFor - A pointer to another product (or multiple products) for which this product is a consumable. - Domain: Product - Range: Product -
-
- isFamilyFriendly - Indicates whether this content is family friendly. - Domain: CreativeWork - Range: Boolean -
-
- isGift - Was the offer accepted as a gift for someone other than the buyer. - Domain: Order - Range: Boolean -
-
- isicV4 - The International Standard of Industrial Classification of All Economic Activities (ISIC), Revision 4 code for a particular organization, business person, or place. - Domain: Organization - Domain: Place - Domain: Person - Range: Text -
-
- isPartOf - Indicates a CreativeWork that this CreativeWork is (in some sense) part of. - Domain: CreativeWork - Range: CreativeWork - -
- -
- isRelatedTo - A pointer to another, somehow related product (or multiple products). - Domain: Product - Domain: Service - Range: Product - Range: Service -
-
- isSimilarTo - A pointer to another, functionally similar product (or multiple products). - Domain: Product - Domain: Service - Range: Product - Range: Service -
-
- issuedThrough - The service through with the permit was granted. - Domain: Permit - Range: Service -
-
- isVariantOf - A pointer to a base product from which this product is a variant. It is safe to infer that the variant inherits all product features from the base model, unless defined locally. This is not transitive. - Domain: ProductModel - Range: ProductModel -
-
- itemCondition - A predefined value from OfferItemCondition or a textual description of the condition of the product or service, or the products or services included in the offer. - Domain: Offer - Domain: Product - Domain: Demand - Range: OfferItemCondition -
- -
- numberOfItems - The number of items in an ItemList. Note that some descriptions might not fully describe all items in a list (e.g., multi-page pagination); in such cases, the numberOfItems would be for the entire list. - Domain: ItemList - Range: Integer -
-
- itemListOrder - Type of ordering (e.g. Ascending, Descending, Unordered). - Domain: ItemList - Range: ItemListOrderType - Range: Text -
- - -
- ItemListOrderType - Enumerated for values for itemListOrder for indicating how an ordered ItemList is organized. - Subclass of: Enumeration -
- -
- ItemListOrderAscending - An ItemList ordered with lower values listed first. - type: ItemListOrderType -
- -
- ItemListOrderDescending - An ItemList ordered with higher values listed first. - type: ItemListOrderType -
- -
- ItemListUnordered - An ItemList ordered with no explicit order. - type: ItemListOrderType -
- - -
- itemOffered - The item being offered. - Domain: Offer - Domain: Demand - Range: Product - Range: Service - -
-
- itemReviewed - The item that is being reviewed/rated. - Domain: AggregateRating - Domain: Review - Range: Thing -
-
- itemShipped - Item(s) being shipped. - Domain: ParcelDelivery - Range: Product -
-
- jobLocation - A (typically single) geographic location associated with the job position. - Domain: JobPosting - Range: Place -
-
- jobTitle - The job title of the person (for example, Financial Manager). - Domain: Person - Range: Text -
-
- keywords - Keywords or tags used to describe this content. Multiple entries in a keywords list are typically delimited by commas. - Domain: CreativeWork - Range: Text -
-
- knows - The most generic bi-directional social/work relation. - Domain: Person - Range: Person -
- -
- landlord - A sub property of participant. The owner of the real estate property. - - Domain: RentAction - Range: Organization - Range: Person -
-
- language - A sub property of instrument. The language used on this action. - - - Domain: CommunicateAction - Domain: WriteAction - Range: Language -
-
- lastReviewed - Date on which the content on this web page was last reviewed for accuracy and/or completeness. - Domain: WebPage - Range: Date -
-
- latitude - The latitude of a location. For example ```37.42242``` ([WGS 84](https://en.wikipedia.org/wiki/World_Geodetic_System)). - Domain: GeoCoordinates - Range: Number - Range: Text -
-
- license - A license document that applies to this content, typically indicated by URL. - Domain: CreativeWork - Range: CreativeWork - Range: URL -
-
- learningResourceType - The predominant type or kind characterizing the learning resource. For example, 'presentation', 'handout'. - Domain: CreativeWork - Range: Text -
-
- legalName - The official name of the organization, e.g. the registered company name. - Domain: Organization - Range: Text -
- -
- lender - A sub property of participant. The person that lends the object being borrowed. - - Domain: BorrowAction - Range: Person - Range: Organization -
-
- lesser - This ordering relation for qualitative values indicates that the subject is lesser than the object. - Domain: QualitativeValue - Range: QualitativeValue -
-
- lesserOrEqual - This ordering relation for qualitative values indicates that the subject is lesser than or equal to the object. - Domain: QualitativeValue - Range: QualitativeValue -
-
- line - A line is a point-to-point path consisting of two or more points. A line is expressed as a series of two or more point objects separated by space. - Domain: GeoShape - Range: Text -
-
- location - The location of for example where the event is happening, an organization is located, or where an action takes place. - Domain: Organization - Domain: Event - Domain: Action - Range: Place - Range: PostalAddress - Range: Text -
-
- logo - An associated logo. - - Domain: Organization - Domain: Place - Domain: Product - Domain: Service - Domain: Brand - Range: ImageObject - Range: URL -
-
- longitude - The longitude of a location. For example ```-122.08585``` ([WGS 84](https://en.wikipedia.org/wiki/World_Geodetic_System)). - Domain: GeoCoordinates - Range: Number - Range: Text -
-
- loser - A sub property of participant. The loser of the action. - - Domain: WinAction - Range: Person -
-
- lowPrice - The lowest price of all offers available. - Domain: AggregateOffer - Range: Number - Range: Text -
-
- mainContentOfPage - Indicates if this web page element is the main subject of the page. - Domain: WebPage - Range: WebPageElement -
- - -
- mainEntity - Indicates the primary entity described in some page or other CreativeWork. - Domain: CreativeWork - Range: Thing - - -
- -
- mainEntityOfPage - Indicates a page (or other CreativeWork) for which this thing is the main entity being described. See [background notes](/docs/datamodel.html#mainEntityBackground) for details. - Domain: Thing - Range: CreativeWork - Range: URL - -
- -
- makesOffer - A pointer to products or services offered by the organization or person. - - Domain: Organization - Domain: Person - Range: Offer -
-
- offeredBy - A pointer to the organization or person making the offer. - - Domain: Organization - Range: Person - Range: Offer -
- -
- hasMap - A URL to a map of the place. - Domain: Place - Range: URL - Range: Map -
-
- map - A URL to a map of the place. - - Domain: Place - Range: URL -
-
- maps - - A URL to a map of the place. - Domain: Place - Range: URL -
- -
- maximumAttendeeCapacity - The total number of individuals that may attend an event or venue. - Domain: Place - Domain: Event - Range: Integer -
- -
- remainingAttendeeCapacity - The number of attendee places for an event that remain unallocated. - Domain: Event - Range: Integer -
- -
- maxPrice - The highest price if the price is a range. - Domain: PriceSpecification - Range: Number -
-
- maxValue - The upper value of some characteristic or property. - Domain: QuantitativeValue - Domain: PropertyValue - Domain: MonetaryAmount - Domain: PropertyValueSpecification - Range: Number -
- -
- member - A member of an Organization or a ProgramMembership. Organizations can be members of organizations; ProgramMembership is typically for individuals. - - Domain: Organization - domain: ProgramMembership - Range: Organization - Range: Person -
-
- memberOf - An Organization (or ProgramMembership) to which this Person or Organization belongs. - - Domain: Person - Domain: Organization - Range: Organization - Range: ProgramMembership -
-
- members - - A member of this organization. - Domain: Organization - domain: ProgramMembership - Range: Organization - Range: Person -
-
- memoryRequirements - Minimum memory requirements. - Domain: SoftwareApplication - Range: Text - Range: URL -
-
- mentions - Indicates that the CreativeWork contains a reference to, but is not necessarily about a concept. - Domain: CreativeWork - Range: Thing -
-
- hasMenu - Either the actual menu as a structured representation, as text, or a URL of the menu. - Domain: FoodEstablishment - Range: Menu - Range: Text - Range: URL -
- -
- menu - Either the actual menu as a structured representation, as text, or a URL of the menu. - - Domain: FoodEstablishment - Range: Menu - Range: Text - Range: URL -
- - -
- merchant - 'merchant' is an out-dated term for 'seller'. - Domain: Order - Range: Organization - Range: Person - -
-
- minPrice - The lowest price if the price is a range. - Domain: PriceSpecification - Range: Number -
-
- minValue - The lower value of some characteristic or property. - Domain: QuantitativeValue - Domain: PropertyValue - Domain: MonetaryAmount - Domain: PropertyValueSpecification - Range: Number -
-
- model - The model of the product. Use with the URL of a ProductModel or a textual representation of the model identifier. The URL of the ProductModel can be from an external source. It is recommended to additionally provide strong product identifiers via the gtin8/gtin13/gtin14 and mpn properties. - Domain: Product - Range: ProductModel - Range: Text -
-
- mpn - The Manufacturer Part Number (MPN) of the product, or the product to which the offer refers. - Domain: Offer - Domain: Product - Domain: Demand - Range: Text -
-
- manufacturer - The manufacturer of the product. - Domain: Product - Range: Organization -
-
- musicBy - The composer of the soundtrack. - Domain: Movie - Domain: Episode - Domain: TVSeries - Domain: RadioSeries - Domain: Clip - Domain: MovieSeries - Domain: VideoGame - Domain: VideoGameSeries - Domain: VideoObject - Range: MusicGroup - Range: Person -
-
- musicGroupMember - A member of a music group&#x2014;for example, John, Paul, George, or Ringo. - - Domain: MusicGroup - Range: Person -
-
- naics - The North American Industry Classification System (NAICS) code for a particular organization or business person. - Domain: Organization - Domain: Person - Range: Text -
-
- name - The name of the item. - Domain: Thing - Range: Text -
-
- nationality - Nationality of the person. - Domain: Person - Range: Country -
- -
- netWorth - The total financial value of the person as calculated by subtracting assets from liabilities. - Domain: Person - Range: PriceSpecification - Range: MonetaryAmount -
-
- nonEqual - This ordering relation for qualitative values indicates that the subject is not equal to the object. - Domain: QualitativeValue - Range: QualitativeValue -
- -
- numberOfEmployees - The number of employees in an organization e.g. business. - Domain: BusinessAudience - Domain: Organization - Range: QuantitativeValue -
-
- numberOfEpisodes - The number of episodes in this season or series. - Domain: CreativeWorkSeason - Domain: TVSeries - Domain: VideoGameSeries - Domain: RadioSeries - Range: Integer -
-
- numberOfPages - The number of pages in the book. - Domain: Book - Range: Integer -
-
- numberOfSeasons - The number of seasons in this series. - Domain: TVSeries - Domain: RadioSeries - Domain: VideoGameSeries - Range: Integer -
-
- numTracks - The number of tracks in this album or playlist. - Domain: MusicPlaylist - Range: Integer -
- -
- object - The object upon which the action is carried out, whose state is kept intact or changed. Also known as the semantic roles patient, affected or undergoer (which change their state) or theme (which doesn't). e.g. John read *a book*. - Domain: Action - Range: Thing -
-
- occupationalCategory - Category or categories describing the job. Use BLS O*NET-SOC taxonomy: http://www.onetcenter.org/taxonomy.html. Ideally includes textual label and formal code, with the property repeated for each applicable value. - Domain: JobPosting - Range: Text -
-
- offerCount - The number of offers for the product. - Domain: AggregateOffer - Range: Integer -
-
- offers - An offer to provide this item&#x2014;for example, an offer to sell a product, rent the DVD of a movie, perform a service, or give away tickets to an event. - Domain: CreativeWork - Domain: Event - Domain: MenuItem - Domain: Product - Domain: Service - - Domain: AggregateOffer - Range: Offer -
-
- openingHours - The general opening hours for a business. Opening hours can be specified as a weekly time range, starting with days, then times per day. Multiple days can be listed with commas ',' separating each day. Day or time ranges are specified using a hyphen '-'.\n\n* Days are specified using the following two-letter combinations: ```Mo```, ```Tu```, ```We```, ```Th```, ```Fr```, ```Sa```, ```Su```.\n* Times are specified using 24:00 time. For example, 3pm is specified as ```15:00```. \n* Here is an example: <code>&lt;time itemprop="openingHours" datetime=&quot;Tu,Th 16:00-20:00&quot;&gt;Tuesdays and Thursdays 4-8pm&lt;/time&gt;</code>.\n* If a business is open 7 days a week, then it can be specified as <code>&lt;time itemprop=&quot;openingHours&quot; datetime=&quot;Mo-Su&quot;&gt;Monday through Sunday, all day&lt;/time&gt;</code>. - Domain: LocalBusiness - Domain: CivicStructure - Range: Text -
-
- openingHoursSpecification - The opening hours of a certain place. - Domain: Place - Range: OpeningHoursSpecification -
-
- specialOpeningHoursSpecification - The special opening hours of a certain place.\n\nUse this to explicitly override general opening hours brought in scope by [[openingHoursSpecification]] or [[openingHours]]. - - Domain: Place - Range: OpeningHoursSpecification -
-
- opens - The opening hour of the place or service on the given day(s) of the week. - Domain: OpeningHoursSpecification - Range: Time -
-
- operatingSystem - Operating systems supported (Windows 7, OSX 10.6, Android 1.6). - Domain: SoftwareApplication - Range: Text -
-
- opponent - A sub property of participant. The opponent on this action. - - Domain: ExerciseAction - Range: Person -
-
- option - - A sub property of object. The options subject to this action. - - Domain: ChooseAction - Range: Text - Range: Thing -
-
- actionOption - A sub property of object. The options subject to this action. - - Domain: ChooseAction - Range: Text - Range: Thing -
-
- orderDate - Date order was placed. - Domain: Order - Range: DateTime -
-
- orderedItem - The item ordered. - Domain: Order - Domain: OrderItem - Range: Product - Range: OrderItem -
-
- orderNumber - The identifier of the transaction. - Domain: Order - Range: Text -
-
- orderStatus - The current status of the order. - Domain: Order - Range: OrderStatus -
-
- originAddress - Shipper's address. - Domain: ParcelDelivery - Range: PostalAddress -
-
- ownedFrom - The date and time of obtaining the product. - Domain: OwnershipInfo - Range: DateTime -
-
- ownedThrough - The date and time of giving up ownership on the product. - Domain: OwnershipInfo - Range: DateTime -
-
- owns - Products owned by the organization or person. - Domain: Organization - Domain: Person - Range: OwnershipInfo - Range: Product -
-
- parent - A parent of this person. - Domain: Person - Range: Person -
-
- parents - - A parents of the person. - Domain: Person - Range: Person -
-
- parentService - A broadcast service to which the broadcast service may belong to such as regional variations of a national channel. - Domain: BroadcastService - Range: BroadcastService -
-
- participant - Other co-agents that participated in the action indirectly. e.g. John wrote a book with *Steve*. - Domain: Action - Range: Organization - Range: Person -
-
- partOfEpisode - The episode to which this clip belongs. - Domain: Clip - Range: Episode - -
-
- partOfInvoice - The order is being paid as part of the referenced Invoice. - Domain: Order - Range: Invoice -
-
- partOfOrder - The overall order the items in this delivery were included in. - Domain: ParcelDelivery - Range: Order -
-
- partOfSeason - The season to which this episode belongs. - Domain: Episode - Domain: Clip - Range: CreativeWorkSeason - -
-
- partOfSeries - The series to which this episode or season belongs. - Domain: Episode - Domain: CreativeWorkSeason - Domain: Clip - Range: CreativeWorkSeries - -
-
- partOfTVSeries - - The TV series to which this episode or season belongs. - Domain: TVEpisode - Domain: TVSeason - Domain: TVClip - Range: TVSeries - -
-
- paymentAccepted - Cash, credit card, etc. - Domain: LocalBusiness - Range: Text -
-
- paymentDue - The date that payment is due. - Domain: Order - Domain: Invoice - Range: DateTime -
-
- paymentMethod - The name of the credit card or other method of payment for the order. - Domain: Order - Domain: Invoice - Range: PaymentMethod -
-
- paymentMethodId - An identifier for the method of payment used (e.g. the last 4 digits of the credit card). - Domain: Order - Domain: Invoice - Range: Text -
-
- paymentUrl - The URL for sending a payment. - Domain: Order - Range: URL -
-
- performer - A performer at the event&#x2014;for example, a presenter, musician, musical group or actor. - Domain: Event - Range: Organization - Range: Person -
-
- performerIn - Event that this person is a performer or participant in. - Domain: Person - Range: Event -
-
- performers - - The main performer or performers of the event&#x2014;for example, a presenter, musician, or actor. - Domain: Event - Range: Organization - Range: Person -
-
- permissions - Permission(s) required to run the app (for example, a mobile app may require full internet access or may run only on wifi). - Domain: SoftwareApplication - Range: Text -
-
- permitAudience - The target audience for this permit. - Domain: Permit - Range: Audience -
- -
- photo - A photograph of this place. - - Domain: Place - Range: ImageObject - Range: Photograph -
-
- photos - - Photographs of this place. - Domain: Place - Range: ImageObject - Range: Photograph -
- -
- playerType - Player type required&#x2014;for example, Flash or Silverlight. - Domain: MediaObject - Range: Text -
-
- polygon - A polygon is the area enclosed by a point-to-point path for which the starting and ending points are the same. A polygon is expressed as a series of four or more space delimited points where the first and final points are identical. - Domain: GeoShape - Range: Text -
- -
- position - The position of an item in a series or sequence of items. - Domain: CreativeWork - Domain: ListItem - Range: Text - Range: Integer -
-
- postalCode - The postal code. For example, 94043. - Domain: PostalAddress - Domain: GeoShape - Domain: GeoCoordinates - Range: Text -
-
- postOfficeBoxNumber - The post office box number for PO box addresses. - Domain: PostalAddress - Range: Text -
- -
- predecessorOf - A pointer from a previous, often discontinued variant of the product to its newer variant. - Domain: ProductModel - Range: ProductModel -
- -
- previousStartDate - Used in conjunction with eventStatus for rescheduled or cancelled events. This property contains the previously scheduled start date. For rescheduled events, the startDate property should be used for the newly scheduled start date. In the (rare) case of an event that has been postponed and rescheduled multiple times, this field may be repeated. - Domain: Event - Range: Date -
-
- price - The offer price of a product, or of a price component when attached to PriceSpecification and its subtypes.\n\nUsage guidelines:\n\n* Use the [[priceCurrency]] property (with [ISO 4217 codes](http://en.wikipedia.org/wiki/ISO_4217#Active_codes) e.g. "USD") instead of - including [ambiguous symbols](http://en.wikipedia.org/wiki/Dollar_sign#Currencies_that_use_the_dollar_or_peso_sign) such as '$' in the value.\n* Use '.' (Unicode 'FULL STOP' (U+002E)) rather than ',' to indicate a decimal point. Avoid using these symbols as a readability separator.\n* Note that both [RDFa](http://www.w3.org/TR/xhtml-rdfa-primer/#using-the-content-attribute) and Microdata syntax allow the use of a "content=" attribute for publishing simple machine-readable values alongside more human-friendly formatting.\n* Use values from 0123456789 (Unicode 'DIGIT ZERO' (U+0030) to 'DIGIT NINE' (U+0039)) rather than superficially similar Unicode symbols. - - Domain: Offer - Domain: PriceSpecification - Domain: TradeAction - Range: Number - Range: Text -
-
- priceRange - The price range of the business, for example ```$$$```. - Domain: LocalBusiness - Range: Text -
-
- priceSpecification - One or more detailed price specifications, indicating the unit price and delivery or payment charges. - Domain: Offer - Domain: Demand - Domain: TradeAction - Range: PriceSpecification -
-
- priceType - A short text or acronym indicating multiple price specifications for the same offer, e.g. SRP for the suggested retail price or INVOICE for the invoice price, mostly used in the car industry. - Domain: UnitPriceSpecification - Range: Text -
-
- priceValidUntil - The date after which the price is no longer available. - Domain: Offer - Range: Date -
-
- primaryImageOfPage - Indicates the main image on the page. - Domain: WebPage - Range: ImageObject -
- -
- printColumn - The number of the column in which the NewsArticle appears in the print edition. - Domain: NewsArticle - Range: Text -
-
- printEdition - The edition of the print product in which the NewsArticle appears. - Domain: NewsArticle - Range: Text -
-
- printPage - If this NewsArticle appears in print, this field indicates the name of the page on which the article is found. Please note that this field is intended for the exact page name (e.g. A5, B18). - Domain: NewsArticle - Range: Text -
-
- printSection - If this NewsArticle appears in print, this field indicates the print section in which the article appeared. - Domain: NewsArticle - Range: Text -
- -
- processingTime - Estimated processing time for the service using this channel. - Domain: ServiceChannel - Range: Duration -
-
- processorRequirements - Processor architecture required to run the application (e.g. IA64). - Domain: SoftwareApplication - Range: Text -
-
- producer - The person or organization who produced the work (e.g. music album, movie, tv/radio series etc.). - Domain: CreativeWork - Range: Person - Range: Organization -
-
- produces - - The tangible thing generated by the service, e.g. a passport, permit, etc. - Domain: Service - Range: Thing -
-
- serviceOutput - The tangible thing generated by the service, e.g. a passport, permit, etc. - Domain: Service - Range: Thing -
-
- productID - The product identifier, such as ISBN. For example: ``` meta itemprop="productID" content="isbn:123-456-789" ```. - Domain: Product - Range: Text -
-
- productionCompany - The production company or studio responsible for the item e.g. series, video game, episode etc. - Domain: MediaObject - Domain: Movie - Domain: Episode - Domain: CreativeWorkSeason - Domain: TVSeries - Domain: RadioSeries - Domain: MovieSeries - Domain: VideoGameSeries - Domain: RadioSeries - - Range: Organization -
-
- productSupported - The product or service this support contact point is related to (such as product support for a particular product line). This can be a specific product or product line (e.g. "iPhone") or a general category of products or services (e.g. "smartphones"). - Domain: ContactPoint - Range: Product - Range: Text -
-
- proficiencyLevel - Proficiency needed for this content; expected values: 'Beginner', 'Expert'. - Domain: TechArticle - Range: Text -
-
- programmingLanguage - The computer programming language. - Domain: SoftwareSourceCode - Range: ComputerLanguage - Range: Text -
-
- programmingModel - Indicates whether API is managed or unmanaged. - Domain: APIReference - Range: Text -
- -
- providesService - The service provided by this channel. - Domain: ServiceChannel - Range: Service -
-
- publication - A publication event associated with the item. - Domain: CreativeWork - Range: PublicationEvent -
- -
- publishedOn - A broadcast service associated with the publication event. - Domain: PublicationEvent - Range: BroadcastService -
-
- publisher - The publisher of the creative work. - Domain: CreativeWork - Range: Organization - Range: Person -
-
- publishingPrinciples - The publishingPrinciples property indicates (typically via [[URL]]) a document describing the editorial principles of an [[Organization]] (or individual e.g. a [[Person]] writing a blog) that relate to their activities as a publisher, e.g. ethics or diversity policies. When applied to a [[CreativeWork]] (e.g. [[NewsArticle]]) the principles are those of the party primarily responsible for the creation of the [[CreativeWork]]. - -While such policies are most typically expressed in natural language, sometimes related information (e.g. indicating a [[funder]]) can be expressed using schema.org terminology. - - Domain: CreativeWork - Domain: Organization - Domain: Person - Range: URL - Range: CreativeWork -
- -
- qualifications - Specific qualifications required for this role. - Domain: JobPosting - Range: Text -
-
- query - A sub property of instrument. The query used on this action. - - Domain: SearchAction - Range: Text -
-
- question - A sub property of object. A question. - - Domain: AskAction - Range: Question -
-
- ratingCount - The count of total number of ratings. - Domain: AggregateRating - Range: Integer -
-
- ratingValue - The rating for the content. - Domain: Rating - Range: Text - Range: Number -
-
- realEstateAgent - A sub property of participant. The real estate agent involved in the action. - - Domain: RentAction - Range: RealEstateAgent -
- -
- recipient - A sub property of participant. The participant who is at the receiving end of the action. - - Domain: Message - Domain: CommunicateAction - Domain: AuthorizeAction - Domain: DonateAction - Domain: GiveAction - Domain: PayAction - Domain: ReturnAction - Domain: SendAction - Domain: TipAction - Range: Audience - Range: ContactPoint - Range: Organization - Range: Person -
- -
- recordedAt - The Event where the CreativeWork was recorded. The CreativeWork may capture all or part of the event. - Domain: CreativeWork - Range: Event - -
-
- recordedIn - The CreativeWork that captured all or part of this Event. - Domain: Event - Range: CreativeWork - -
- -
- relatedLink - A link related to this web page, for example to other related web pages. - Domain: WebPage - Range: URL -
- -
- relatedTo - The most generic familial relation. - Domain: Person - Range: Person -
-
- releaseDate - The release date of a product or product model. This can be used to distinguish the exact variant of a product. - Domain: Product - Range: Date -
-
- releaseNotes - Description of what changed in this version. - Domain: SoftwareApplication - Range: Text - Range: URL -
- -
- replacee - A sub property of object. The object that is being replaced. - - Domain: ReplaceAction - Range: Thing -
-
- replacer - A sub property of object. The object that replaces. - - Domain: ReplaceAction - Range: Thing -
-
- replyToUrl - The URL at which a reply may be posted to the specified UserComment. - Domain: UserComments - Range: URL -
-
- representativeOfPage - Indicates whether this image is representative of the content of the page. - Domain: ImageObject - Range: Boolean -
-
- requiredGender - Audiences defined by a person's gender. - Domain: PeopleAudience - Range: Text -
-
- requiredMaxAge - Audiences defined by a person's maximum age. - Domain: PeopleAudience - Range: Integer -
-
- requiredMinAge - Audiences defined by a person's minimum age. - Domain: PeopleAudience - Range: Integer -
-
- requirements - - Component dependency requirements for application. This includes runtime environments and shared libraries that are not included in the application distribution package, but required to run the application (Examples: DirectX, Java or .NET runtime). - Domain: SoftwareApplication - Range: Text - Range: URL -
-
- softwareRequirements - Component dependency requirements for application. This includes runtime environments and shared libraries that are not included in the application distribution package, but required to run the application (Examples: DirectX, Java or .NET runtime). - Domain: SoftwareApplication - Range: Text - Range: URL -
-
- requiresSubscription - Indicates if use of the media require a subscription (either paid or free). Allowed values are ```true``` or ```false``` (note that an earlier version had 'yes', 'no'). - Domain: MediaObject - Range: Boolean -
-
- responsibilities - Responsibilities associated with this role. - Domain: JobPosting - Range: Text -
- -
- result - The result produced in the action. e.g. John wrote *a book*. - Domain: Action - Range: Thing -
-
- resultComment - A sub property of result. The Comment created or sent as a result of this action. - - Domain: CommentAction - Domain: ReplyAction - Range: Comment -
-
- resultReview - A sub property of result. The review that resulted in the performing of the action. - - Domain: ReviewAction - Range: Review -
-
- review - A review of the item. - Domain: CreativeWork - Domain: Event - Domain: Brand - Domain: Service - Domain: Organization - Domain: Place - Domain: Offer - Domain: Product - Range: Review -
-
- reviewBody - The actual body of the review. - Domain: Review - Range: Text -
-
- reviewCount - The count of total number of reviews. - Domain: AggregateRating - Range: Integer -
-
- reviewedBy - People or organizations that have reviewed the content on this web page for accuracy and/or completeness. - Domain: WebPage - Range: Organization - Range: Person -
-
- reviewRating - The rating given in this review. Note that reviews can themselves be rated. The ```reviewRating``` applies to rating given by the review. The [[aggregateRating]] property applies to the review itself, as a creative work. - Domain: Review - Range: Rating -
-
- reviews - - Review of the item. - Domain: CreativeWork - Domain: Organization - Domain: Place - Domain: Offer - Domain: Product - Range: Review -
- -
- runtime - - Runtime platform or script interpreter dependencies (Example - Java v1, Python2.3, .Net Framework 3.0). - Domain: SoftwareSourceCode - Range: Text -
-
- runtimePlatform - Runtime platform or script interpreter dependencies (Example - Java v1, Python2.3, .Net Framework 3.0). - Domain: SoftwareSourceCode - Range: Text -
- -
- salaryCurrency - The currency (coded using [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) ) used for the main salary information in this job posting or for this employee. - Domain: JobPosting - Domain: EmployeeRole - Range: Text -
-
- sameAs - URL of a reference Web page that unambiguously indicates the item's identity. E.g. the URL of the item's Wikipedia page, Wikidata entry, or official website. - Domain: Thing - Range: URL -
-
- sampleType - - What type of code sample: full (compile ready) solution, code snippet, inline code, scripts, template. - Domain: SoftwareSourceCode - Range: Text -
-
- codeSampleType - What type of code sample: full (compile ready) solution, code snippet, inline code, scripts, template. - Domain: SoftwareSourceCode - Range: Text -
- -
- scheduledTime - The time the object is scheduled to. - Domain: PlanAction - Range: DateTime -
-
- screenCount - The number of screens in the movie theater. - Domain: MovieTheater - Range: Number -
-
- videoFormat - The type of screening or video broadcast used (e.g. IMAX, 3D, SD, HD, etc.). - Domain: ScreeningEvent - Domain: BroadcastEvent - Domain: BroadcastService - Range: Text -
-
- screenshot - A link to a screenshot image of the app. - Domain: SoftwareApplication - Range: ImageObject - Range: URL -
-
- season - - A season in a media series. - Domain: VideoGameSeries - Domain: TVSeries - Domain: RadioSeries - Range: CreativeWorkSeason - -
-
- containsSeason - A season that is part of the media series. - Domain: VideoGameSeries - Domain: TVSeries - Domain: RadioSeries - Range: CreativeWorkSeason - -
-
- seasonNumber - Position of the season within an ordered group of seasons. - - Domain: CreativeWorkSeason - Range: Integer - Range: Text -
-
- seasons - - A season in a media series. - Domain: VideoGameSeries - Domain: TVSeries - Domain: RadioSeries - Range: CreativeWorkSeason -
-
- seeks - A pointer to products or services sought by the organization or person (demand). - Domain: Organization - Domain: Person - Range: Demand -
-
- seller - An entity which offers (sells / leases / lends / loans) the services / goods. A seller may also be a provider. - Domain: Order - Domain: BuyAction - Domain: Offer - Domain: Demand - Domain: Flight - Range: Organization - Range: Person - -
-
- sender - A sub property of participant. The participant who is at the sending end of the action. - - Domain: Message - Domain: ReceiveAction - Range: Audience - Range: Organization - Range: Person -
- -
- serialNumber - The serial number or any alphanumeric identifier of a particular product. When attached to an offer, it is a shortcut for the serial number of the product included in the offer. - Domain: Offer - Domain: Demand - Domain: IndividualProduct - Range: Text -
-
- servesCuisine - The cuisine of the restaurant. - Domain: FoodEstablishment - Range: Text -
-
- serviceArea - The geographic area where the service is provided. - - Domain: Service - Domain: Organization - Domain: ContactPoint - Range: Place - Range: AdministrativeArea - Range: GeoShape -
-
- serviceAudience - The audience eligible for this service. - - Domain: Service - Range: Audience -
-
- serviceLocation - The location (e.g. civic structure, local business, etc.) where a person can go to access the service. - Domain: ServiceChannel - Range: Place -
-
- serviceOperator - The operating organization, if different from the provider. This enables the representation of services that are provided by an organization, but operated by another organization like a subcontractor. - Domain: GovernmentService - Range: Organization -
-
- servicePhone - The phone number to use to access the service. - Domain: ServiceChannel - Range: ContactPoint -
-
- servicePostalAddress - The address for accessing the service by mail. - Domain: ServiceChannel - Range: PostalAddress -
-
- serviceSmsNumber - The number to access the service by text message. - Domain: ServiceChannel - Range: ContactPoint -
-
- serviceType - The type of service being offered, e.g. veterans' benefits, emergency relief, etc. - Domain: Service - Range: Text -
-
- serviceUrl - The website to access the service. - Domain: ServiceChannel - Range: URL -
- -
- sibling - A sibling of the person. - Domain: Person - Range: Person -
- -
- siblings - - A sibling of the person. - Domain: Person - Range: Person -
- -
- significantLink - One of the more significant URLs on the page. Typically, these are the non-navigation links that are clicked on the most. - Domain: WebPage - Range: URL -
- -
- significantLinks - - The most significant URLs on the page. Typically, these are the non-navigation links that are clicked on the most. - Domain: WebPage - Range: URL -
-
- skills - Skills required to fulfill this role. - Domain: JobPosting - Range: Text -
-
- sku - The Stock Keeping Unit (SKU), i.e. a merchant-specific identifier for a product or service, or the product to which the offer refers. - Domain: Offer - Domain: Product - Domain: Demand - Range: Text -
- -
- softwareVersion - Version of the software instance. - Domain: SoftwareApplication - Range: Text -
- -
- sourceOrganization - The Organization on whose behalf the creator was working. - Domain: CreativeWork - Range: Organization -
-
- spatial - The range of spatial applicability of a dataset, e.g. for a dataset of New York weather, the state of New York. - - Domain: Dataset - Range: Place - -
- -
- spatialCoverage - The spatialCoverage of a CreativeWork indicates the place(s) which are the focus of the content. It is a subproperty of - contentLocation intended primarily for more technical and detailed materials. For example with a Dataset, it indicates - areas that the dataset describes: a dataset of New York weather would have spatialCoverage which was the place: the state of New York. - - Domain: CreativeWork - Range: Place - -
- -
- specialCommitments - Any special commitments associated with this job posting. Valid entries include VeteranCommit, MilitarySpouseCommit, etc. - Domain: JobPosting - Range: Text -
-
- specialty - One of the domain specialities to which this web page's content applies. - Domain: WebPage - Range: Specialty -
-
- sponsor - A person or organization that supports a thing through a pledge, promise, or financial contribution. e.g. a sponsor of a Medical Study or a corporate sponsor of an event. - Domain: CreativeWork - Domain: Person - Domain: Organization - Domain: Event - Range: Organization - Range: Person -
-
- funder - A person or organization that supports (sponsors) something through some kind of financial contribution. - - Domain: CreativeWork - Domain: Person - Domain: Organization - Domain: Event - Range: Organization - Range: Person -
-
- sportsActivityLocation - A sub property of location. The sports activity location where this action occurred. - - Domain: ExerciseAction - Range: SportsActivityLocation -
-
- sportsEvent - A sub property of location. The sports event where this action occurred. - - Domain: ExerciseAction - Range: SportsEvent -
-
- sportsTeam - A sub property of participant. The sports team that participated on this action. - - Domain: ExerciseAction - Range: SportsTeam -
-
- spouse - The person's spouse. - Domain: Person - Range: Person -
- -
- startDate - The start date and time of the item (in [ISO 8601 date format](http://en.wikipedia.org/wiki/ISO_8601)). - Domain: Role - Domain: Event - Domain: CreativeWorkSeason - Domain: CreativeWorkSeries - Range: Date - Range: DateTime -
-
- startTime - The startTime of something. For a reserved event or service (e.g. FoodEstablishmentReservation), the time that it is expected to start. For actions that span a period of time, when the action was performed. e.g. John wrote a book from *January* to December.\n\nNote that Event uses startDate/endDate instead of startTime/endTime, even when describing dates with times. This situation may be clarified in future revisions. - Domain: Action - Domain: FoodEstablishmentReservation - Range: DateTime -
- -
- storageRequirements - Storage requirements (free space required). - Domain: SoftwareApplication - Range: Text - Range: URL -
-
- streetAddress - The street address. For example, 1600 Amphitheatre Pkwy. - Domain: PostalAddress - Range: Text -
- -
- subEvent - An Event that is part of this event. For example, a conference event includes many presentations, each of which is a subEvent of the conference. - Domain: Event - Range: Event - -
-
- subEvents - - Events that are a part of this event. For example, a conference event includes many presentations, each subEvents of the conference. - Domain: Event - Range: Event -
-
- subOrganization - A relationship between two organizations where the first includes the second, e.g., as a subsidiary. See also: the more specific 'department' property. - Domain: Organization - Range: Organization - -
-
- subtitleLanguage - Languages in which subtitles/captions are available, in [IETF BCP 47 standard format](http://tools.ietf.org/html/bcp47). - Domain: Movie - Domain: ScreeningEvent - Domain: TVEpisode - Range: Text - Range: Language -
- -
- successorOf - A pointer from a newer variant of a product to its previous, often discontinued predecessor. - Domain: ProductModel - Range: ProductModel -
- -
- suggestedGender - The gender of the person or audience. - Domain: PeopleAudience - Range: Text -
-
- suggestedMaxAge - Maximal age recommended for viewing content. - Domain: PeopleAudience - Range: Number -
-
- suggestedMinAge - Minimal age recommended for viewing content. - Domain: PeopleAudience - Range: Number -
-
- suitableForDiet - Indicates a dietary restriction or guideline for which this recipe or menu item is suitable, e.g. diabetic, halal etc. - Domain: MenuItem - Domain: Recipe - Range: RestrictedDiet -
-
- superEvent - An event that this event is a part of. For example, a collection of individual music performances might each have a music festival as their superEvent. - - Domain: Event - Range: Event -
-
- supportingData - Supporting data for a SoftwareApplication. - Domain: SoftwareApplication - Range: DataFeed -
-
- targetDescription - The description of a node in an established educational framework. - Domain: AlignmentObject - Range: Text -
-
- targetName - The name of a node in an established educational framework. - Domain: AlignmentObject - Range: Text -
-
- targetPlatform - Type of app development: phone, Metro style, desktop, XBox, etc. - Domain: APIReference - Range: Text -
- -
- targetProduct - Target Operating System / Product to which the code applies. If applies to several versions, just the product name can be used. - Domain: SoftwareSourceCode - Range: SoftwareApplication -
-
- targetUrl - The URL of a node in an established educational framework. - Domain: AlignmentObject - Range: URL -
-
- taxID - The Tax / Fiscal ID of the organization or person, e.g. the TIN in the US or the CIF/NIF in Spain. - Domain: Organization - Domain: Person - Range: Text -
-
- telephone - The telephone number. - Domain: Organization - Domain: Place - Domain: ContactPoint - Domain: Person - Range: Text -
- -
- temporalCoverage - The temporalCoverage of a CreativeWork indicates the period that the content applies to, i.e. that it describes, either as a DateTime or as a textual string indicating a time period in [ISO 8601 time interval format](https://en.wikipedia.org/wiki/ISO_8601#Time_intervals). In - the case of a Dataset it will typically indicate the relevant time period in a precise notation (e.g. for a 2011 census dataset, the year 2011 would be written "2011/2012"). Other forms of content e.g. ScholarlyArticle, Book, TVSeries or TVEpisode may indicate their temporalCoverage in broader terms - textually or via well-known URL. - Written works such as books may sometimes have precise temporal coverage too, e.g. a work set in 1939 - 1945 can be indicated in ISO 8601 interval format format via "1939/1945". - Domain: CreativeWork - Range: DateTime - Range: Text - Range: URL - -
-
- temporal - - The range of temporal applicability of a dataset, e.g. for a 2011 census dataset, the year 2011 (in ISO 8601 time interval format). - Domain: Dataset - Range: DateTime -
-
- datasetTimeInterval - The range of temporal applicability of a dataset, e.g. for a 2011 census dataset, the year 2011 (in ISO 8601 time interval format). - - Domain: Dataset - Range: DateTime -
-
- text - The textual content of this CreativeWork. - Domain: CreativeWork - Range: Text -
-
- thumbnail - Thumbnail image for an image or video. - Domain: ImageObject - Domain: VideoObject - Range: ImageObject -
-
- thumbnailUrl - A thumbnail image relevant to the Thing. - Domain: CreativeWork - Range: URL -
-
- tickerSymbol - The exchange traded instrument associated with a Corporation object. The tickerSymbol is expressed as an exchange and an instrument name separated by a space character. For the exchange component of the tickerSymbol attribute, we recommend using the controlled vocaulary of Market Identifier Codes (MIC) specified in ISO15022. - Domain: Corporation - Range: Text -
-
- timeRequired - Approximate or typical time it takes to work with or through this learning resource for the typical intended target audience, e.g. 'P30M', 'P1H25M'. - Domain: CreativeWork - Range: Duration -
- -
- title - The title of the job. - Domain: JobPosting - Range: Text -
-
- toLocation - A sub property of location. The final location of the object or the agent after the action. - - Domain: InsertAction - Domain: MoveAction - Domain: TransferAction - Domain: ExerciseAction - Range: Place -
- -
- toRecipient - A sub property of recipient. The recipient who was directly sent the message. - - Domain: Message - Range: Audience - Range: ContactPoint - Range: Organization - Range: Person -
-
- trackingNumber - Shipper tracking number. - Domain: ParcelDelivery - Range: Text -
-
- trackingUrl - Tracking url for the parcel delivery. - Domain: ParcelDelivery - Range: URL -
-
- tracks - - A music recording (track)&#x2014;usually a single song. - Domain: MusicPlaylist - Domain: MusicGroup - Range: MusicRecording -
-
- trailer - The trailer of a movie or tv/radio series, season, episode, etc. - Domain: Movie - Domain: Episode - Domain: CreativeWorkSeason - Domain: VideoGame - Domain: VideoGameSeries - Domain: MovieSeries - Domain: RadioSeries - Domain: TVSeries - Range: VideoObject -
-
- transcript - If this MediaObject is an AudioObject or VideoObject, the transcript of that object. - Domain: AudioObject - Domain: VideoObject - Range: Text -
- -
- typeOfGood - The product that this structured value is referring to. - Domain: OwnershipInfo - Domain: TypeAndQuantityNode - Range: Product - Range: Service - -
-
- typicalAgeRange - The typical expected age range, e.g. '7-9', '11-'. - Domain: CreativeWork - Domain: Event - Range: Text -
- -
- unitCode - The unit of measurement given using the UN/CEFACT Common Code (3 characters) or a URL. Other codes than the UN/CEFACT Common Code may be used with a prefix followed by a colon. - Domain: QuantitativeValue - Domain: TypeAndQuantityNode - Domain: UnitPriceSpecification - Domain: PropertyValue - Range: Text - Range: URL -
- -
- uploadDate - Date when this media object was uploaded to this site. - Domain: MediaObject - Range: Date -
-
- url - URL of the item. - Domain: Thing - Range: URL -
- -
- validFor - The time validity of the permit. - Domain: Permit - Range: Duration -
-
- validFrom - The date when the item becomes valid. - Domain: Offer - Domain: PriceSpecification - Domain: PriceSpecification - Domain: Demand - Domain: OpeningHoursSpecification - Domain: Permit - Domain: LocationFeatureSpecification - Range: DateTime -
-
- validIn - The geographic area where the permit is valid. - Domain: Permit - Range: AdministrativeArea -
-
- validThrough - The date after when the item is not valid. For example the end of an offer, salary period, or a period of opening hours. - Domain: Offer - Domain: PriceSpecification - Domain: PriceSpecification - Domain: Demand - Domain: JobPosting - Domain: OpeningHoursSpecification - Domain: LocationFeatureSpecification - Range: DateTime -
-
- validUntil - The date when the item is no longer valid. - Domain: Permit - Range: Date -
-
- value - The value of the quantitative value or property value node.\n\n* For [[QuantitativeValue]] and [[MonetaryAmount]], the recommended type for values is 'Number'.\n* For [[PropertyValue]], it can be 'Text;', 'Number', 'Boolean', or 'StructuredValue'. - Domain: QuantitativeValue - Domain: PropertyValue - Domain: MonetaryAmount - Range: Number - Range: Text - Range: Boolean - Range: StructuredValue -
-
- valueAddedTaxIncluded - Specifies whether the applicable value-added tax (VAT) is included in the price specification or not. - Domain: PriceSpecification - Range: Boolean -
-
- valueReference - A pointer to a secondary value that provides additional information on the original value, e.g. a reference temperature. - Domain: QualitativeValue - Domain: QuantitativeValue - Domain: PropertyValue - Range: Enumeration - Range: StructuredValue - - Range: PropertyValue - Range: QualitativeValue - Range: QuantitativeValue - -
-
- vatID - The Value-added Tax ID of the organization or person. - Domain: Organization - Domain: Person - Range: Text -
-
- vendor - 'vendor' is an earlier term for 'seller'. - - Domain: BuyAction - Range: Organization - Range: Person - -
-
- version - The version of the CreativeWork embodied by a specified resource. - Domain: CreativeWork - Range: Number - Range: Text -
-
- video - An embedded video object. - Domain: CreativeWork - Range: VideoObject -
-
- videoFrameSize - The frame size of the video. - Domain: VideoObject - Range: Text -
-
- videoQuality - The quality of the video. - Domain: VideoObject - Range: Text -
- -
- warranty - The warranty promise(s) included in the offer. - Domain: Offer - Domain: Demand - Range: WarrantyPromise -
-
- paymentDue - The date that payment is due. - - Domain: Order - Domain: Invoice - Range: DateTime -
-
- paymentDueDate - The date that payment is due. - Domain: Order - Domain: Invoice - Range: DateTime -
-
- paymentMethod - The name of the credit card or other method of payment for the order. - Domain: Order - Domain: Invoice - Range: PaymentMethod -
-
- paymentMethodId - An identifier for the method of payment used (e.g. the last 4 digits of the credit card). - Domain: Order - Domain: Invoice - Range: Text - -
-
- warrantyPromise - The warranty promise(s) included in the offer. - - Domain: BuyAction - Domain: SellAction - Range: WarrantyPromise -
-
- warrantyScope - The scope of the warranty promise. - Domain: WarrantyPromise - Range: WarrantyScope -
-
- weight - The weight of the product or person. - Domain: Product - Domain: Person - Range: QuantitativeValue -
-
- width - The width of the item. - Domain: MediaObject - Domain: Product - Range: Distance - Range: QuantitativeValue -
-
- winner - A sub property of participant. The winner of the action. - - Domain: LoseAction - Range: Person -
-
- wordCount - The number of words in the text of the Article. - Domain: Article - Range: Integer -
-
- workHours - The typical working hours for this job (e.g. 1st shift, night shift, 8am-5pm). - Domain: JobPosting - Range: Text -
- -
- workLocation - A contact location for a person's place of work. - - Domain: Person - Range: ContactPoint - Range: Place -
-
- worksFor - Organizations that the person works for. - Domain: Person - Range: Organization -
-
- worstRating - The lowest value allowed in this rating system. If worstRating is omitted, 1 is assumed. - Domain: Rating - Range: Number - Range: Text -
-
- yearlyRevenue - The size of the business in annual revenue. - Domain: BusinessAudience - Range: QuantitativeValue -
-
- yearsInOperation - The age of the business. - Domain: BusinessAudience - Range: QuantitativeValue -
- -
- WikiDoc - This class contains information contributed by [http://wikidoc.org>WikiDoc](http://wikidoc.org>WikiDoc). -
- -
- Stack Exchange - The Question/Answer types were [based on](https://www.w3.org/wiki/WebSchemas/QASchemaResearch) the Stack Overflow API. -
- -
- rNews - This class contains derivatives of IPTC rNews properties. rNews is a data model of publishing metadata with serializations currently available for RDFa as well as HTML5 Microdata. More information about the IPTC and rNews can be found at [rnews.org](http://rnews.org). -
- -
- The Trust Project - This term and associated definitions draws upon the work of [The Trust Project](http://thetrustproject.org/). -
- -
- DatasetClass - This class is based upon W3C DCAT work, and benefits from collaboration around the DCAT, ADMS and VoID vocabularies. See http://www.w3.org/wiki/WebSchemas/Datasets for full details and mappings. -
- -
- GoodRelationsClass - This class is derived from the GoodRelations Vocabulary for E-Commerce, created by Martin Hepp. GoodRelations is a data model for sharing e-commerce data on the Web that can be expressed in a variety of syntaxes, including RDFa and HTML5 Microdata. More information about GoodRelations can be found at [http://purl.org/goodrelations/](http://purl.org/goodrelations/). -
- -
- GoodRelationsTerms - This term [uses](http://blog.schema.org/2012/11/good-relations-and-schemaorg.html) terminology from the GoodRelations Vocabulary for E-Commerce, created by Martin Hepp. GoodRelations is a data model for sharing e-commerce data on the Web. More information about GoodRelations can be found at [http://purl.org/goodrelations/](http://purl.org/goodrelations/). -
- -
- LRMIClass - This class is based on the work of the LRMI project, see lrmi.net for details. -
- -
- ActionCollabClass - The schema.org Actions mechanism benefited from extensive discussions across the Web standards community around W3C, in particular from the [Hydra project](http://purl.org/hydra/)'s community group. -
- -
- BibExTerm - The W3C [Schema Bib Extend](http://www.w3.org/community/schemabibex/) (BibEx) group led the work to improve schema.org for bibliographic information, including terms for periodicals, articles and multi-volume works. The design was inspired in places (e.g. [[pageStart]], [[pageEnd]], [[pagination]]) by the [Bibliographic Ontology](http://bibliontology.com/), 'bibo'. -
- -
- AutomotiveOntologyWGClass - This element is based on the work of the Automotive Ontology Working Group, see [www.automotive-ontology.org](http://www.automotive-ontology.org) for details. Many class and property definitions are inspired by or based on abstracts from Wikipedia, the free encyclopedia. -
-
- -

Reservations

- -
- Reservation - Describes a reservation for travel, dining or an event. Some reservations require tickets. \n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. For offers of tickets, restaurant reservations, flights, or rental cars, use [[Offer]]. - Subclass of: Intangible -
-
- BusReservation - A reservation for bus travel. \n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. For offers of tickets, use [[Offer]]. - Subclass of: Reservation -
-
- EventReservation - A reservation for an event like a concert, sporting event, or lecture.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. For offers of tickets, use [[Offer]]. - Subclass of: Reservation -
-
- FlightReservation - A reservation for air travel.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. For offers of tickets, use [[Offer]]. - Subclass of: Reservation -
-
- FoodEstablishmentReservation - A reservation to dine at a food-related business.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. - Subclass of: Reservation -
-
- LodgingReservation - A reservation for lodging at a hotel, motel, inn, etc.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. - Subclass of: Reservation -
-
- RentalCarReservation - A reservation for a rental car.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. - Subclass of: Reservation -
-
- TaxiReservation - A reservation for a taxi.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. For offers of tickets, use [[Offer]]. - Subclass of: Reservation -
-
- TrainReservation - A reservation for train travel.\n\nNote: This type is for information about actual reservations, e.g. in confirmation emails or HTML pages with individual confirmations of reservations. For offers of tickets, use [[Offer]]. - Subclass of: Reservation -
-
- ReservationPackage - A group of multiple reservations with common values for all sub-reservations. - Subclass of: Reservation -
-
- ReservationStatusType - Enumerated status values for Reservation. - Subclass of: Enumeration -
-
- ReservationCancelled - The status for a previously confirmed reservation that is now cancelled. - type: ReservationStatusType -
-
- ReservationConfirmed - The status of a confirmed reservation. - type: ReservationStatusType -
-
- ReservationHold - The status of a reservation on hold pending an update like credit card number or flight changes. - type: ReservationStatusType -
-
- ReservationPending - The status of a reservation when a request has been sent, but not confirmed. - type: ReservationStatusType -
-
- BusTrip - A trip on a commercial bus line. - Subclass of: Intangible -
-
- TrainTrip - A trip on a commercial train line. - Subclass of: Intangible -
-
- Flight - An airline flight. - Subclass of: Intangible -
-
- Airline - An organization that provides flights for passengers. - Subclass of: Organization -
-
- ProgramMembership - Used to describe membership in a loyalty programs (e.g. "StarAliance"), traveler clubs (e.g. "AAA"), purchase clubs ("Safeway Club"), etc. - Subclass of: Intangible -
-
- Ticket - Used to describe a ticket to an event, a flight, a bus ride, etc. - Subclass of: Intangible -
-
- Seat - Used to describe a seat, such as a reserved seat in an event reservation. - Subclass of: Intangible -
-
- Taxi - - A taxi. - Subclass of: Service -
-
- TaxiService - A service for a vehicle for hire with a driver for local travel. Fares are usually calculated based on distance traveled. - Subclass of: Service -
-
- Vehicle - A vehicle is a device that is designed or used to transport people or cargo over land, water, air, or through space. - Subclass of: Product -
-
- Car - Source: GAO - A car is a wheeled, self-powered motor vehicle used for transportation. - Subclass of: Vehicle -
-
- reservationId - A unique identifier for the reservation. - domain: Reservation - Range: Text -
-
- reservationStatus - The current status of the reservation. - domain: Reservation - Range: ReservationStatusType -
-
- reservationFor - The thing -- flight, event, restaurant,etc. being reserved. - domain: Reservation - Range: Thing -
-
- underName - The person or organization the reservation or ticket is for. - domain: Reservation - domain: Ticket - Range: Person - Range: Organization -
-
- provider - The service provider, service operator, or service performer; the goods producer. Another party (a seller) may offer those services or goods on behalf of the provider. A provider may also serve as the seller. - domain: CreativeWork - domain: Service - domain: Invoice - domain: Reservation - domain: Flight - domain: ParcelDelivery - domain: TrainTrip - domain: BusTrip - Range: Person - Range: Organization -
-
- providerMobility - Indicates the mobility of a provided service (e.g. 'static', 'dynamic'). - domain: Service - Range: Text -
-
- bookingAgent - 'bookingAgent' is an out-dated term indicating a 'broker' that serves as a booking agent. - domain: Reservation - Range: Person - Range: Organization - -
-
- bookingTime - The date and time the reservation was booked. - domain: Reservation - Range: DateTime -
-
- modifiedTime - The date and time the reservation was modified. - domain: Reservation - Range: DateTime -
-
- programMembershipUsed - Any membership in a frequent flyer, hotel loyalty program, etc. being applied to the reservation. - domain: Reservation - Range: ProgramMembership -
-
- reservedTicket - A ticket associated with the reservation. - domain: Reservation - Range: Ticket -
-
- totalPrice - The total price for the reservation or ticket, including applicable taxes, shipping, etc. - domain: Reservation - domain: Ticket - Range: Number - Range: Text - Range: PriceSpecification -
-
- priceCurrency - The currency (in 3-letter ISO 4217 format) of the price or a price component, when attached to [[PriceSpecification]] and its subtypes. - domain: Reservation - domain: Ticket - Domain: Offer - Domain: PriceSpecification - Range: Text - -
-
- membershipNumber - A unique identifier for the membership. - domain: ProgramMembership - Range: Text -
-
- programName - The program providing the membership. - domain: ProgramMembership - Range: Text -
-
- hostingOrganization - The organization (airline, travelers' club, etc.) the membership is made with. - domain: ProgramMembership - Range: Organization -
-
- issuedBy - The organization issuing the ticket or permit. - domain: Ticket - Domain: Permit - Range: Organization -
-
- dateIssued - The date the ticket was issued. - domain: Ticket - Range: DateTime -
-
- ticketedSeat - The seat associated with the ticket. - domain: Ticket - Range: Seat -
-
- ticketNumber - The unique identifier for the ticket. - domain: Ticket - Range: Text -
-
- ticketToken - Reference to an asset (e.g., Barcode, QR code image or PDF) usable for entrance. - domain: Ticket - Range: Text - Range: URL -
-
- seatNumber - The location of the reserved seat (e.g., 27). - domain: Seat - Range: Text -
-
- seatRow - The row location of the reserved seat (e.g., B). - domain: Seat - Range: Text -
-
- seatSection - The section location of the reserved seat (e.g. Orchestra). - domain: Seat - Range: Text -
-
- seatingType - The type/class of the seat. - domain: Seat - Range: Text - Range: QualitativeValue -
-
- subReservation - The individual reservations included in the package. Typically a repeated property. - domain: ReservationPackage - Range: Reservation -
-
- boardingGroup - The airline-specific indicator of boarding order / preference. - domain: ReservationPackage - Range: Text -
-
- passengerSequenceNumber - The passenger's sequence number as assigned by the airline. - domain: FlightReservation - Range: Text -
-
- securityScreening - The type of security screening the passenger is subject to. - domain: FlightReservation - Range: Text -
-
- passengerPriorityStatus - The priority status assigned to a passenger for security or boarding (e.g. FastTrack or Priority). - domain: FlightReservation - Range: Text - Range: QualitativeValue -
-
- flightNumber - The unique identifier for a flight including the airline IATA code. For example, if describing United flight 110, where the IATA code for United is 'UA', the flightNumber is 'UA110'. - domain: Flight - Range: Text -
- - -
- departureTime - The expected departure time. - domain: BusTrip - domain: Flight - domain: TrainTrip - Range: DateTime -
-
- arrivalTime - The expected arrival time. - domain: BusTrip - domain: Flight - domain: TrainTrip - Range: DateTime -
-
- departureAirport - The airport where the flight originates. - domain: Flight - Range: Airport -
-
- arrivalAirport - The airport where the flight terminates. - domain: Flight - Range: Airport -
-
- departureGate - Identifier of the flight's departure gate. - domain: Flight - Range: Text -
-
- arrivalGate - Identifier of the flight's arrival gate. - domain: Flight - Range: Text -
-
- boardingPolicy - The type of boarding policy used by the airline (e.g. zone-based or group-based). - domain: Airline - domain: Flight - Range: BoardingPolicyType -
-
- departureTerminal - Identifier of the flight's departure terminal. - domain: Flight - Range: Text -
-
- arrivalTerminal - Identifier of the flight's arrival terminal. - domain: Flight - Range: Text -
-
- aircraft - The kind of aircraft (e.g., "Boeing 747"). - domain: Flight - Range: Text - Range: Vehicle -
-
- mealService - Description of the meals that will be provided or available for purchase. - domain: Flight - Range: Text -
-
- estimatedFlightDuration - The estimated time the flight will take. - domain: Flight - Range: Text - Range: Duration -
-
- flightDistance - The distance of the flight. - domain: Flight - Range: Text - Range: Distance -
-
- webCheckinTime - The time when a passenger can check into the flight online. - domain: Flight - Range: DateTime -
-
- iataCode - IATA identifier for an airline or airport. - domain: Airline - domain: Airport - Range: Text -
-
- icaoCode - ICAO identifier for an airport. - domain: Airport - Range: Text -
-
- partySize - Number of people the reservation should accommodate. - domain: FoodEstablishmentReservation - domain: TaxiReservation - Range: Integer - Range: QuantitativeValue -
-
- trainNumber - The unique identifier for the train. - domain: TrainTrip - Range: Text -
-
- trainName - The name of the train (e.g. The Orient Express). - domain: TrainTrip - Range: Text -
-
- departureStation - The station from which the train departs. - domain: TrainTrip - Range: TrainStation -
-
- arrivalStation - The station where the train trip ends. - domain: TrainTrip - Range: TrainStation -
-
- departurePlatform - The platform from which the train departs. - domain: TrainTrip - Range: Text -
-
- arrivalPlatform - The platform where the train arrives. - domain: TrainTrip - Range: Text -
-
- busNumber - The unique identifier for the bus. - domain: BusTrip - Range: Text -
-
- busName - The name of the bus (e.g. Bolt Express). - domain: BusTrip - Range: Text -
-
- departureBusStop - The stop or station from which the bus departs. - domain: BusTrip - Range: BusStation - Range: BusStop -
-
- arrivalBusStop - The stop or station from which the bus arrives. - domain: BusTrip - Range: BusStation - Range: BusStop -
-
- pickupLocation - Where a taxi will pick up a passenger or a rental car can be picked up. - domain: RentalCarReservation - domain: TaxiReservation - Range: Place -
-
- dropoffLocation - Where a rental car can be dropped off. - domain: RentalCarReservation - Range: Place -
-
- pickupTime - When a taxi will pickup a passenger or a rental car can be picked up. - domain: RentalCarReservation - domain: TaxiReservation - Range: DateTime -
-
- dropoffTime - When a rental car can be dropped off. - domain: RentalCarReservation - Range: DateTime -
-
- checkinTime - The earliest someone may check into a lodging establishment. - domain: LodgingReservation - domain: LodgingBusiness - Range: DateTime -
-
- checkoutTime - The latest someone may check out of a lodging establishment. - domain: LodgingReservation - domain: LodgingBusiness - Range: DateTime -
-
- lodgingUnitType - Textual description of the unit type (including suite vs. room, size of bed, etc.). - domain: LodgingReservation - Range: Text - Range: QualitativeValue -
-
- lodgingUnitDescription - A full description of the lodging unit. - domain: LodgingReservation - Range: Text -
-
- numAdults - The number of adults staying in the unit. - domain: LodgingReservation - Range: Integer - Range: QuantitativeValue -
-
- numChildren - The number of children staying in the unit. - domain: LodgingReservation - Range: Integer - Range: QuantitativeValue -
- -
- BoardingPolicyType - A type of boarding policy used by an airline. - Subclass of: Enumeration -
-
- ZoneBoardingPolicy - The airline boards by zones of the plane. -
-
- GroupBoardingPolicy - The airline boards by groups based on check-in time, priority, etc. -
- -
- -

Questions and Answers (QA) and FAQ schema

-

Enrichment of Schema.org to enable annotation of questions and answers content, as discussed on public-vocabs@w3.org.

-

See wiki for details.

- - -
- QAPage - A QAPage is a WebPage focused on a specific Question and its Answer(s), e.g. in a question answering site or documenting Frequently Asked Questions (FAQs). - Subclass of: WebPage -
- - -
- Question - A specific question - e.g. from a user seeking answers online, or collected in a Frequently Asked Questions (FAQ) document. - Subclass of: CreativeWork - Source: Stack Overflow -
- -
- upvoteCount - The number of upvotes this question, answer or comment has received from the community. - Domain: Question - Domain: Comment - Range: Integer -
-
- downvoteCount - The number of downvotes this question, answer or comment has received from the community. - Domain: Question - Domain: Comment - Range: Integer -
- - - - - -
- answerCount - The number of answers this question has received. - Domain: Question - Range: Integer -
-
- commentCount - The number of comments this CreativeWork (e.g. Article, Question or Answer) has received. This is most applicable to works published in Web sites with commenting system; additional comments may exist elsewhere. - Domain: CreativeWork - Range: Integer -
- -
- acceptedAnswer - The answer that has been accepted as best, typically on a Question/Answer site. Sites vary in their selection mechanisms, e.g. drawing on community opinion and/or the view of the Question author. - - Domain: Question - Range: Answer -
- - -
- Answer - An answer offered to a question; perhaps correct, perhaps opinionated or wrong. - Subclass of: Comment - Source: Stack Overflow -
- -
- parentItem - The parent of a question, answer or item in general. - Domain: Comment - Range: Question -
- - - - - -
- suggestedAnswer - An answer (possibly one of several, possibly incorrect) to a Question, e.g. on a Question/Answer site. - Domain: Question - Range: Answer -
- - -
- -

EmailMessage

- -
- EmailMessage - An email message. - Subclass of: Message -
- -
- - -

Potential Actions

- - -
- actionStatus - Indicates the current disposition of the Action. - Domain: Action - Range: ActionStatusType -
- -
- ActionStatusType - The status of an Action. - Subclass of: Enumeration -
- -
- PotentialActionStatus - A description of an action that is supported. -
- -
- ActiveActionStatus - An in-progress action (e.g, while watching the movie, or driving to a location). -
- -
- CompletedActionStatus - An action that has already taken place. -
- -
- FailedActionStatus - An action that failed to complete. The action's error property and the HTTP return code contain more information about the failure. -
- -
- error - For failed actions, more information on the cause of the failure. - Domain: Action - Range: Thing -
- -
- potentialAction - Indicates a potential Action, which describes an idealized action in which this thing would play an 'object' role. - Domain: Thing - Range: Action -
- -
- EntryPoint - An entry point, within some Web-based protocol. - Subclass of: Intangible - Source: Action collaborations -
- -
- actionPlatform - The high level platform(s) where the Action can be performed for the given URL. To specify a specific application or operating system instance, use actionApplication. - Domain: EntryPoint - Range: - Range: -
- -
- target - Indicates a target EntryPoint for an Action. - Domain: Action - Range: EntryPoint -
- -
- httpMethod - An HTTP method that specifies the appropriate HTTP method for a request to an HTTP EntryPoint. Values are capitalized strings as used in HTTP. - Domain: EntryPoint - Range: Text -
- - -
- encodingType - The supported encoding type(s) for an EntryPoint request. - Domain: EntryPoint - Range: Text -
- -
- contentType - The supported content type(s) for an EntryPoint response. - Domain: EntryPoint - Range: Text -
- -
- application - - An application that can complete the request. - Domain: EntryPoint - Range: SoftwareApplication -
-
- actionApplication - An application that can complete the request. - Domain: EntryPoint - Range: SoftwareApplication -
- -
- PropertyValueSpecification - A Property value specification. - Subclass of: Intangible - Source: Action collaborations -
- -
- urlTemplate - An url template (RFC6570) that will be used to construct the target of the execution of the action. - Domain: EntryPoint - Range: Text -
- -
- valueName - Indicates the name of the PropertyValueSpecification to be used in URL templates and form encoding in a manner analogous to HTML's input@name. - Domain: PropertyValueSpecification - Range: Text -
- -
- valueRequired - Whether the property must be filled in to complete the action. Default is false. - Domain: PropertyValueSpecification - Range: Boolean -
- -
- defaultValue - The default value of the input. For properties that expect a literal, the default is a literal value, for properties that expect an object, it's an ID reference to one of the current values. - Domain: PropertyValueSpecification - Range: Thing - Range: Text -
- -
- readonlyValue - Whether or not a property is mutable. Default is false. Specifying this for a property that also has a value makes it act similar to a "hidden" input in an HTML form. - Domain: PropertyValueSpecification - Range: Boolean -
- -
- multipleValues - Whether multiple values are allowed for the property. Default is false. - Domain: PropertyValueSpecification - Range: Boolean -
- -
- valueMinLength - Specifies the minimum allowed range for number of characters in a literal value. - Domain: PropertyValueSpecification - Range: Number -
- -
- valueMaxLength - Specifies the allowed range for number of characters in a literal value. - Domain: PropertyValueSpecification - Range: Number -
- -
- valuePattern - Specifies a regular expression for testing literal values according to the HTML spec. - Domain: PropertyValueSpecification - Range: Text -
-
- workPresented - The movie presented during this event. - - Domain: ScreeningEvent - Range: Movie -
- - - -
- stepValue - The stepValue attribute indicates the granularity that is expected (and required) of the value in a PropertyValueSpecification. - Domain: PropertyValueSpecification - Range: Number -
- -

workPerformed

- -
- workPerformed - A work performed in some event, for example a play performed in a TheaterEvent. - - domainIncludes: Event - rangeIncludes: CreativeWork -
- -
- workFeatured - A work featured in some event, e.g. exhibited in an ExhibitionEvent. - Specific subproperties are available for workPerformed (e.g. a play), or a workPresented (a Movie at a ScreeningEvent). - domainIncludes: Event - rangeIncludes: CreativeWork -
- - -

Role

- -
- Role - Represents additional information about a relationship or property. For example a Role can be used to say that a 'member' role linking some SportsTeam to a player occurred during a particular time period. Or that a Person's 'actor' role in a Movie was for some particular characterName. Such properties can be attached to a Role entity, which is then associated with the main entities using ordinary properties like 'member' or 'actor'.\n\nSee also [blog post](http://blog.schema.org/2014/06/introducing-role.html). - Subclass of: Intangible -
- -
- PerformanceRole - A PerformanceRole is a Role that some entity places with regard to a theatrical performance, e.g. in a Movie, TVSeries etc. - Subclass of: Role -
- -
- characterName - The name of a character played in some acting or performing role, i.e. in a PerformanceRole. - domainIncludes: PerformanceRole - rangeIncludes: Text -
- -
- OrganizationRole - A subclass of Role used to describe roles within organizations. - Subclass of: Role -
- -
- namedPosition - - A position played, performed or filled by a person or organization, as part of an organization. For example, an athlete in a SportsTeam might play in the position named 'Quarterback'. - domainIncludes: Role - rangeIncludes: Text - rangeIncludes: URL -
- -
- roleName - A role played, performed or filled by a person or organization. For example, the team of creators for a comic book might fill the roles named 'inker', 'penciller', and 'letterer'; or an athlete in a SportsTeam might play in the position named 'Quarterback'. - domainIncludes: Role - rangeIncludes: Text - rangeIncludes: URL -
- - -
- EmployeeRole - A subclass of OrganizationRole used to describe employee relationships. - Subclass of: OrganizationRole -
- -

WebSite

- -
- WebSite - A WebSite is a set of related web pages and other items typically served from a single web domain and accessible via URLs. - Subclass of: CreativeWork -
- -

Periodicals and BibExtend-related

- -
- Periodical - A publication in any medium issued in successive parts bearing numerical or chronological designations and intended, such as a magazine, scholarly journal, or newspaper to continue indefinitely.\n\nSee also [blog post](http://blog.schema.org/2014/09/schemaorg-support-for-bibliographic_2.html). - Subclass of: CreativeWorkSeries - - Source: BibEx -
- -
- PublicationVolume - A part of a successively published publication such as a periodical or multi-volume work, often numbered. It may represent a time span, such as a year. - - <br/><br/>See also <a href="http://blog.schema.org/2014/09/schemaorg-support-for-bibliographic_2.html">blog post</a>. - Subclass of: CreativeWork - Source: BibEx -
-
- PublicationIssue - A part of a successively published publication such as a periodical or publication volume, often numbered, usually containing a grouping of works such as articles.\n\n[blog post](http://blog.schema.org/2014/09/schemaorg-support-for-bibliographic_2.html). - Subclass of: CreativeWork - - Source: BibEx -
-
- hasPart - Indicates a CreativeWork that is (in some sense) a part of this CreativeWork. - Domain: CreativeWork - Range: CreativeWork - - Source: BibEx -
-
- issn - The International Standard Serial Number (ISSN) that identifies this serial publication. You can repeat this property to identify different formats of, or the linking ISSN (ISSN-L) for, this serial publication. - Domain: CreativeWorkSeries - Domain: Blog - Domain: Dataset - Domain: WebSite - Range: Text - - Source: BibEx -
-
- issueNumber - Identifies the issue of publication; for example, "iii" or "2". - - Domain: PublicationIssue - Range: Integer - Range: Text - - Source: BibEx -
-
- pageEnd - The page on which the work ends; for example "138" or "xvi". - Domain: PublicationVolume - Domain: PublicationIssue - Domain: Article - Range: Integer - Range: Text - - Source: BibEx -
-
- pageStart - The page on which the work starts; for example "135" or "xiii". - Domain: PublicationVolume - Domain: PublicationIssue - Domain: Article - Range: Integer - Range: Text - - Source: BibEx -
-
- pagination - Any description of pages that is not separated into pageStart and pageEnd; for example, "1-6, 9, 55" or "10-12, 46-49". - Domain: PublicationVolume - Domain: PublicationIssue - Domain: Article - Range: Text - - Source: BibEx -
-
- volumeNumber - Identifies the volume of publication or multi-part work; for example, "iii" or "2". - - Domain: PublicationVolume - Range: Integer - Range: Text - - Source: BibEx -
- -
- workExample - Example/instance/realization/derivation of the concept of this creative work. eg. The paperback edition, first edition, or eBook. - Domain: CreativeWork - Range: CreativeWork - Source: BibEx - -
- -
- exampleOfWork - A creative work that this work is an example/instance/realization/derivation of. - Domain: CreativeWork - Range: CreativeWork - Source: BibExt - -
- -

Broker

- -
- broker - An entity that arranges for an exchange between a buyer and a seller. In most cases a broker never acquires or releases ownership of a product or service involved in an exchange. If it is not clear whether an entity is a broker, seller, or buyer, the latter two terms are preferred. - domainIncludes: Reservation - domainIncludes: Order - domainIncludes: Invoice - domainIncludes: Service - rangeIncludes: Person - rangeIncludes: Organization -
- -

ItemList and ListItem extras

- -
- itemListElement - For itemListElement values, you can use simple strings (e.g. "Peter", "Paul", "Mary"), existing entities, or use ListItem.\n\nText values are best if the elements in the list are plain strings. Existing entities are best for a simple, unordered list of existing things in your data. ListItem is used with ordered lists when you want to provide additional context about the element in that list or when the same item might be in different places in different lists.\n\nNote: The order of elements in your mark-up is not sufficient for indicating the order or elements. Use ListItem with a 'position' property in such cases. - Domain: ItemList - Range: Text - Range: ListItem - Range: Thing -
- -
- ListItem - An list item, e.g. a step in a checklist or how-to description. - Subclass of: Intangible -
- - - -
- item - An entity represented by an entry in a list or data feed (e.g. an 'artist' in a list of 'artists')’. - Domain: ListItem - Domain: DataFeedItem - Range: Thing -
- -
- previousItem - A link to the ListItem that precedes the current one. - Domain: ListItem - Domain: ListItem -
- -
- nextItem - A link to the ListItem that follows the current one. - Domain: ListItem - Domain: ListItem -
- - - -

MovieSeries, BookSeries

- -

(minimal additions to fit with VideoGameSeries integration)

- -
- MovieSeries - A series of movies. Included movies can be indicated with the hasPart property. - Subclass of: CreativeWorkSeries -
- -
- BookSeries - A series of books. Included books can be indicated with the hasPart property. - Subclass of: CreativeWorkSeries -
- - -

VideoGame

- -
- VideoGame - A video game is an electronic game that involves human interaction with a user interface to generate visual feedback on a video device. - Subclass of: SoftwareApplication - Subclass of: Game -
- -
- VideoGameClip - A short segment/part of a video game. - Subclass of: Clip -
- -
- GameServer - Server that provides game interaction in a multiplayer game. - Subclass of: Intangible -
-
- Game - The Game type represents things which are games. These are typically rule-governed recreational activities, e.g. role-playing games in which players assume the role of characters in a fictional setting. - Subclass of: CreativeWork -
- -
- GamePlayMode - Indicates whether this game is multi-player, co-op or single-player. - Subclass of: Enumeration -
- -
- MultiPlayer - Play mode: MultiPlayer. Requiring or allowing multiple human players to play simultaneously. -
-
- CoOp - Play mode: CoOp. Co-operative games, where you play on the same team with friends. -
-
- SinglePlayer - Play mode: SinglePlayer. Which is played by a lone player. -
- -
- GameServerStatus - Status of a game server. - Subclass of: Enumeration -
- -
- Online - Game server status: Online. Server is available. -
-
- OnlineFull - Game server status: OnlineFull. Server is online but unavailable. The maximum number of players has reached. -
-
- OfflineTemporarily - Game server status: OfflineTemporarily. Server is offline now but it can be online soon. -
-
- OfflinePermanently - Game server status: OfflinePermanently. Server is offline and not available. -
- -
- numberOfPlayers - Indicate how many people can play this game (minimum, maximum, or range). - Domain: Game - Domain: VideoGameSeries - Range: QuantitativeValue -
-
- quest - The task that a player-controlled character, or group of characters may complete in order to gain a reward. - Domain: Game - Domain: VideoGameSeries - Range: Thing -
-
- gameItem - An item is an object within the game world that can be collected by a player or, occasionally, a non-player character. - Domain: Game - Domain: VideoGameSeries - Range: Thing -
-
- character - Fictional person connected with a creative work. - Domain: CreativeWork - Range: Person -
-
- characterAttribute - A piece of data that represents a particular aspect of a fictional character (skill, power, character points, advantage, disadvantage). - Domain: Game - Domain: VideoGameSeries - Range: Thing -
- -
- playMode - Indicates whether this game is multi-player, co-op or single-player. The game can be marked as multi-player, co-op and single-player at the same time. - Domain: VideoGame - Domain: VideoGameSeries - Range: GamePlayMode -
-
- translator - Organization or person who adapts a creative work to different languages, regional differences and technical requirements of a target market, or that translates during some event. - Domain: CreativeWork - Domain: Event - Range: Person - Range: Organization -
-
- softwareAddOn - Additional content for a software application. - Domain: SoftwareApplication - Range: SoftwareApplication -
-
- cheatCode - Cheat codes to the game. - Domain: VideoGame - Domain: VideoGameSeries - Range: CreativeWork -
-
- softwareHelp - Software application help. - Domain: SoftwareApplication - Range: CreativeWork -
-
- gameTip - Links to tips, tactics, etc. - Domain: VideoGame - Range: CreativeWork -
-
- gamePlatform - The electronic systems used to play <a href="http://en.wikipedia.org/wiki/Category:Video_game_platforms">video games</a>. - Domain: VideoGame - Domain: VideoGameSeries - Range: Text - Range: URL - Range: Thing -
-
- serverStatus - Status of a game server. - Domain: GameServer - Range: GameServerStatus -
-
- playersOnline - Number of players on the server. - Domain: GameServer - Range: Integer -
-
- game - Video game which is played on this server. - Domain: GameServer - Range: VideoGame - -
-
- gameServer - The server on which it is possible to play the game. - Range: GameServer - Domain: VideoGame - -
-
- gameLocation - Real or fictional location of the game (or part of game). - Domain: Game - Domain: VideoGameSeries - Range: URL - Range: Place - Range: PostalAddress -
- -
-

Music

- -

Here we extend schema.org to better describe music, thanks to a collaboration with MusicBrainz.

- -
- MBZ - This vocabulary was improved through collaboration with the MusicBrainz project - ([www.musicbrainz.org](http://www.musicbrainz.org)), and is partially inspired by the MusicBrainz and - [Music Ontology](http://musicontology.com/docs/getting-started.html) schemas. -
- -

We begin by extending MusicAlbum.

- -
- albumProductionType - Classification of the album by it's type of content: soundtrack, live album, studio album, etc. - Domain: MusicAlbum - Range: MusicAlbumProductionType - -
-
- albumReleaseType - The kind of release which this album is: single, EP or album. - Domain: MusicAlbum - Range: MusicAlbumReleaseType - -
-
- albumRelease - A release of this album. - - Domain: MusicAlbum - Range: MusicRelease -
-
- track - A music recording (track)&#x2014;usually a single song. If an ItemList is given, the list should contain items of type MusicRecording. - Domain: MusicPlaylist - Domain: MusicGroup - Range: ItemList - Range: MusicRecording - -
- -

We add an enumeration type: MusicAlbumProductionType.

- -
- MusicAlbumProductionType - Classification of the album by it's type of content: soundtrack, live album, studio album, etc. - Subclass of: Enumeration - -
- -
- CompilationAlbum - CompilationAlbum. - -
-
- DemoAlbum - DemoAlbum. - -
-
- DJMixAlbum - DJMixAlbum. - -
-
- LiveAlbum - LiveAlbum. - -
-
- MixtapeAlbum - MixtapeAlbum. - -
-
- RemixAlbum - RemixAlbum. - -
-
- SoundtrackAlbum - SoundtrackAlbum. - -
-
- SpokenWordAlbum - SpokenWordAlbum. - -
-
- StudioAlbum - StudioAlbum. - -
- - -
- MusicAlbumReleaseType - The kind of release which this album is: single, EP or album. - Subclass of: Enumeration - -
- -
- AlbumRelease - AlbumRelease. - -
-
- BroadcastRelease - BroadcastRelease. - -
-
- EPRelease - EPRelease. - -
-
- SingleRelease - SingleRelease. - -
- -

A new type, MusicComposition + supporting properties.

-
- MusicComposition - A musical composition. - Subclass of: CreativeWork - -
-
- musicArrangement - An arrangement derived from the composition. - Domain: MusicComposition - Range: MusicComposition - -
-
- composer - The person or organization who wrote a composition, or who is the composer of a work performed at some event. - Domain: MusicComposition - Domain: Event - Range: Person - Range: Organization - -
-
- firstPerformance - The date and place the work was first performed. - Domain: MusicComposition - Range: Event - -
-
- includedComposition - Smaller compositions included in this work (e.g. a movement in a symphony). - Domain: MusicComposition - Range: MusicComposition - -
-
- iswcCode - The International Standard Musical Work Code for the composition. - Domain: MusicComposition - Range: Text - -
-
- lyricist - The person who wrote the words. - Domain: MusicComposition - Range: Person - -
-
- musicCompositionForm - The type of composition (e.g. overture, sonata, symphony, etc.). - Domain: MusicComposition - Range: Text - -
-
- musicalKey - The key, mode, or scale this composition uses. - Domain: MusicComposition - Range: Text - -
-
- recordedAs - An audio recording of the work. - - Domain: MusicComposition - Range: MusicRecording - -
- -

Deprecating musicGroupMember in favour of member (already done, but site UI is not ideal; TODO: we should update any examples).

- -

Additions for MusicRecording

- -

TODO: For discussion - do we need something like CreativeWorkContributionRole ?

- -
- isrcCode - The International Standard Recording Code for the recording. - Domain: MusicRecording - Range: Text - -
-
- recordingOf - The composition this track is a recording of. - - Domain: MusicRecording - Range: MusicComposition - -
- -

MusicRelease: Thing > CreativeWork > MusicPlaylist > MusicRelease is a new type describing a specific release of a music album. -

- -
- MusicRelease - A MusicRelease is a specific release of a music album. - -Subclass of: MusicPlaylist -
- -
- catalogNumber - The catalog number for the release. - Domain: MusicRelease - Range: Text - -
- -
- creditedTo - The group the release is credited to if different than the byArtist. For example, Red and Blue is credited to "Stefani Germanotta Band", but by Lady Gaga. - Domain: MusicRelease - Range: Person - Range: Organization - -
- -

NOTE: proposal had 'duration' but this already existed, so just adding MusicRelease as an expected type to MusicRelease.

- -
- Domain: MusicRelease -
- -
- musicReleaseFormat - Format of this release (the type of recording media used, ie. compact disc, digital media, LP, etc.). - Domain: MusicRelease - Range: MusicReleaseFormatType - -
- -

NOTE: also we needed 'producer' to be applicable to a MusicRelease - attaching it to CreativeWork to cover everything. Adding Organization as a possible value.

- -
- recordLabel - The label that issued the release. - Domain: MusicRelease - Range: Organization - - -
- -
- releaseOf -

TODO: broaden meaning or add 'album' to name?

- The album this is a release of. - - Domain: MusicRelease - Range: MusicAlbum - -
- -
- regionsAllowed - The regions where the media is allowed. If not specified, then it's assumed to be allowed everywhere. Specify the countries in [ISO 3166 format](http://en.wikipedia.org/wiki/ISO_3166). - Domain: MediaObject - Range: Place -
- -

Addition to CreativeWork.

- - - - -
- releasedEvent - The place and time the release was issued, expressed as a PublicationEvent. - Domain: CreativeWork - Range: PublicationEvent -
- -

TODO: Add CreativeWorkReleaseRegion - or decide whether PublicationEvent does the job, and rename properties accordingly.

- -
- MusicReleaseFormatType - Format of this release (the type of recording media used, ie. compact disc, digital media, LP, etc.). - Subclass of: Enumeration - -
- -
- CassetteFormat - CassetteFormat. - -
-
- CDFormat - CDFormat. - -
-
- DVDFormat - DVDFormat. - -
-
- DigitalFormat - DigitalFormat. - -
-
- DigitalAudioTapeFormat - DigitalAudioTapeFormat. - -
-
- LaserDiscFormat - LaserDiscFormat. - -
-
- VinylFormat - VinylFormat. - -
- - -

NOTE: Added foundingLocation (Place) to Organization.

-
- foundingLocation - The place where the Organization was founded. - Domain: Organization - Range: Place -
- -
- birthPlace - The place where the person was born. - Domain: Person - Range: Place -
- -
- deathPlace - The place where the person died. - Domain: Person - Range: Place -
- -

NOTE: Added foundingLocation (Place) to Organization.

- -
- - - -
- -

Sports

-

Sports Agents Vocabulary as of 2014-09-16.

- - - -
- Subclass of: SportsOrganization -
- - -
- SportsOrganization - Represents the collection of all sports organizations, including sports teams, governing bodies, and sports associations. - Subclass of: Organization -
-
- sport - A type of sport (e.g. Baseball). - domain: SportsOrganization - Range: Text - Range: URL -
- - -
- coach - A person that acts in a coaching role for a sports team. - domain: SportsTeam - Range: Person -
-
- athlete - A person that acts as performing member of a sports team; a player as opposed to a coach. - domain: SportsTeam - Range: Person -
- - -
- numberedPosition - A number associated with a role in an organization, for example, the number on an athlete's jersey. - domain: OrganizationRole - Range: Number -
- - - - -
- homeTeam - The home team in a sports event. - domain: SportsEvent - Range: Person - Range: SportsTeam - -
- -
- awayTeam - The away team in a sports event. - domain: SportsEvent - Range: Person - Range: SportsTeam - -
- -
- competitor - A competitor in a sports event. - domain: SportsEvent - Range: Person - Range: SportsTeam -
- - -
- - -
-

Dated Money Specification

-

Addition of DatedMoneySpecification as of 2014-11-14.

-

Tweaks: calling it DatedMoneySpecification rather than DatedMoneyValue - for symmetry with PriceSpecification and subtypes. Removed comments on startDate/endDate as definitions are global and these exist.

- - -
- - Subclass of: StructuredValue - -
- - -
- DatedMoneySpecification - - A DatedMoneySpecification represents monetary values with optional start and end dates. For example, this could represent an employee's salary over a specific period of time. __Note:__ This type has been superseded by [[MonetaryAmount]] use of that type is recommended - - Subclass of: StructuredValue - -
- -
- amount - The amount of money. - domain: DatedMoneySpecification - Domain: LoanOrCredit - Domain: InvestmentOrDeposit - Range: MonetaryAmount - Range: Number -
-
- currency - The currency in which the monetary amount is expressed (in 3-letter [ISO 4217](http://en.wikipedia.org/wiki/ISO_4217) format). - domain: DatedMoneySpecification - Domain: MonetaryAmount - Range: Text -
-
- - - domain: DatedMoneySpecification - - - Range: Date - -
-
- - - domain: DatedMoneySpecification - - - Range: Date - Range: DateTime - -
-
-

VisualArtwork

- - -

See discussion and wiki

- - -
- VisualArtwork - A work of art that is primarily visual in character. - Subclass of: CreativeWork - Source: WebSchemas community -
- -
- artform - e.g. Painting, Drawing, Sculpture, Print, Photograph, Assemblage, Collage, etc. - Domain: VisualArtwork - Range: Text - Range: URL -
- -
- material - - A material that something is made from, e.g. leather, wool, cotton, paper. - Domain: CreativeWork - Domain: Product - Range: Text - Range: URL - Range: Product -
-
- artMedium - The material used. (e.g. Oil, Watercolour, Acrylic, Linoprint, Marble, Cyanotype, Digital, Lithograph, DryPoint, Intaglio, Pastel, Woodcut, Pencil, Mixed Media, etc.) - - Domain: VisualArtwork - Range: Text - Range: URL -
- -
- surface - - A material used as a surface in some artwork, e.g. Canvas, Paper, Wood, Board, etc. - - Domain: VisualArtwork - Range: Text - Range: URL -
-
- artworkSurface - The supporting materials for the artwork, e.g. Canvas, Paper, Wood, Board, etc. - Domain: VisualArtwork - Range: Text - Range: URL -
- -
- Domain: VisualArtwork -
- -
- Domain: VisualArtwork -
- -
- Domain: VisualArtwork -
- -
- artEdition - The number of copies when multiple copies of a piece of artwork are produced - e.g. for a limited edition of 20 prints, 'artEdition' refers to the total number of copies (in this example "20"). - Domain: VisualArtwork - Range: Text - Range: Integer -
- -

Bills

-
- Invoice - A statement of the money due for goods or services; a bill. - Subclass of: Intangible -
- -
- totalPaymentDue - The total amount due. - Domain: Invoice - Range: PriceSpecification - Range: MonetaryAmount -
- -
- minimumPaymentDue - The minimum payment required at this time. - Domain: Invoice - Domain: PriceSpecification - Range: MonetaryAmount -
-
- accountId - The identifier for the account the payment will be applied to. - Domain: Invoice - Domain: Text -
-
- scheduledPaymentDate - The date the invoice is scheduled to be paid. - Domain: Invoice - Domain: Date -
-
- billingPeriod - The time interval used to compute the invoice. - Domain: Invoice - Domain: Duration -
-
- paymentStatus - The status of payment; whether the invoice has been paid or not. - Domain: Invoice - Domain: PaymentStatusType - Domain: Text -
- -
- referencesOrder - The Order(s) related to this Invoice. One or more Orders may be combined into a single Invoice. - Domain: Invoice - Domain: Order -
- - - -

Property-Value Support

-
- PropertyValue - A property-value pair, e.g. representing a feature of a product or place. Use the 'name' property for the name of the property. If there is an additional human-readable version of the value, put that into the 'description' property.\n\n Always use specific schema.org properties when a) they exist and b) you can populate them. Using PropertyValue as a substitute will typically not trigger the same effect as using the original, specific property. - - Subclass of: StructuredValue - Source: GoodRelationsClass -
-
- additionalProperty - A property-value pair representing an additional characteristics of the entity, e.g. a product feature or another characteristic for which there is no matching property in schema.org.\n\nNote: Publishers should be aware that applications designed to use specific schema.org properties (e.g. http://schema.org/width, http://schema.org/color, http://schema.org/gtin13, ...) will typically expect such data to be provided using those properties, rather than using the generic property/value mechanism. - - Domain: Product - Domain: Place - Domain: QualitativeValue - Domain: QuantitativeValue - Range: PropertyValue -
-
- unitText - A string or text indicating the unit of measurement. Useful if you cannot provide a standard unit code for -<a href='unitCode'>unitCode</a>. - Domain: PropertyValue - Domain: QuantitativeValue - Domain: TypeAndQuantityNode - Domain: UnitPriceSpecification - Range: Text -
-
- propertyID - A commonly used identifier for the characteristic represented by the property, e.g. a manufacturer or a standard code for a property. propertyID can be -(1) a prefixed string, mainly meant to be used with standards for product properties; (2) a site-specific, non-prefixed string (e.g. the primary key of the property or the vendor-specific id of the property), or (3) -a URL indicating the type of the property, either pointing to an external vocabulary, or a Web resource that describes the property (e.g. a glossary entry). -Standards bodies should promote a standard prefix for the identifiers of properties from their standards. - Domain: PropertyValue - Range: Text - Range: URL -
- -
-

TV Listing additions

-
- broadcastAffiliateOf - The media network(s) whose content is broadcast on this station. - Domain: BroadcastService - Range: Organization -
-
- broadcastDisplayName - The name displayed in the channel guide. For many US affiliates, it is the network name. - Domain: BroadcastService - Range: Text -
-
- broadcastOfEvent - The event being broadcast such as a sporting event or awards ceremony. - Domain: BroadcastEvent - Range: Event -
-
- broadcastTimezone - The timezone in [ISO 8601 format](http://en.wikipedia.org/wiki/ISO_8601) for which the service bases its broadcasts - Domain: BroadcastService - Range: Text -
-
- isLiveBroadcast - True is the broadcast is of a live event. - Domain: BroadcastEvent - Range: Boolean -
-
- CableOrSatelliteService - A service which provides access to media programming like TV or radio. Access may be via cable or satellite. - Subclass of: Service -
-
- BroadcastChannel - A unique instance of a BroadcastService on a CableOrSatelliteService lineup. - Subclass of: Intangible -
-
- TelevisionChannel - A unique instance of a television BroadcastService on a CableOrSatelliteService lineup. - Subclass of: BroadcastChannel -
-
- RadioChannel - A unique instance of a radio BroadcastService on a CableOrSatelliteService lineup. - Subclass of: BroadcastChannel -
-
- broadcastChannelId - The unique address by which the BroadcastService can be identified in a provider lineup. In US, this is typically a number. - Domain: BroadcastChannel - Range: Text -
-
- inBroadcastLineup - The CableOrSatelliteService offering the channel. - Domain: BroadcastChannel - Range: CableOrSatelliteService -
-
- broadcastServiceTier - The type of service required to have access to the channel (e.g. Standard or Premium). - Domain: BroadcastChannel - Range: Text -
-
- providesBroadcastService - The BroadcastService offered on this channel. - Domain: BroadcastChannel - Range: BroadcastService -
-
- - -

Vehicles

- -

See #262 - some terms enter core, others will be an auto: extension.

- -
- EngineSpecification - Information about the engine of the vehicle. A vehicle can have multiple engines represented by multiple engine specification entities. - Subclass of: StructuredValue - Source: GAO -
- -
- numberOfDoors - The number of doors.\n\nTypical unit code(s): C62 - Domain: Vehicle - Range: QuantitativeValue - Range: Number - Source: GAO -
-
- Bridge - A bridge. - Subclass of: CivicStructure -
- -
- numberOfAirbags - The number or type of airbags in the vehicle. - Domain: Vehicle - Range: Number - Range: Text - Source: GAO -
- -
- numberOfAxles - The number of axles.\n\nTypical unit code(s): C62 - Domain: Vehicle - Range: QuantitativeValue - Range: Number - Source: GAO -
- -
- vehicleEngine - Information about the engine or engines of the vehicle. - Domain: Vehicle - Range: EngineSpecification - Source: GAO -
- -
- fuelConsumption - The amount of fuel consumed for traveling a particular distance or temporal duration with the given vehicle (e.g. liters per 100 km).\n\n* Note 1: There are unfortunately no standard unit codes for liters per 100 km. Use [[unitText]] to indicate the unit of measurement, e.g. L/100 km.\n* Note 2: There are two ways of indicating the fuel consumption, [[fuelConsumption]] (e.g. 8 liters per 100 km) and [[fuelEfficiency]] (e.g. 30 miles per gallon). They are reciprocal.\n* Note 3: Often, the absolute value is useful only when related to driving speed ("at 80 km/h") or usage pattern ("city traffic"). You can use [[valueReference]] to link the value for the fuel consumption to another value. - Domain: Vehicle - Range: QuantitativeValue - Source: GAO -
- -
- fuelEfficiency - The distance traveled per unit of fuel used; most commonly miles per gallon (mpg) or kilometers per liter (km/L).\n\n* Note 1: There are unfortunately no standard unit codes for miles per gallon or kilometers per liter. Use [[unitText]] to indicate the unit of measurement, e.g. mpg or km/L.\n* Note 2: There are two ways of indicating the fuel consumption, [[fuelConsumption]] (e.g. 8 liters per 100 km) and [[fuelEfficiency]] (e.g. 30 miles per gallon). They are reciprocal.\n* Note 3: Often, the absolute value is useful only when related to driving speed ("at 80 km/h") or usage pattern ("city traffic"). You can use [[valueReference]] to link the value for the fuel economy to another value. - Domain: Vehicle - Range: QuantitativeValue - Source: GAO -
- -
- numberOfForwardGears - The total number of forward gears available for the transmission system of the vehicle.\n\nTypical unit code(s): C62 - Domain: Vehicle - Range: QuantitativeValue - Range: Number - Source: GAO -
- -
- vehicleIdentificationNumber - The Vehicle Identification Number (VIN) is a unique serial number used by the automotive industry to identify individual motor vehicles. - - Domain: Vehicle - Range: Text - Source: GAO -
- -
- cargoVolume - The available volume for cargo or luggage. For automobiles, this is usually the trunk volume.\n\nTypical unit code(s): LTR for liters, FTQ for cubic foot/feet\n\nNote: You can use [[minValue]] and [[maxValue]] to indicate ranges. - Domain: Vehicle - Range: QuantitativeValue - Source: GAO -
- - -
- vehicleConfiguration - A short text indicating the configuration of the vehicle, e.g. '5dr hatchback ST 2.5 MT 225 hp' or 'limited edition'. - Domain: Vehicle - Range: Text - Source: GAO -
- -
- knownVehicleDamages - A textual description of known damages, both repaired and unrepaired. - Domain: Vehicle - Range: Text - Source: GAO -
- -
- dateVehicleFirstRegistered - The date of the first registration of the vehicle with the respective public authorities. - Domain: Vehicle - Range: Date - Source: GAO -
- -
- driveWheelConfiguration - The drive wheel configuration, i.e. which roadwheels will receive torque from the vehicle's engine via the drivetrain. - Domain: Vehicle - Range: DriveWheelConfigurationValue - Range: Text - Source: GAO -
- -
- DriveWheelConfigurationValue - A value indicating which roadwheels will receive torque. - Subclass of: QualitativeValue - Source: GAO -
- - - -
- FourWheelDriveConfiguration - Four-wheel drive is a transmission layout where the engine primarily drives two wheels with a part-time four-wheel drive capability. - Source: GAO -
- -
- AllWheelDriveConfiguration - All-wheel Drive is a transmission layout where the engine drives all four wheels. - Source: GAO -
-
- FrontWheelDriveConfiguration - Front-wheel drive is a transmission layout where the engine drives the front wheels. - Source: GAO -
-
- RearWheelDriveConfiguration - Real-wheel drive is a transmission layout where the engine drives the rear wheels. - Source: GAO -
- - -
- fuelType - The type of fuel suitable for the engine or engines of the vehicle. If the vehicle has only one engine, this property can be attached directly to the vehicle. - Domain: Vehicle - Domain: EngineSpecification - Range: Text - Range: QualitativeValue - Range: URL - Source: GAO -
- -
- vehicleInteriorColor - The color or color combination of the interior of the vehicle. - Domain: Vehicle - Range: Text - Source: GAO -
- -
- vehicleInteriorType - The type or material of the interior of the vehicle (e.g. synthetic fabric, leather, wood, etc.). While most interior types are characterized by the material used, an interior type can also be based on vehicle usage or target audience. - Domain: Vehicle - Range: Text - Source: GAO -
- -
- mileageFromOdometer - The total distance travelled by the particular vehicle since its initial production, as read from its odometer.\n\nTypical unit code(s): KMT for kilometers, SMI for statute miles - Domain: Vehicle - Range: QuantitativeValue - Source: GAO -
- -
- vehicleModelDate - The release date of a vehicle model (often used to differentiate versions of the same make and model). - Domain: Vehicle - Range: Date - Source: GAO -
- -
- numberOfPreviousOwners - The number of owners of the vehicle, including the current one.\n\nTypical unit code(s): C62 - Domain: Vehicle - Range: QuantitativeValue - Range: Number - Source: GAO -
- -
- productionDate - The date of production of the item, e.g. vehicle. - Domain: Vehicle - Domain: Product - Range: Date - Source: GAO -
- -
- purchaseDate - The date the item e.g. vehicle was purchased by the current owner. - Domain: Vehicle - Domain: Product - Range: Date - Source: GAO -
- -
- vehicleSeatingCapacity - The number of passengers that can be seated in the vehicle, both in terms of the physical space available, and in terms of limitations set by law.\n\nTypical unit code(s): C62 for persons. - Domain: Vehicle - Range: QuantitativeValue - Range: Number - Source: GAO -
- -
- vehicleTransmission - The type of component used for transmitting the power from a rotating power source to the wheels or other relevant component(s) ("gearbox" for cars). - Domain: Vehicle - Range: Text - Range: QualitativeValue - Range: URL - Source: GAO -
- -
- steeringPosition - The position of the steering wheel or similar device (mostly for cars). - Domain: Vehicle - Range: SteeringPositionValue - Source: GAO -
- -
- SteeringPositionValue - A value indicating a steering position. - Subclass of: QualitativeValue - Source: GAO -
- -
- RightHandDriving - The steering position is on the right side of the vehicle (viewed from the main direction of driving). - Source: GAO -
- -
- LeftHandDriving - The steering position is on the left side of the vehicle (viewed from the main direction of driving). - Source: GAO -
- -
- vehicleSpecialUsage - Indicates whether the vehicle has been used for special purposes, like commercial rental, driving school, or as a taxi. The legislation in many countries requires this information to be revealed when offering a car for sale. - Domain: Vehicle - Range: Text -
- -

InteractionCounter

- -
- InteractionCounter - A summary of how users have interacted with this CreativeWork. In most cases, authors will use a subtype to specify the specific type of interaction. - Subclass of: StructuredValue -
- -
- interactionService - The WebSite or SoftwareApplication where the interactions took place. - Domain: InteractionCount - Range: SoftwareApplication - Range: WebSite -
-
- interactionStatistic - The number of interactions for the CreativeWork using the WebSite or SoftwareApplication. The most specific child type of InteractionCounter should be used. - Domain: CreativeWork - Range: InteractionCounter -
-
- interactionType - The Action representing the type of interaction. For up votes, +1s, etc. use [[LikeAction]]. For down votes use [[DislikeAction]]. Otherwise, use the most specific Action. - Domain: InteractionCounter - Range: Action -
-
- userInteractionCount - The number of interactions for the CreativeWork using the WebSite or SoftwareApplication. - Domain: InteractionCount - Range: Integer -
- -

Social Media

- -
- SocialMediaPosting - A post to a social media platform, including blog posts, tweets, Facebook posts, etc. - Subclass of: Article -
-
- sharedContent - A CreativeWork such as an image, video, or audio clip shared as part of this posting. - Domain: SocialMediaPosting - Range: CreativeWork -
- -
- DiscussionForumPosting - A posting to a discussion forum. - Subclass of: SocialMediaPosting -
- -
- LiveBlogPosting - A blog post intended to provide a rolling textual coverage of an ongoing event through continuous updates. - Subclass of: BlogPosting -
- -
- coverageStartTime - The time when the live blog will begin covering the Event. Note that coverage may begin before the Event's start time. The LiveBlogPosting may also be created before coverage begins. - Domain: LiveBlogPosting - Range: DateTime -
- -
- coverageEndTime - The time when the live blog will stop covering the Event. Note that coverage may continue after the Event concludes. - Domain: LiveBlogPosting - Range: DateTime -
- -
- liveBlogUpdate - An update to the LiveBlog. - Domain: LiveBlogPosting - Range: BlogPosting -
- -
- PaymentStatusType - A specific payment status. For example, PaymentDue, PaymentComplete, etc. - Subclass of: Enumeration - -
- -
- PaymentAutomaticallyApplied - An automatic payment system is in place and will be used. -
- -
- PaymentComplete - The payment has been received and processed. -
- -
- PaymentDeclined - The payee received the payment, but it was declined for some reason. -
- -
- PaymentDue - The payment is due, but still within an acceptable time to be received. -
- -
- PaymentPastDue - The payment is due and considered late. -
- -
- Report - A Report generated by governmental or non-governmental organization. - Subclass of: Article -
-
- reportNumber - The number or other unique designator assigned to a Report by the publishing organization. - Domain: Report - Range: Text -
- -
- lyrics - The words in the song. - Domain: MusicComposition - Range: CreativeWork - -
- -
- - - -
- calories - The number of calories. - Domain: NutritionInformation - Range: Energy -
- -
- carbohydrateContent - The number of grams of carbohydrates. - Domain: NutritionInformation - Range: Mass -
- -
- cholesterolContent - The number of milligrams of cholesterol. - Domain: NutritionInformation - Range: Mass -
- -
- fiberContent - The number of grams of fiber. - Domain: NutritionInformation - Range: Mass -
- -
- proteinContent - The number of grams of protein. - Domain: NutritionInformation - Range: Mass -
- -
- saturatedFatContent - The number of grams of saturated fat. - Domain: NutritionInformation - Range: Mass -
- -
- servingSize - The serving size, in terms of the number of volume or mass. - Domain: NutritionInformation - Range: Text -
- -
- sodiumContent - The number of milligrams of sodium. - Domain: NutritionInformation - Range: Mass -
- -
- sugarContent - The number of grams of sugar. - Domain: NutritionInformation - Range: Mass -
- -
- Enumeration - Lists or enumerations—for example, a list of cuisines or music genres, etc. - Subclass of: Intangible -
- -
- NutritionInformation - Nutritional information about the recipe. - Subclass of: StructuredValue -
- -
- Recipe - A recipe. For dietary restrictions covered by the recipe, a few common restrictions are enumerated via [[suitableForDiet]]. The [[keywords]] property can also be used to add more detail. - Subclass of: HowTo -
- -
- cookTime - The time it takes to actually cook the dish, in [ISO 8601 duration format](http://en.wikipedia.org/wiki/ISO_8601). - Subproperty of: performTime - Domain: Recipe - Range: Duration -
- -
- cookingMethod - The method of cooking, such as Frying, Steaming, ... - Domain: Recipe - Range: Text -
- - -
- fatContent - The number of grams of fat. - Domain: NutritionInformation - Range: Mass -
- -
- foodEstablishment - A sub property of location. The specific food establishment where the action occurred. - Domain: CookAction - Range: FoodEstablishment - Range: Place - SubProperty of: location -
- -
- foodEvent - A sub property of location. The specific food event where the action occurred. - Domain: CookAction - Range: FoodEvent - SubProperty of: location -
- -
- nutrition - Nutrition information about the recipe or menu item. - Domain: MenuItem - Domain: Recipe - Range: NutritionInformation -
- -
- recipeCategory - The category of the recipe—for example, appetizer, entree, etc. - Domain: Recipe - Range: Text -
- -
- recipeCuisine - The cuisine of the recipe (for example, French or Ethiopian). - Domain: Recipe - Range: Text -
- -
- ingredients - A single ingredient used in the recipe, e.g. sugar, flour or garlic. - Subproperty of: supply - Domain: Recipe - Range: Text - -
- -
- recipeIngredient - A single ingredient used in the recipe, e.g. sugar, flour or garlic. - Subproperty of: supply - Domain: Recipe - Range: Text -
- -
- recipeInstructions - A step in making the recipe, in the form of a single item (document, video, etc.) or an ordered list with HowToStep and/or HowToSection items. - Subproperty of: steps - Domain: Recipe - Range: CreativeWork - Range: ItemList - Range: Text -
- -
- recipeYield - The quantity produced by the recipe (for example, number of people served, number of servings, etc). - Subproperty of: yield - Domain: Recipe - Range: Text - Range: QuantitativeValue -
- -
- recipe - A sub property of instrument. The recipe/instructions used to perform the action. - Domain: CookAction - Range: Recipe - SubProperty of: instrument -
- - -
- transFatContent - The number of grams of trans fat. - Domain: NutritionInformation - Range: Mass -
- -
- unsaturatedFatContent - The number of grams of unsaturated fat. - Domain: NutritionInformation - Range: Mass -
- -

DataFeed

- -
- DataFeed - A single feed providing structured information about one or more entities or topics. - Subclass of: Dataset -
-
- dataFeedElement - An item within in a data feed. Data feeds may have many elements. - Domain: DataFeed - Range: Text - Range: Thing - Range: DataFeedItem -
-
- DataFeedItem - A single item within a larger data feed. - Subclass of: Intangible -
- -

Day of Week

- -
- PublicHolidays - This stands for any day that is a public holiday; it is a placeholder for all official public holidays in some particular location. While not technically a "day of the week", it can be used with [[OpeningHoursSpecification]]. In the context of an opening hours specification it can be used to indicate opening hours on public holidays, overriding general opening hours for the day of the week on which a public holiday occurs. - Source: GoodRelationsClass -
- -
- Monday - The day of the week between Sunday and Tuesday. - Same as: Monday -
-
- Tuesday - The day of the week between Monday and Wednesday. - Same as: Tuesday -
-
- Wednesday - The day of the week between Tuesday and Thursday. - Same as: Wednesday -
-
- Thursday - The day of the week between Wednesday and Friday. - Same as: Thursday -
-
- Friday - The day of the week between Thursday and Saturday. - Same as: Friday -
-
- Saturday - The day of the week between Friday and Sunday. - Same as: Saturday -
-
- Sunday - The day of the week between Saturday and Monday. - Same as: Sunday -
- - -
- CompoundPriceSpecification - A compound price specification is one that bundles multiple prices that all apply in combination for different dimensions of consumption. Use the name property of the attached unit price specification for indicating the dimension of a price component (e.g. "electricity" or "final cleaning"). - Subclass of: PriceSpecification - Source: GoodRelationsClass -
- -
- referenceQuantity - The reference quantity for which a certain price applies, e.g. 1 EUR per 4 kWh of electricity. This property is a replacement for unitOfMeasurement for the advanced cases where the price does not relate to a standard unit. - Domain: UnitPriceSpecification - Range: QuantitativeValue - Source: GoodRelationsProperty -
- Source: Tourism - Source: IIT-CNR.it - -
- Tourism - This element is based on the work of the [Tourism Structured Web Data Community Group](https://www.w3.org/community/tourismdata). -
-
- IITCNRit - This element is based on work by the Web Applications for the Future Internet Lab, Institute of Informatics and Telematics, Pisa, Italy. -
- - -

FIBO - Finance inspired

- -
- FIBO - This element is based on the work of the Financial Industry Business Ontology project (see [http://www.fibo.org/schema](http://www.fibo.org/schema) for details), in support of the W3C Financial Industry Business Ontology Community Group ([http://www.fibo.org/community](http://www.fibo.org/community)). Many class and property definitions are inspired by or based on [http://www.fibo.org](http://www.fibo.org). -
- -
- GLEIF - The implementation and use of Legal Entity Identifier (LEI) is supported by Global Legal Entity Identifier Foundation [https://www.gleif.org](https://www.gleif.org). -
- -
- MonetaryAmount - A monetary value or range. This type can be used to describe an amount of money such as $50 USD, or a range as in describing a bank account being suitable for a balance between £1,000 and £1,000,000 GBP, or the value of a salary, etc. It is recommended to use [[PriceSpecification]] Types to describe the price of an Offer, Invoice, etc. - Subclass of: StructuredValue - Source: FIBO -
- -
- leiCode - An organization identifier that uniquely identifies a legal entity as defined in ISO 17442. - Domain: Organization - Range: Text - Source: FIBO - Source: GLEIF -
- - -
- FinancialProduct - A product provided to consumers and businesses by financial institutions such as banks, insurance companies, brokerage firms, consumer finance companies, and investment companies which comprise the financial services industry. - Subclass of: Service - Source: FIBO -
- -
- annualPercentageRate - The annual rate that is charged for borrowing (or made by investing), expressed as a single percentage number that represents the actual yearly cost of funds over the term of a loan. This includes any fees or additional costs associated with the transaction. - Domain: FinancialProduct - Range: QuantitativeValue - Range: Number - Source: FIBO -
- -
- feesAndCommissionsSpecification - Description of fees, commissions, and other terms applied either to a class of financial product, or by a financial service organization. - Domain: FinancialProduct - Domain: FinancialService - Range: Text - Range: URL - Source: FIBO -
- -
- interestRate - The interest rate, charged or paid, applicable to the financial product. Note: This is different from the calculated annualPercentageRate. - Domain: FinancialProduct - Range: QuantitativeValue - Range: Number - Source: FIBO -
- -
- BankAccount - A product or service offered by a bank whereby one may deposit, withdraw or transfer money and in some cases be paid interest. - Subclass of: FinancialProduct - Source: FIBO -
- -
- DepositAccount - A type of Bank Account with a main purpose of depositing funds to gain interest or other benefits. - Subclass of: BankAccount - Subclass of: InvestmentOrDeposit - Source: FIBO -
- -
- LoanOrCredit - A financial product for the loaning of an amount of money under agreed terms and charges. - Subclass of: FinancialProduct - Source: FIBO -
- -
- loanTerm - The duration of the loan or credit agreement. - Subproperty of: duration - Domain: LoanOrCredit - Range: QuantitativeValue - Source: FIBO -
- -
- requiredCollateral - Assets required to secure loan or credit repayments. It may take form of third party pledge, goods, financial instruments (cash, securities, etc.) - Domain: LoanOrCredit - Range: Thing - Range: Text - Source: FIBO -
- -
- PaymentCard - A payment method using a credit, debit, store or other card to associate the payment with an account. - Subclass of: FinancialProduct - Subclass of: PaymentMethod - Source: FIBO -
- -
- InvestmentOrDeposit - A type of financial product that typically requires the client to transfer funds to a financial service in return for potential beneficial financial return. - Subclass of: FinancialProduct - Source: FIBO -
- -
- PaymentService - A Service to transfer funds from a person or organization to a beneficiary person or organization. - Subclass of: FinancialProduct - Source: FIBO -
- -
- CurrencyConversionService - A service to convert funds from one currency to another currency. - Subclass of: FinancialProduct - Source: FIBO -
- -

Conversation

- -
- Conversation - One or more messages between organizations or people on a particular topic. Individual messages can be linked to the conversation with isPartOf or hasPart properties. - Subclass of: CreativeWork -
-
- Message - A single message from a sender to one or more organizations or people. - Subclass of: CreativeWork -
-
- dateRead - The date/time at which the message has been read by the recipient if a single recipient exists. - Domain: Message - Range: DateTime -
-
- dateReceived - The date/time the message was received if a single recipient exists. - Domain: Message - Range: DateTime -
-
- dateSent - The date/time at which the message was sent. - Domain: Message - Range: DateTime -
-
- messageAttachment - A CreativeWork attached to the message. - Domain: Message - Range: CreativeWork -
- - -
- CompoundPriceSpecification - A compound price specification is one that bundles multiple prices that all apply in combination for different dimensions of consumption. Use the name property of the attached unit price specification for indicating the dimension of a price component (e.g. "electricity" or "final cleaning"). - Subclass of: PriceSpecification - Source: GoodRelationsClass -
- -
- priceComponent - This property links to all [[UnitPriceSpecification]] nodes that apply in parallel for the [[CompoundPriceSpecification]] node. - Domain: CompoundPriceSpecification - Range: UnitPriceSpecification - Source: GoodRelationsProperty -
- -
- referenceQuantity - The reference quantity for which a certain price applies, e.g. 1 EUR per 4 kWh of electricity. This property is a replacement for unitOfMeasurement for the advanced cases where the price does not relate to a standard unit. - Domain: UnitPriceSpecification - Range: QuantitativeValue - Source: GoodRelationsProperty -
- -

DigitalDocument

- -
- DigitalDocument - An electronic file or document. - Subclass of: CreativeWork -
-
- PresentationDigitalDocument - A file containing slides or used for a presentation. - Subclass of: DigitalDocument -
-
- SpreadsheetDigitalDocument - A spreadsheet file. - Subclass of: DigitalDocument -
-
- TextDigitalDocument - A file composed primarily of text. - Subclass of: DigitalDocument -
-
- NoteDigitalDocument - A file containing a note, primarily for the author. - Subclass of: DigitalDocument -
-
- DigitalDocumentPermission - A permission for a particular person or group to access a particular file. - Subclass of: Intangible -
-
- DigitalDocumentPermissionType - A type of permission which can be granted for accessing a digital document. - Subclass of: Enumeration -
-
- CommentPermission - Permission to add comments to the document. -
-
- ReadPermission - Permission to read or view the document. -
-
- WritePermission - Permission to write or edit the document. -
-
- hasDigitalDocumentPermission - A permission related to the access to this document (e.g. permission to read or write an electronic document). For a public document, specify a grantee with an Audience with audienceType equal to "public". - Domain: DigitalDocument - Range: DigitalDocumentPermission -
-
- grantee - The person, organization, contact point, or audience that has been granted this permission. - Domain: DigitalDocumentPermission - Range: Person - Range: Organization - Range: Audience - Range: ContactPoint -
-
- permissionType - The type of permission granted the person, organization, or audience. - Domain: DigitalDocumentPermission - Range: DocumentPermissionType -
- -

Hotels

- - -
- STI Accommodation Ontology - This element is based on the STI Accommodation Ontology, see <a href="http://ontologies.sti-innsbruck.at/acco/ns.html">http://ontologies.sti-innsbruck.at/acco/ns.html</a> for details. - Many class and property definitions are inspired by or based on abstracts from Wikipedia, the free encyclopedia. -
- - - - -
- Resort - A resort is a place used for relaxation or recreation, attracting visitors for holidays or vacations. Resorts are places, towns or sometimes commercial establishment operated by a single company (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/Resort">http://en.wikipedia.org/wiki/Resort</a>). -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: LodgingBusiness - Source: STI Accommodation Ontology -
- - -
- Accommodation - An accommodation is a place that can accommodate human beings, e.g. a hotel room, a camping pitch, or a meeting room. Many accommodations are for overnight stays, but this is not a mandatory requirement. -For more specific types of accommodations not defined in schema.org, one can use additionalType with external vocabularies. -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: Place - Source: STI Accommodation Ontology -
- -
- Room - A room is a distinguishable space within a structure, usually separated from other spaces by interior walls. (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/Room">http://en.wikipedia.org/wiki/Room</a>). -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: Accommodation - Source: STI Accommodation Ontology -
- -
- HotelRoom - A hotel room is a single room in a hotel. -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: Room - Source: STI Accommodation Ontology -
- -
- MeetingRoom - A meeting room, conference room, or conference hall is a room provided for singular events such as business conferences and meetings (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/Conference_hall">http://en.wikipedia.org/wiki/Conference_hall</a>). -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: Room - Source: STI Accommodation Ontology -
- -
- CampingPitch - A camping pitch is an individual place for overnight stay in the outdoors, typically being part of a larger camping site. -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: Accommodation - Source: STI Accommodation Ontology -
- -
- Suite - A suite in a hotel or other public accommodation, denotes a class of luxury accommodations, the key feature of which is multiple rooms (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/Suite_(hotel)">http://en.wikipedia.org/wiki/Suite_(hotel)</a>). -<br /><br /> -See also the <a href="/docs/hotels.html">dedicated document on the use of schema.org for marking up hotels and other forms of accommodations</a>. - - Subclass of: Accommodation - Source: STI Accommodation Ontology -
- -
- House - A house is a building or structure that has the ability to be occupied for habitation by humans or other creatures (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/House">http://en.wikipedia.org/wiki/House</a>). - Subclass of: Accommodation - Source: STI Accommodation Ontology -
- -
- Apartment - An apartment (in American English) or flat (in British English) is a self-contained housing unit (a type of residential real estate) that occupies only part of a building (Source: Wikipedia, the free encyclopedia, see <a href="http://en.wikipedia.org/wiki/Apartment">http://en.wikipedia.org/wiki/Apartment</a>). - Subclass of: Accommodation - Source: STI Accommodation Ontology -
- - - -
- FoodService - A food service, like breakfast, lunch, or dinner. - Subclass of: Service - Source: STI Accommodation Ontology -
- -
- LocationFeatureSpecification - Specifies a location feature by providing a structured value representing a feature of an accommodation as a property-value pair of varying degrees of formality. - Subclass of: PropertyValue - Source: STI Accommodation Ontology -
- -
- BedDetails - An entity holding detailed information about the available bed types, e.g. the quantity of twin beds for a hotel room. For the single case of just one bed of a certain type, you can use bed directly with a text. See also [[BedType]] (under development). - Subclass of: Intangible - Source: STI Accommodation Ontology -
- - -
- amenityFeature - An amenity feature (e.g. a characteristic or service) of the Accommodation. This generic property does not make a statement about whether the feature is included in an offer for the main accommodation or available at extra costs. - Domain: Accommodation - Domain: LodgingBusiness - Domain: Place - Range: LocationFeatureSpecification - Source: STI Accommodation Ontology -
- -
- typeOfBed - The type of bed to which the BedDetail refers, i.e. the type of bed available in the quantity indicated by quantity. - Domain: BedDetails - Range: Text - Source: STI Accommodation Ontology -
- -
- bed - The type of bed or beds included in the accommodation. For the single case of just one bed of a certain type, you use bed directly with a text. - If you want to indicate the quantity of a certain kind of bed, use an instance of BedDetails. For more detailed information, use the amenityFeature property. - Domain: HotelRoom - Domain: Suite - Range: Text - Range: BedDetails - Source: STI Accommodation Ontology -
- -
- numberOfRooms - The number of rooms (excluding bathrooms and closets) of the acccommodation or lodging business. -Typical unit code(s): ROM for room or C62 for no unit. The type of room can be put in the unitText property of the QuantitativeValue. - Domain: House - Domain: Accommodation - Domain: Apartment - Domain: Suite - Domain: SingleFamilyResidence - Range: Number - Range: QuantitativeValue - Source: STI Accommodation Ontology -
- -
- floorSize - The size of the accommodation, e.g. in square meter or squarefoot. -Typical unit code(s): MTK for square meter, FTK for square foot, or YDK for square yard - Domain: Accommodation - Range: QuantitativeValue - Source: STI Accommodation Ontology -
- -
- occupancy - The allowed total occupancy for the accommodation in persons (including infants etc). For individual accommodations, this is not necessarily the legal maximum but defines the permitted usage as per the contractual agreement (e.g. a double room used by a single person). -Typical unit code(s): C62 for person - Domain: HotelRoom - Domain: Apartment - Domain: Suite - Domain: SingleFamilyResidence - Range: QuantitativeValue - Source: STI Accommodation Ontology -
- -
- permittedUsage - Indications regarding the permitted usage of the accommodation. - Domain: Accommodation - Range: Text - Source: STI Accommodation Ontology -
- - - -
- petsAllowed - Indicates whether pets are allowed to enter the accommodation or lodging business. More detailed information can be put in a text value. - Domain: Accommodation - Domain: LodgingBusiness - Range: Boolean - Range: Text - Source: STI Accommodation Ontology -
- -
- smokingAllowed - Indicates whether it is allowed to smoke in the place, e.g. in the restaurant, hotel or hotel room. - Domain: Place - Range: Boolean - Source: STI Accommodation Ontology -
- -
- numberOfBeds - The quantity of the given bed type available in the HotelRoom, Suite, House, or Apartment. - Domain: BedDetails - Range: Number - Source: STI Accommodation Ontology -
- -
- starRating - An official rating for a lodging business or food establishment, e.g. from national associations or standards bodies. Use the author property to indicate the rating organization, e.g. as an Organization with name such as (e.g. HOTREC, DEHOGA, WHR, or Hotelstars). - Domain: LodgingBusiness - Domain: FoodEstablishment - Range: Rating - Source: STI Accommodation Ontology -
- -

HowTo

- -
- HowTo - Instructions that explain how to achieve a result by performing a sequence of steps. - Subclass of: CreativeWork -
- -
- estimatedCost - The estimated cost of the supply or supplies consumed when performing instructions. - Domain: HowTo - Domain: HowToSupply - Range: Text - Range: MonetaryAmount -
- -
- performTime - The length of time it takes to perform instructions or a direction (not including time to prepare the supplies), in [ISO 8601 duration format](http://en.wikipedia.org/wiki/ISO_8601). - Domain: HowTo - Domain: HowToDirection - Range: Duration -
- -
- prepTime - The length of time it takes to prepare the items to be used in instructions or a direction, in [ISO 8601 duration format](http://en.wikipedia.org/wiki/ISO_8601). - Domain: HowTo - Domain: HowToDirection - Range: Duration -
- -
- supply - A sub-property of instrument. A supply consumed when performing instructions or a direction. - Subproperty of: instrument - Domain: HowTo - Domain: HowToDirection - Range: Text - Range: HowToSupply -
- -
- steps - The steps in the form of a single item (text, document, video, etc.) or an ordered list with HowToStep and/or HowToSection items. - Domain: HowTo - Domain: HowToSection - Range: CreativeWork - Range: ItemList - Range: Text -
- -
- tool - A sub property of instrument. An object used (but not consumed) when performing instructions or a direction. - Subproperty of: instrument - Domain: HowTo - Domain: HowToDirection - Range: Text - Range: HowToTool -
- -
- totalTime - The total time required to perform instructions or a direction (including time to prepare the supplies), in [ISO 8601 duration format](http://en.wikipedia.org/wiki/ISO_8601). - Domain: HowTo - Domain: HowToDirection - Range: Duration -
- -
- yield - The quantity that results by performing instructions. For example, a paper airplane, 10 personalized candles. - Domain: HowTo - Range: Text - Range: QuantitativeValue -
- -

HowToDirection

- -
- HowToDirection - A direction indicating a single action to do in the instructions for how to achieve a result. - Subclass of: ListItem -
- -
- afterMedia - A media object representing the circumstances after performing this direction. - Domain: HowToDirection - Range: MediaObject -
- -
- beforeMedia - A media object representing the circumstances before performing this direction. - Domain: HowToDirection - Range: MediaObject -
- -
- duringMedia - A media object representing the circumstances while performing this direction. - Domain: HowToDirection - Range: MediaObject -
- -

HowToItem

- -
- HowToItem - An item used as either a tool or supply when performing the instructions for how to to achieve a result. - Subclass of: ListItem -
- -
- requiredQuantity - The required quantity of the item(s). - Domain: HowToItem - Range: Text - Range: Number - Range: QuantitativeValue -
- -

HowToSupply

- -
- HowToSupply - A supply consumed when performing the instructions for how to achieve a result. - Subclass of: HowToItem -
- -

HowToSection

- -
- HowToSection - A sub-grouping of steps in the instructions for how to achieve a result (e.g. steps for making a pie crust within a pie recipe). - Subclass of: ItemList -
- -

HowToStep

- -
- HowToStep - A step in the instructions for how to achieve a result. It is an ordered list with HowToDirection and/or HowToTip items. - Subclass of: ItemList -
- -

HowToTip

- -
- HowToTip - An explanation in the instructions for how to achieve a result. It provides supplementary information about a technique, supply, author's preference, etc. It can explain what could be done, or what should not be done, but doesn't specify what should be done (see HowToDirection). - Subclass of: ListItem -
- -

HowToTool

- -
- HowToTool - A tool used (but not consumed) when performing instructions for how to achieve a result. - Subclass of: HowToItem -
- - -

Courses

- -

Moved into core from pending (issue-195.rdfa), 2016-09-07.

- - - - - - -
- - Course - A description of an educational course which may be offered as distinct instances at which take place at different times or take place at different locations, or be offered through different media or modes of study. An educational course is a sequence of one or more educational events and/or creative works which aims to build knowledge, competence or ability of learners. - Subclass of: CreativeWork - -
- -
- - courseCode - The identifier for the [[Course]] used by the course [[provider]] (e.g. CS101 or 6.001). - Domain: Course - Range: Text - -
- -
- - coursePrerequisites - Requirements for taking the Course. May be completion of another [[Course]] or a textual description like "permission of instructor". Requirements may be a pre-requisite competency, referenced using [[AlignmentObject]]. - Domain: Course - Range: Text - Range: Course - Range: AlignmentObject - -
- -
- - hasCourseInstance - An offering of the course at a specific time and place or through specific media or mode of study or to a specific section of students. - Domain: Course - Range: CourseInstance - -
- - - - - - -
- - CourseInstance - An instance of a [[Course]] which is distinct from other instances because it is offered at a different time or location or through different media or modes of study or to a specific section of students. - Subclass of: Event - -
- -
- - courseMode - The medium or means of delivery of the course instance or the mode of study, either as a text label (e.g. "online", "onsite" or "blended"; "synchronous" or "asynchronous"; "full-time" or "part-time") or as a URL reference to a term from a controlled vocabulary (e.g. https://ceds.ed.gov/element/001311#Asynchronous ). - Domain: CourseInstance - Range: Text - Range: URL - -
- -
- - instructor - A person assigned to instruct or provide instructional assistance for the [[CourseInstance]]. - Domain: CourseInstance - Range: Person - -
- -

Identifier

- -
- -
- identifier - The identifier property represents any kind of identifier for any kind of [[Thing]], such as ISBNs, GTIN codes, UUIDs etc. Schema.org provides dedicated properties for representing many of these, either as textual strings or as URL (URI) links. See [background notes](/docs/datamodel.html#identifierBg) for more details. - - - Domain: Thing - Range: URL - Range: Text - Range: PropertyValue - -
- - -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- -
- - -
- -
- - -
- -
- - -
- -
- -
- -
- - -
- -
- -
- -
- - -
- -
- -
- - - - - - -

ClaimReview

- -
- - -
- Category: issue-1061 - ClaimReview - A fact-checking review of claims made (or reported) in some creative work (referenced via itemReviewed). - Subclass of: Review - Source: #1061 -
- -
- Category: issue-1061 - claimReviewed - A short summary of the specific claims reviewed in a ClaimReview. - Domain: ClaimReview - Range: Text - Source: #1061 -
- -
- - - -

Menu

- -

Adding menu markup schema (issue-1288 .rdfa), 2016-10-26.

- - - -
- -
- Menu - A structured representation of food or drink items available from a FoodEstablishment. - Subclass of: CreativeWork -
- -
- MenuItem - A food or drink item listed in a menu or menu section. - Subclass of: CreativeWork -
- -
- MenuSection - A sub-grouping of food or drink items in a menu. E.g. courses (such as 'Dinner', 'Breakfast', etc.), specific type of dishes (such as 'Meat', 'Vegan', 'Drinks', etc.), or some other classification made by the menu provider. - Subclass of: CreativeWork -
- -
- hasMenuItem - A food or drink item contained in a menu or menu section. - Domain: Menu - Domain: MenuSection - Range: MenuSection -
- -
- hasMenuSection - A subgrouping of the menu (by dishes, course, serving time period, etc.). - Domain: Menu - Domain: MenuSection - Range: MenuSection -
- - - -

Digital Publishing Accessibility

- -

"Proposal of accessMode, accessModeSufficient, and accessibilitySummary properties for e.g. epubs"

- -
- Category: issue-1110 - accessMode - The human sensory perceptual system or cognitive faculty through which a person may process or perceive information. Expected values include: auditory, tactile, textual, visual, colorDependent, chartOnVisual, chemOnVisual, diagramOnVisual, mathOnVisual, musicOnVisual, textOnVisual. - - domainIncludes: CreativeWork - rangeIncludes: Text - Source: #1100 -
- -
- Category: issue-1110 - accessModeSufficient - A list of single or combined accessModes that are sufficient to understand all the intellectual content of a resource. Expected values include: auditory, tactile, textual, visual. - - domainIncludes: CreativeWork - rangeIncludes: Text - Source: #1100 -
- -
- Category: issue-1110 - accessibilitySummary - A human-readable summary of specific accessibility features or deficiencies, consistent with the other accessibility metadata but expressing subtleties such as "short descriptions are present but long descriptions will be needed for non-visual users" or "short descriptions are present and no long descriptions are needed." - domainIncludes: CreativeWork - rangeIncludes: Text - Source: #1100 -
- - - - -
- - - - - diff --git a/tests/data/vgo.rdf b/tests/data/vgo.rdf index 100c409a..648c3c73 100644 --- a/tests/data/vgo.rdf +++ b/tests/data/vgo.rdf @@ -2,7 +2,7 @@ + @@ -30,7 +30,7 @@ xmlns:vann="http://purl.org/vocab/vann/" xmlns:net="http://purl.org/net/" xmlns:ontology="http://dbpedia.org/ontology/" - xmlns:schema="http://schema.org/" + xmlns:schema="https://schema.org/" xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#" xmlns:owl2xml="http://www.w3.org/2006/12/owl2-xml#" xmlns:xsd="http://www.w3.org/2001/XMLSchema#" @@ -52,10 +52,10 @@ The Video Game Ontology The Video Game Ontology is an ontology designed for describing video games and all the resources related to their game plays. - - - - - + @@ -96,7 +96,7 @@ - + @@ -108,7 +108,7 @@ - + @@ -120,7 +120,7 @@ - + @@ -131,7 +131,7 @@ - + @@ -142,7 +142,7 @@ - + @@ -154,7 +154,7 @@ - + @@ -166,7 +166,7 @@ - + @@ -177,7 +177,7 @@ - + @@ -189,7 +189,7 @@ - + @@ -201,7 +201,7 @@ - + @@ -213,7 +213,7 @@ - + @@ -225,7 +225,7 @@ - + @@ -237,7 +237,7 @@ - + @@ -249,7 +249,7 @@ - + @@ -261,7 +261,7 @@ - + @@ -272,7 +272,7 @@ - + @@ -283,7 +283,7 @@ - + @@ -294,7 +294,7 @@ - + @@ -305,7 +305,7 @@ - + @@ -316,7 +316,7 @@ - + @@ -329,7 +329,7 @@ - + @@ -341,7 +341,7 @@ - + @@ -353,7 +353,7 @@ - + @@ -365,7 +365,7 @@ - + @@ -376,7 +376,7 @@ - + @@ -387,7 +387,7 @@ - + @@ -398,7 +398,7 @@ - + @@ -409,7 +409,7 @@ - + @@ -420,7 +420,7 @@ - + @@ -431,7 +431,7 @@ - + @@ -442,7 +442,7 @@ - + @@ -453,16 +453,16 @@ - + - - - + @@ -481,7 +481,7 @@ - + @@ -492,7 +492,7 @@ - + @@ -503,7 +503,7 @@ - + @@ -514,7 +514,7 @@ - + @@ -525,7 +525,7 @@ - + @@ -536,10 +536,10 @@ - - - + - + - + Achievement - The vgo:Achievement is a reward gained in a game due to some event accomplished in the game. Achievements are commonly used in game industry to reward players for having accomplished tasks in the game. + The vgo:Achievement is a reward gained in a game due to some event accomplished in the game. Achievements are commonly used in game industry to reward players for having accomplished tasks in the game. This ontology defines various subclasses of vgo:Achievement, which are all based on the classification presented by Markus Montola et al. [Markus Montola, Timo Nummenmaa, Andrés Lucero, Marion Boberg, and Hannu Korhonen, 2009, “Applying game achievement systems to enhance user experience in a photo sharing service”, In Proceedings of the 13th International MindTrek Conference: Everyday Life in the Ubiquitous Era (MindTrek '09)] http://dl.acm.org/citation.cfm?id=1621859 - + @@ -578,7 +578,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based Character A vgo:Character is any actor that can exists in a game. A character can be a human-like creature as seen traditionally in video games. However, a character could also be a car, a paddle in game of Pong or spaceship of a space shooter game. This is often contextually related to the gameplay of a certain game. A character can be either controller by a player or by a computer. - + @@ -588,7 +588,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based The vgo:Collection type of achievement is typically rewarded from collecting an amount of certain items in a game. An example of vgo:Collection would be obtaining a full set of christmas clothes for a character to wear or collecting every possible flower in the game. - + @@ -598,7 +598,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based The vgo:Completion type of achievement is usually rewarded from successfully completing a certain goal or subgoal in a game. An example of vgo:Completion would be to save a princess from a burning tower or completing all side-quests in a game. - + @@ -608,7 +608,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based The vgo:Curiosity describes funny random things that can happen or be found in the game. An example could be jumping from the Eiffel tower without dying or following a comupter controlled character’s activities for one hour. - + @@ -618,7 +618,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based The vgo:Fandom achievement is related to doing some true fan activities. An example of vgo:Fandom could be purchasing a collectors edition of the game or attending a fan gathering. - + @@ -627,7 +627,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based Feature vgo:Feature describes an ability or characteristic. For example, a sword could have “damage dealing” ability and a bottle of water could be “potable”. - + @@ -637,7 +637,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based The vgo:GainEvent describes an event that is related to character/player gaining something in a game. This is a subclass of vgo:GameEvent as gaining something is related to a specific game. For example, a player can gain a new character, achievement or item. - + @@ -647,7 +647,7 @@ This ontology defines various subclasses of vgo:Achievement, which are all based The vgo:Game class describes a game product that can be played by a player. Examples of games are Pong, Grand Theft Auto, Pokemon and Need for Speed. - + @@ -657,7 +657,7 @@ Examples of games are Pong, Grand Theft Auto, Pokemon and Need for Speed. The vgo:GameEvent describes an event that takes place in a game without straight player interaction. GameEvents are often very specific for each game. Examples of vgo:GameEvent could be an enemy dying, connecting to a multiplayer server, loading a new level or playing an animation. - + @@ -680,7 +680,7 @@ Examples of games are Pong, Grand Theft Auto, Pokemon and Need for Speed.A vgo:GameProduct is anything that is for sale inside a game. These can be either normal game items purchased with in-game currency or with real world money. An example of vgo:GameProduct could be a consumable health potion bought with real money, a better weapon or some visual improvement (e.g. Hats in Steam). Basically a game product can be anything, a character, an item or an achievement. GameProduct is a subclass of Good Relations: ProductOrService & schema:Product. Since vgo:GameProduct is a type of buyable product, it reuses the properties available in the schema and Good Relations, such as currency price, validity of the offer and so on. - + @@ -689,7 +689,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ Genre The vgo:Genre class describes the genre a game belongs to. All of the games have at least one genre. Examples of this are RPG, Simulator and Adventure - + @@ -699,7 +699,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:HardMode achievement describes succeeding in a game on a high difficulty level. An example could be completing the “Doom” game on Nightmare difficulty level. - + @@ -709,7 +709,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:InAppPurchaseEvent describes an event that is related to making a purchase with real money inside a game. This is a subclass of InstantaneousEvent because it happens at certain moment in time. An example of vgo:InAppPurchaseEvent would be unlocking secret levels with real money or purchasing better equipment with real money. - + @@ -718,7 +718,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ instantaneous event The vgo:InstantaneousEvent class describes an event that happens during the gameplay at a certain moment in time. This can be a player gaining an achievement, killing an enemy or making an in-app purchase. - + @@ -727,7 +727,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ Item A vgo:Item portrays any item that exists in a game. The item can either be just visual part of the game or a concrete usable item. As an example an item could be a drinkable potion, a magical sword or just a flower pot. - + @@ -737,7 +737,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Leaderboard class describes a ranking system of the players. There can be multiple rankings in a game, for example, the kill-count ranking of Modern Warfare or the best time listing of Formula 1 game. - + @@ -747,7 +747,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ vgo:LoseEvent describes an event that is related to character/player losing something in a game. This is a subclass of GameEvent as gaining something is related to a specific game. For example, a player can lose a character due to trade with another player. Another example would be a character losing item due to consuming it. - + @@ -757,7 +757,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Loyalty achievement is used to give recognition to loyal players. For example, this could be an achievement received after subscribing to the game for a year. - + @@ -767,7 +767,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Lucky describes an achievement that is awarded to the player in a lucky situation. An example of vgo:Lucky achievement would be winning in a lottery or throwing “Yahtzee” without re-rolling the dice. - + @@ -777,7 +777,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:MenuEvent describes an event that is related to interacting with the ingame menu. An example of menu event is muting sounds, changing graphic settings, changing gameplay difficulty or remapping game controls. - + @@ -787,7 +787,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Minigame achievement describes success in mini-games that have been included in a certain game but are not vital for completing the game. An example could be to complete all the Pizza deliveries in GTA minigame or gaining over 100 dollars while playing poker in Red Dead Redemption. - + @@ -797,7 +797,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Multiplayer achievement describes anything that can be awarded to one or multiple players due to their gameplay in multiplayer. For example, this could be winning 10 Team Fortress matches in a row with the same team or getting killed ten times in a row in Counter-Strike. - + @@ -807,7 +807,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Paragon is a rare achievement that is given only to limited number of players. An example of vgo:Paragon achievement could be the first player to finish a game under 10 hours or the first ten players to complete the game 100% through. - + @@ -817,7 +817,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Player describes the entity playing the game. This can be either a human or a computer. vgo:Player class is used to keep a profile of a certain playing entity and to connect all the games, achievements and characters he/she has. The vgo:Player is a subclass of foaf:Person as it contains all relative information of a certain person. - + @@ -827,7 +827,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:PlayerEvent describes a vgo:InstantaneousEvent that is caused by the player. For example jumping in the game, throwing an item or pressing a joystick button. - + @@ -836,7 +836,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ playing area The vgo:PlayingArea is the description of a place where the gameplay takes place. All of the games have some kind of area where they are played in. An example of playing areas could be football field in soccer game, a race track from a racing game or a star system of EVE Online. - + @@ -846,7 +846,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Session class describes a session of gameplay. A session can be a single round of chess, a round of Counter-Strike, one half-time of soccer or one race of Formula 1. vgo:Session class can be used to store gameplay information, especially for analytical reasons. - + @@ -856,7 +856,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:SpecialPlayStyle achievement is awarded to players after playing a game in special fashion. Often this is something harder than the regular play and requires more player experience to excel in it. An example of vgo:SpecialPlayStyle could be to complete a game without any violence or against a timer. - + @@ -866,7 +866,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Tutorial achievement is awarded to a player for trying out various features of the game. This is often related to learning how to play the game, how the controls work and how the game logic works. An example of vgo:Tutorial could be testing out newly gained special equipment or just playing through the in-game tutorial in the beginning. - + @@ -876,7 +876,7 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Veteran achievement is an award that is given for accumulating a lot of play hours or game actions. For example, vgo:Veteran could be playing thousand hours of World of Tanks or making 100 goals in ice hockey game. - + @@ -886,19 +886,19 @@ GameProduct is a subclass of Good Relations: ProductOrService & schema:Produ The vgo:Virtuosity describes an achievement that is awarded for playing masterfully in the game. Examples of virtuous play could be finishing the game without saving at all, dying zero times or preventing an opposing team from scoring any goals in a soccer game. - - + + - + - + diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 57377b19..759b8328 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -11,7 +11,7 @@ types: familyName: ~ givenName: ~ additionalName: ~ - address: { range: http://schema.org/PostalAddress } + address: { range: https://schema.org/PostalAddress } birthDate: ~ telephone: ~ email: ~ @@ -20,7 +20,7 @@ types: # Disable the generation of the class hierarchy for this type parent: false properties: - addressCountry: { range: http://schema.org/Text } + addressCountry: { range: https://schema.org/Text } addressLocality: ~ addressRegion: ~ postOfficeBoxNumber: ~ diff --git a/tests/e2e/src/App/Entity/Person.php b/tests/e2e/src/App/Entity/Person.php index e21384cf..c48ad787 100644 --- a/tests/e2e/src/App/Entity/Person.php +++ b/tests/e2e/src/App/Entity/Person.php @@ -21,10 +21,10 @@ /** * A person (alive, dead, undead, or fictional). * - * @see http://schema.org/Person + * @see https://schema.org/Person * * @ORM\Entity - * @ApiResource(iri="http://schema.org/Person") + * @ApiResource(iri="https://schema.org/Person") */ class Person { @@ -38,50 +38,50 @@ class Person /** * Family name. In the U.S., the last name of a Person. * - * @see http://schema.org/familyName + * @see https://schema.org/familyName * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/familyName") + * @ApiProperty(iri="https://schema.org/familyName") */ private ?string $familyName = null; /** * Given name. In the U.S., the first name of a Person. * - * @see http://schema.org/givenName + * @see https://schema.org/givenName * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/givenName") + * @ApiProperty(iri="https://schema.org/givenName") */ private ?string $givenName = null; /** * An additional name for a Person, can be used for a middle name. * - * @see http://schema.org/additionalName + * @see https://schema.org/additionalName * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/additionalName") + * @ApiProperty(iri="https://schema.org/additionalName") */ private ?string $additionalName = null; /** * Physical address of the item. * - * @see http://schema.org/address + * @see https://schema.org/address * * @ORM\ManyToOne(targetEntity="App\Entity\PostalAddress") - * @ApiProperty(iri="http://schema.org/address") + * @ApiProperty(iri="https://schema.org/address") */ private ?PostalAddress $address = null; /** * Date of birth. * - * @see http://schema.org/birthDate + * @see https://schema.org/birthDate * * @ORM\Column(type="date", nullable=true) - * @ApiProperty(iri="http://schema.org/birthDate") + * @ApiProperty(iri="https://schema.org/birthDate") * @Assert\Date */ private ?\DateTimeInterface $birthDate = null; @@ -89,20 +89,20 @@ class Person /** * The telephone number. * - * @see http://schema.org/telephone + * @see https://schema.org/telephone * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/telephone") + * @ApiProperty(iri="https://schema.org/telephone") */ private ?string $telephone = null; /** * Email address. * - * @see http://schema.org/email + * @see https://schema.org/email * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/email") + * @ApiProperty(iri="https://schema.org/email") * @Assert\Email */ private ?string $email = null; @@ -110,10 +110,10 @@ class Person /** * URL of the item. * - * @see http://schema.org/url + * @see https://schema.org/url * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/url") + * @ApiProperty(iri="https://schema.org/url") * @Assert\Url */ private ?string $url = null; diff --git a/tests/e2e/src/App/Entity/PostalAddress.php b/tests/e2e/src/App/Entity/PostalAddress.php index f71bc5ff..697feb97 100644 --- a/tests/e2e/src/App/Entity/PostalAddress.php +++ b/tests/e2e/src/App/Entity/PostalAddress.php @@ -20,10 +20,10 @@ /** * The mailing address. * - * @see http://schema.org/PostalAddress + * @see https://schema.org/PostalAddress * * @ORM\Entity - * @ApiResource(iri="http://schema.org/PostalAddress") + * @ApiResource(iri="https://schema.org/PostalAddress") */ class PostalAddress { @@ -37,60 +37,60 @@ class PostalAddress /** * The country. For example, USA. You can also provide the two-letter \[ISO 3166-1 alpha-2 country code\](http://en.wikipedia.org/wiki/ISO\_3166-1). * - * @see http://schema.org/addressCountry + * @see https://schema.org/addressCountry * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/addressCountry") + * @ApiProperty(iri="https://schema.org/addressCountry") */ private ?string $addressCountry = null; /** * The locality in which the street address is, and which is in the region. For example, Mountain View. * - * @see http://schema.org/addressLocality + * @see https://schema.org/addressLocality * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/addressLocality") + * @ApiProperty(iri="https://schema.org/addressLocality") */ private ?string $addressLocality = null; /** * The region in which the locality is, and which is in the country. For example, California or another appropriate first-level \[Administrative division\](https://en.wikipedia.org/wiki/List\_of\_administrative\_divisions\_by\_country). * - * @see http://schema.org/addressRegion + * @see https://schema.org/addressRegion * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/addressRegion") + * @ApiProperty(iri="https://schema.org/addressRegion") */ private ?string $addressRegion = null; /** * The post office box number for PO box addresses. * - * @see http://schema.org/postOfficeBoxNumber + * @see https://schema.org/postOfficeBoxNumber * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/postOfficeBoxNumber") + * @ApiProperty(iri="https://schema.org/postOfficeBoxNumber") */ private ?string $postOfficeBoxNumber = null; /** * The postal code. For example, 94043. * - * @see http://schema.org/postalCode + * @see https://schema.org/postalCode * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/postalCode") + * @ApiProperty(iri="https://schema.org/postalCode") */ private ?string $postalCode = null; /** * The street address. For example, 1600 Amphitheatre Pkwy. * - * @see http://schema.org/streetAddress + * @see https://schema.org/streetAddress * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/streetAddress") + * @ApiProperty(iri="https://schema.org/streetAddress") */ private ?string $streetAddress = null; diff --git a/tests/e2e/src/App/Entity/Thing.php b/tests/e2e/src/App/Entity/Thing.php index 5638a09b..3311053a 100644 --- a/tests/e2e/src/App/Entity/Thing.php +++ b/tests/e2e/src/App/Entity/Thing.php @@ -20,10 +20,10 @@ /** * The most generic type of item. * - * @see http://schema.org/Thing + * @see https://schema.org/Thing * * @ORM\Entity - * @ApiResource(iri="http://schema.org/Thing") + * @ApiResource(iri="https://schema.org/Thing") */ class Thing { @@ -37,10 +37,10 @@ class Thing /** * The name of the item. * - * @see http://schema.org/name + * @see https://schema.org/name * * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="http://schema.org/name") + * @ApiProperty(iri="https://schema.org/name") */ private ?string $name = null; From 2e8df2046b29b8c9fc28f821b51868430b74603a Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Sat, 20 Nov 2021 13:19:33 +0100 Subject: [PATCH 190/258] feat: generate PHP 8 attributes (#351) --- box.json.dist | 4 - .../AbstractAttributeGenerator.php | 76 +++++++ .../ApiPlatformCoreAttributeGenerator.php} | 31 ++- .../AttributeGeneratorInterface.php | 44 ++++ .../ConstraintAttributeGenerator.php} | 39 ++-- .../DoctrineMongoDBAttributeGenerator.php} | 50 +++-- .../DoctrineOrmAttributeGenerator.php} | 120 +++++------ .../SerializerGroupsAttributeGenerator.php} | 16 +- src/ClassMutator/AttributeAppender.php | 93 +++++++++ src/Model/Class_.php | 26 ++- src/Model/Property.php | 23 ++- src/PropertyGenerator/PropertyGenerator.php | 1 + src/TypesGenerator.php | 10 + src/TypesGeneratorConfiguration.php | 40 ++-- .../DoctrineOrmAnnotationGeneratorTest.php | 100 --------- .../PhpDocAnnotationGeneratorTest.php | 58 ++++++ ...ApiPlatformCoreAttributeGeneratorTest.php} | 37 ++-- .../ConstraintAttributeGeneratorTest.php | 121 +++++++++++ .../DoctrineMongoDBAttributeGeneratorTest.php | 126 ++++++++++++ .../DoctrineOrmAttributeGeneratorTest.php | 189 ++++++++++++++++++ .../SerializerGroupAttributeGeneratorTest.php | 48 +++++ tests/Command/DumpConfigurationTest.php | 27 ++- tests/Command/GenerateCommandTest.php | 37 ++-- tests/TypesGeneratorTest.php | 2 + tests/config/address-book.yaml | 8 +- tests/config/blog.yaml | 5 +- tests/config/fluent-mutators.yaml | 8 +- tests/config/mongodb/address-book.yaml | 5 +- tests/config/mongodb/ecommerce.yaml | 5 +- tests/config/public-properties.yaml | 8 +- tests/config/vgo.yaml | 11 +- tests/e2e/schema.yml | 5 +- tests/e2e/src/App/Entity/Person.php | 88 ++++---- tests/e2e/src/App/Entity/PostalAddress.php | 52 ++--- tests/e2e/src/App/Entity/Thing.php | 27 +-- 35 files changed, 1110 insertions(+), 430 deletions(-) create mode 100644 src/AttributeGenerator/AbstractAttributeGenerator.php rename src/{AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php => AttributeGenerator/ApiPlatformCoreAttributeGenerator.php} (74%) create mode 100644 src/AttributeGenerator/AttributeGeneratorInterface.php rename src/{AnnotationGenerator/ConstraintAnnotationGenerator.php => AttributeGenerator/ConstraintAttributeGenerator.php} (71%) rename src/{AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php => AttributeGenerator/DoctrineMongoDBAttributeGenerator.php} (68%) rename src/{AnnotationGenerator/DoctrineOrmAnnotationGenerator.php => AttributeGenerator/DoctrineOrmAttributeGenerator.php} (60%) rename src/{AnnotationGenerator/SerializerGroupsAnnotationGenerator.php => AttributeGenerator/SerializerGroupsAttributeGenerator.php} (59%) create mode 100644 src/ClassMutator/AttributeAppender.php delete mode 100644 tests/AnnotationGenerator/DoctrineOrmAnnotationGeneratorTest.php create mode 100644 tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php rename tests/{AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php => AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php} (54%) create mode 100644 tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php create mode 100644 tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php create mode 100644 tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php create mode 100644 tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php diff --git a/box.json.dist b/box.json.dist index e1eaff00..85d3a276 100644 --- a/box.json.dist +++ b/box.json.dist @@ -12,12 +12,8 @@ "templates/" ], "files": [ - "vendor/friendsofphp/php-cs-fixer/tests/TestCase.php", "vendor/twig/twig/src/TwigTest.php" ], - "directories": [ - "vendor/friendsofphp/php-cs-fixer/tests/Test" - ], "force-autodiscovery": true, "compression": "GZ", diff --git a/src/AttributeGenerator/AbstractAttributeGenerator.php b/src/AttributeGenerator/AbstractAttributeGenerator.php new file mode 100644 index 00000000..1b25b6f2 --- /dev/null +++ b/src/AttributeGenerator/AbstractAttributeGenerator.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; +use Doctrine\Inflector\Inflector; +use EasyRdf\Graph; +use Psr\Log\LoggerInterface; + +/** + * Abstract attribute generator. + * + * @author Kévin Dunglas + */ +abstract class AbstractAttributeGenerator implements AttributeGeneratorInterface +{ + protected PhpTypeConverterInterface $phpTypeConverter; + protected Inflector $inflector; + protected LoggerInterface $logger; + /** + * @var Graph[] + */ + protected array $graphs; + protected array $cardinalities; + protected array $config; + /** @var Class_[] */ + protected array $classes; + + public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes) + { + $this->phpTypeConverter = $phpTypeConverter; + $this->inflector = $inflector; + $this->logger = $logger; + $this->graphs = $graphs; + $this->cardinalities = $cardinalities; + $this->config = $config; + $this->classes = $classes; + } + + /** + * {@inheritdoc} + */ + public function generateClassAttributes(Class_ $class): array + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generatePropertyAttributes(Property $property, string $className): array + { + return []; + } + + /** + * {@inheritdoc} + */ + public function generateUses(Class_ $class): array + { + return []; + } +} diff --git a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php similarity index 74% rename from src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php rename to src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 41e0ec05..bfdabc0f 100644 --- a/src/AnnotationGenerator/ApiPlatformCoreAnnotationGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -11,7 +11,7 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; @@ -22,18 +22,18 @@ use Symfony\Component\OptionsResolver\OptionsResolver; /** - * Generates API Platform core annotations. + * Generates API Platform core attributes. * * @author Kévin Dunglas * * @see https://github.com/api-platform/core */ -final class ApiPlatformCoreAnnotationGenerator extends AbstractAnnotationGenerator +final class ApiPlatformCoreAttributeGenerator extends AbstractAttributeGenerator { /** * {@inheritdoc} */ - public function generateClassAnnotations(Class_ $class): array + public function generateClassAttributes(Class_ $class): array { if ($class->isAbstract()) { return []; @@ -41,9 +41,9 @@ public function generateClassAnnotations(Class_ $class): array $arguments = []; if ($class->name() !== $localName = $class->resourceLocalName()) { - $arguments[] = sprintf('shortName="%s"', $localName); + $arguments['shortName'] = $localName; } - $arguments[] = sprintf('iri="%s"', $class->resourceUri()); + $arguments['iri'] = $class->resourceUri(); if ([] !== $class->operations()) { $operations = $this->validateClassOperations($class->operations()); @@ -53,15 +53,15 @@ public function generateClassAnnotations(Class_ $class): array $methodConfig = $this->validateClassOperationMethodConfig($methodConfig); $methodArguments = []; foreach ($methodConfig as $key => $value) { - $methodArguments[] = sprintf('"%s"="%s"', $key, $value); + $methodArguments[$key] = $value; } - $targetArguments[] = sprintf('"%s"={%s}', $method, implode(', ', $methodArguments)); + $targetArguments[$method] = $methodArguments; } - $arguments[] = sprintf('%sOperations={%s}', $operationTarget, implode(', ', $targetArguments)); + $arguments[sprintf('%sOperations', $operationTarget)] = $targetArguments; } } - return [sprintf('@ApiResource(%s)', implode(', ', $arguments))]; + return [['ApiResource' => $arguments]]; } /** @@ -78,7 +78,7 @@ private function validateClassOperations(array $operations): array } /** - * Validates the individual method config for an item/collection operation annotation. + * Validates the individual method config for an item/collection operation attribute. */ private function validateClassOperationMethodConfig(array $methodConfig): array { @@ -104,14 +104,9 @@ function (Options $options, $value) { /** * {@inheritdoc} */ - public function generatePropertyAnnotations(Property $property, string $className): array + public function generatePropertyAttributes(Property $property, string $className): array { - return $property->isCustom ? [] : [ - sprintf( - '@ApiProperty(iri="%s")', - $property->resourceUri() - ), - ]; + return $property->isCustom ? [] : [['ApiProperty' => ['iri' => $property->resourceUri()]]]; } /** diff --git a/src/AttributeGenerator/AttributeGeneratorInterface.php b/src/AttributeGenerator/AttributeGeneratorInterface.php new file mode 100644 index 00000000..f32f2dcd --- /dev/null +++ b/src/AttributeGenerator/AttributeGeneratorInterface.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; + +/** + * Attribute Generator Interface. + * + * @author Kévin Dunglas + */ +interface AttributeGeneratorInterface +{ + /** + * Generates class's attributes. + * + * @return array[] + */ + public function generateClassAttributes(Class_ $class): array; + + /** + * Generates field's attributes. + * + * @return array[] + */ + public function generatePropertyAttributes(Property $property, string $className): array; + + /** + * Generates uses. + */ + public function generateUses(Class_ $class): array; +} diff --git a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php similarity index 71% rename from src/AnnotationGenerator/ConstraintAnnotationGenerator.php rename to src/AttributeGenerator/ConstraintAttributeGenerator.php index d7651852..3da2ca56 100644 --- a/src/AnnotationGenerator/ConstraintAnnotationGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -11,27 +11,28 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use Nette\PhpGenerator\Literal; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; /** - * Constraint annotation generator. + * Constraint attribute generator. * * @author Kévin Dunglas */ -final class ConstraintAnnotationGenerator extends AbstractAnnotationGenerator +final class ConstraintAttributeGenerator extends AbstractAttributeGenerator { /** * {@inheritdoc} */ - public function generatePropertyAnnotations(Property $property, string $className): array + public function generatePropertyAttributes(Property $property, string $className): array { if ($property->isId) { if ('uuid' === $this->config['id']['generationStrategy']) { - return ['@Assert\Uuid']; + return [['Assert\Uuid' => []]]; } return []; @@ -42,41 +43,39 @@ public function generatePropertyAnnotations(Property $property, string $classNam if (!$property->isArray && $property->range) { switch ($property->range->getUri()) { case 'https://schema.org/URL': - $asserts[] = '@Assert\Url'; + $asserts[] = ['Assert\Url' => []]; break; case 'https://schema.org/Date': case 'https://schema.org/DateTime': case 'https://schema.org/Time': - $asserts[] = '@Assert\Type("\DateTimeInterface")'; + $asserts[] = ['Assert\Type' => [new Literal('\DateTimeInterface::class')]]; break; } if (null !== $property->resource && 'https://schema.org/email' === $property->resourceUri()) { - $asserts[] = '@Assert\Email'; + $asserts[] = ['Assert\Email' => []]; } if (!$asserts && $this->config['validator']['assertType']) { $phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []); if (\in_array($phpType, ['bool', 'float', 'int', 'string'], true)) { - $asserts[] = sprintf('@Assert\Type(type="%s")', $phpType); + $asserts[] = ['Assert\Type' => [$phpType]]; } } } if (!$property->isNullable) { - $asserts[] = '@Assert\NotNull'; + $asserts[] = ['Assert\NotNull' => []]; } if ($property->isEnum && $property->range) { - $assert = sprintf('@Assert\Choice(callback={"%s", "toArray"}', $property->rangeName); + $args = ['callback' => [$property->rangeName, 'toArray']]; if ($property->isArray) { - $assert .= ', multiple=true'; + $args['multiple'] = true; } - $assert .= ')'; - - $asserts[] = $assert; + $asserts[] = ['Assert\Choice' => $args]; } return $asserts; @@ -114,13 +113,13 @@ public function generateUses(Class_ $class): array /** * {@inheritdoc} */ - public function generateClassAnnotations(Class_ $class): array + public function generateClassAttributes(Class_ $class): array { if ($class->isEnum()) { return []; } - $annotation = []; + $attributes = []; $uniqueProperties = $class->uniquePropertyNames(); if (!$uniqueProperties) { @@ -128,11 +127,11 @@ public function generateClassAnnotations(Class_ $class): array } if (1 === \count($uniqueProperties)) { - $annotation[] = sprintf('@UniqueEntity("%s")', $uniqueProperties[0]); + $attributes[] = ['UniqueEntity' => [$uniqueProperties[0]]]; } else { - $annotation[] = sprintf('@UniqueEntity(fields={"%s"})', implode('","', $uniqueProperties)); + $attributes[] = ['UniqueEntity' => ['fields' => $uniqueProperties]]; } - return $annotation; + return $attributes; } } diff --git a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php similarity index 68% rename from src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php rename to src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index cc70b9cc..a7f4328b 100644 --- a/src/AnnotationGenerator/DoctrineMongoDBAnnotationGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -11,45 +11,57 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; /** - * Doctrine MongoDB annotation generator. + * Doctrine MongoDB attribute generator. * * @author Andrew Meshchanchuk > */ -final class DoctrineMongoDBAnnotationGenerator extends AbstractAnnotationGenerator +final class DoctrineMongoDBAttributeGenerator extends AbstractAttributeGenerator { /** * {@inheritdoc} */ - public function generateClassAnnotations(Class_ $class): array + public function generateClassAttributes(Class_ $class): array { + if ($doctrineAttributes = ($this->config['types'][$class->name()]['doctrine']['attributes'] ?? false)) { + return $doctrineAttributes; + } + if ($class->isEnum()) { return []; } - return [ - '', - $this->config['types'][$class->name()]['doctrine']['inheritanceMapping'] ?? ($class->isAbstract() ? '@MongoDB\MappedSuperclass' : '@MongoDB\Document'), - ]; + $attributes = []; + if ($class->isAbstract()) { + if ($inheritanceAttributes = ($this->config['doctrine']['inheritanceAttributes'] ?? [])) { + return $inheritanceAttributes; + } + + $attributes[] = ['MongoDB\MappedSuperclass' => []]; + } else { + $attributes[] = ['MongoDB\Document' => []]; + } + + return $attributes; } /** * {@inheritdoc} */ - public function generatePropertyAnnotations(Property $property, string $className): array + public function generatePropertyAttributes(Property $property, string $className): array { if (null === $property->range) { return []; } if ($property->isId) { - return $this->generateIdAnnotations(); + return $this->generateIdAttributes(); } $type = null; @@ -88,20 +100,20 @@ public function generatePropertyAnnotations(Property $property, string $classNam } if (null !== $type) { - return [sprintf('@MongoDB\Field(type="%s")', $type)]; + return [['MongoDB\Field' => ['type' => $type]]]; } if (CardinalitiesExtractor::CARDINALITY_0_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_0 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_1 === $property->cardinality) { - return [sprintf('@MongoDB\ReferenceOne(targetDocument="%s", simple=true))', $this->getRelationName($property->rangeName))]; + return [['MongoDB\ReferenceOne' => ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true]]]; } if (CardinalitiesExtractor::CARDINALITY_0_N === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_N === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_N === $property->cardinality) { - return [sprintf('@MongoDB\ReferenceMany(targetDocument="%s", simple=true)', $this->getRelationName($property->rangeName))]; + return [['MongoDB\ReferenceMany' => ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true]]]; } return []; @@ -124,21 +136,21 @@ private function getRelationName(string $rangeName): string ? $this->classes[$rangeName]->interfaceName() : $rangeName; } - private function generateIdAnnotations(): array + private function generateIdAttributes(): array { switch ($this->config['id']['generationStrategy']) { case 'uuid': if ($this->config['id']['writable']) { - return ['@MongoDB\Id(strategy="NONE", type="bin_uuid")']; + return [['MongoDB\Id' => ['strategy' => 'NONE', 'type' => 'bin_uuid']]]; } - return ['@MongoDB\Id(strategy="UUID")']; + return [['MongoDB\Id' => ['strategy' => 'UUID']]]; case 'auto': - return ['@MongoDB\Id(strategy="INCREMENT")']; + return [['MongoDB\Id' => ['strategy' => 'INCREMENT']]]; case 'mongoid': - return ['@MongoDB\Id']; + return [['MongoDB\Id' => []]]; default: - return ['@MongoDB\Id(strategy="NONE", type="string")']; + return [['MongoDB\Id' => ['strategy' => 'NONE', 'type' => 'string']]]; } } } diff --git a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php similarity index 60% rename from src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php rename to src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index d0450e24..bdc6e134 100644 --- a/src/AnnotationGenerator/DoctrineOrmAnnotationGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -11,18 +11,18 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; /** - * Doctrine annotation generator. + * Doctrine attribute generator. * * @author Kévin Dunglas */ -final class DoctrineOrmAnnotationGenerator extends AbstractAnnotationGenerator +final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator { private const RESERVED_KEYWORDS = [ 'add', @@ -38,10 +38,10 @@ final class DoctrineOrmAnnotationGenerator extends AbstractAnnotationGenerator /** * {@inheritdoc} */ - public function generateClassAnnotations(Class_ $class): array + public function generateClassAttributes(Class_ $class): array { - if ($this->config['types'][$class->name()]['doctrine']['annotations'] ?? false) { - return array_merge([''], $this->config['types'][$class->name()]['doctrine']['annotations']); + if ($doctrineAttributes = ($this->config['types'][$class->name()]['doctrine']['attributes'] ?? false)) { + return $doctrineAttributes; } if ($class->isEnum()) { @@ -49,18 +49,18 @@ public function generateClassAnnotations(Class_ $class): array } if ($class->isEmbeddable()) { - return ['', '@ORM\Embeddable']; + return [['ORM\Embeddable' => []]]; } - $annotations = ['']; + $attributes = []; if ($class->isAbstract()) { - if ($this->config['doctrine']['inheritanceAnnotations'] ?? []) { - return array_merge($annotations, $this->config['doctrine']['inheritanceAnnotations']); + if ($inheritanceAttributes = ($this->config['doctrine']['inheritanceAttributes'] ?? [])) { + return $inheritanceAttributes; } - $annotations[] = '@ORM\MappedSuperclass'; + $attributes[] = ['ORM\MappedSuperclass' => []]; } else { - $annotations[] = '@ORM\Entity'; + $attributes[] = ['ORM\Entity' => []]; } foreach (self::RESERVED_KEYWORDS as $keyword) { @@ -68,32 +68,29 @@ public function generateClassAnnotations(Class_ $class): array continue; } - $annotations[] = sprintf('@ORM\Table(name="`%s`")', strtolower($class->name())); + $attributes[] = ['ORM\Table' => ['name' => strtolower($class->name())]]; - return $annotations; + return $attributes; } - return $annotations; + return $attributes; } /** * {@inheritdoc} */ - public function generatePropertyAnnotations(Property $property, string $className): array + public function generatePropertyAttributes(Property $property, string $className): array { if (null === $property->rangeName) { return []; } - $annotation = '@ORM\Column'; - if (null !== $property->ormColumn) { - $annotation = sprintf('@ORM\Column(%s)', $property->ormColumn); - - return [$annotation]; + if ($property->ormColumn) { + return [['ORM\Column' => $property->ormColumn]]; } if ($property->isId) { - return $this->generateIdAnnotations(); + return $this->generateIdAttributes(); } if (isset($this->config['types'][$className]['properties'][$property->name()])) { @@ -140,31 +137,27 @@ public function generatePropertyAnnotations(Property $property, string $classNam } if (null !== $type) { - $annotArr = []; + $args = []; if ('string' !== $type) { - $annotArr[] = sprintf('type="%s"', $type); + $args['type'] = $type; } if ($property->isNullable) { - $annotArr[] = 'nullable=true'; + $args['nullable'] = true; } if ($property->isUnique) { - $annotArr[] = 'unique=true'; + $args['unique'] = true; } foreach (self::RESERVED_KEYWORDS as $keyword) { if (0 === strcasecmp($keyword, $property->name())) { - $annotArr[] = sprintf('name="`%s`"', $property->name()); + $args['name'] = sprintf('`%s`', $property->name()); break; } } - if ($annotArr) { - $annotation .= sprintf('(%s)', implode(', ', $annotArr)); - } - - return [$annotation]; + return [['ORM\Column' => $args]]; } if (null === $relationName = $this->getRelationName($property->rangeName)) { @@ -174,68 +167,65 @@ public function generatePropertyAnnotations(Property $property, string $classNam } if ($property->isEmbedded) { - $columnPrefix = ', columnPrefix='; - if (\is_bool($property->columnPrefix)) { - $columnPrefix .= $property->columnPrefix ? 'true' : 'false'; - } else { - $columnPrefix .= sprintf('"%s"', $property->columnPrefix); - } - - return [sprintf('@ORM\Embedded(class="%s"%s)', $relationName, $columnPrefix)]; + return [['ORM\Embedded' => ['class' => $relationName, 'columnPrefix' => $property->columnPrefix]]]; } - $annotations = []; + $attributes = []; switch ($property->cardinality) { case CardinalitiesExtractor::CARDINALITY_0_1: - $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $relationName); + $attributes[] = ['ORM\OneToOne' => ['targetEntity' => $relationName]]; break; case CardinalitiesExtractor::CARDINALITY_1_1: - $annotations[] = sprintf('@ORM\OneToOne(targetEntity="%s")', $relationName); - $annotations[] = '@ORM\JoinColumn(nullable=false)'; + $attributes[] = ['ORM\OneToOne' => ['targetEntity' => $relationName]]; + $attributes[] = ['ORM\JoinColumn' => ['nullable' => false]]; break; case CardinalitiesExtractor::CARDINALITY_UNKNOWN: case CardinalitiesExtractor::CARDINALITY_N_0: if (null !== $property->inversedBy) { - $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s", inversedBy="%s")', $relationName, $property->inversedBy); + $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName, 'inversedBy' => $property->inversedBy]]; } else { - $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $relationName); + $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName]]; } break; case CardinalitiesExtractor::CARDINALITY_N_1: if (null !== $property->inversedBy) { - $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s", inversedBy="%s")', $relationName, $property->inversedBy); + $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName, 'inversedBy' => $property->inversedBy]]; } else { - $annotations[] = sprintf('@ORM\ManyToOne(targetEntity="%s")', $relationName); + $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName]]; } - $annotations[] = '@ORM\JoinColumn(nullable=false)'; + $attributes[] = ['ORM\JoinColumn' => ['nullable' => false]]; break; case CardinalitiesExtractor::CARDINALITY_0_N: if (null !== $property->mappedBy) { - $annotations[] = sprintf('@ORM\OneToMany(targetEntity="%s", mappedBy="%s")', $relationName, $property->mappedBy); + $attributes[] = ['ORM\OneToMany' => ['targetEntity' => $relationName, 'mappedBy' => $property->mappedBy]]; } else { - $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $relationName); + $attributes[] = ['ORM\ManyToMany' => ['targetEntity' => $relationName]]; } - $name = $property->relationTableName ? sprintf('name="%s", ', $property->relationTableName) : ''; - $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(unique=true)})'; + if ($property->relationTableName) { + $attributes[] = ['ORM\JoinTable' => ['name' => $property->relationTableName]]; + } + $attributes[] = ['ORM\InverseJoinColumn' => ['unique' => true]]; break; case CardinalitiesExtractor::CARDINALITY_1_N: if (null !== $property->mappedBy) { - $annotations[] = sprintf('@ORM\OneToMany(targetEntity="%s", mappedBy="%s")', $relationName, $property->mappedBy); + $attributes[] = ['ORM\OneToMany' => ['targetEntity' => $relationName, 'mappedBy' => $property->mappedBy]]; } else { - $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $relationName); + $attributes[] = ['ORM\ManyToMany' => ['targetEntity' => $relationName]]; + } + if ($property->relationTableName) { + $attributes[] = ['ORM\JoinTable' => ['name' => $property->relationTableName]]; } - $name = $property->relationTableName ? sprintf('name="%s", ', $property->relationTableName) : ''; - $annotations[] = '@ORM\JoinTable('.$name.'inverseJoinColumns={@ORM\JoinColumn(nullable=false, unique=true)})'; + $attributes[] = ['ORM\InverseJoinColumn' => ['nullable' => false, 'unique' => true]]; break; case CardinalitiesExtractor::CARDINALITY_N_N: - $annotations[] = sprintf('@ORM\ManyToMany(targetEntity="%s")', $relationName); + $attributes[] = ['ORM\ManyToMany' => ['targetEntity' => $relationName]]; if ($property->relationTableName) { - $annotations[] = sprintf('@ORM\JoinTable(name="%s")', $property->relationTableName); + $attributes[] = ['ORM\JoinTable' => ['name' => $property->relationTableName]]; } break; } - return $annotations; + return $attributes; } /** @@ -246,11 +236,11 @@ public function generateUses(Class_ $class): array return $class->isEnum() ? [] : ['Doctrine\ORM\Mapping as ORM']; } - private function generateIdAnnotations(): array + private function generateIdAttributes(): array { - $annotations = ['@ORM\Id']; + $attributes = [['ORM\Id' => []]]; if ('none' !== $this->config['id']['generationStrategy'] && !$this->config['id']['writable']) { - $annotations[] = sprintf('@ORM\GeneratedValue(strategy="%s")', strtoupper($this->config['id']['generationStrategy'])); + $attributes[] = ['ORM\GeneratedValue' => ['strategy' => strtoupper($this->config['id']['generationStrategy'])]]; } switch ($this->config['id']['generationStrategy']) { @@ -265,9 +255,9 @@ private function generateIdAnnotations(): array break; } - $annotations[] = sprintf('@ORM\Column(type="%s")', $type); + $attributes[] = ['ORM\Column' => ['type' => $type]]; - return $annotations; + return $attributes; } /** diff --git a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php b/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php similarity index 59% rename from src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php rename to src/AttributeGenerator/SerializerGroupsAttributeGenerator.php index 8fb1cc03..4b53ac0c 100644 --- a/src/AnnotationGenerator/SerializerGroupsAnnotationGenerator.php +++ b/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php @@ -11,33 +11,29 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use Symfony\Component\Serializer\Annotation\Groups; /** - * Symfony Serializer Groups annotation generator. + * Symfony Serializer Groups attribute generator. * * @author Youssef El Montaser * @author Kévin Dunglas * * @see https://symfony.com/doc/master/components/serializer.html */ -final class SerializerGroupsAnnotationGenerator extends AbstractAnnotationGenerator +final class SerializerGroupsAttributeGenerator extends AbstractAttributeGenerator { /** * {@inheritdoc} */ - public function generatePropertyAnnotations(Property $property, string $className): array + public function generatePropertyAttributes(Property $property, string $className): array { - if ($this->config['types'][$className]['properties'] ?? null) { - return []; - } - - if (false === $property->isId && $property->groups() ?? false) { - return [sprintf('@Groups({"%s"})', implode('", "', $property->groups()))]; + if (false === $property->isId && $property->groups()) { + return [['Groups' => [$property->groups()]]]; } return []; diff --git a/src/ClassMutator/AttributeAppender.php b/src/ClassMutator/AttributeAppender.php new file mode 100644 index 00000000..6df99000 --- /dev/null +++ b/src/ClassMutator/AttributeAppender.php @@ -0,0 +1,93 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\ClassMutator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\AttributeGeneratorInterface; +use ApiPlatform\SchemaGenerator\Model\Class_; + +final class AttributeAppender implements ClassMutatorInterface +{ + /** @var AttributeGeneratorInterface[] */ + private array $attributeGenerators; + /** @var Class_[] */ + private array $classes; + + /** + * @param AttributeGeneratorInterface[] $attributeGenerators + */ + public function __construct(array $classes, array $attributeGenerators) + { + $this->attributeGenerators = $attributeGenerators; + $this->classes = $classes; + } + + public function __invoke(Class_ $class): Class_ + { + $class = $this->generateClassUses($class); + $class = $this->generateClassAttributes($class); + $class = $this->generatePropertiesAttributes($class); + + return $class; + } + + private function generateClassUses(Class_ $class): Class_ + { + $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; + if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace()) { + $class->addUse(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName())); + } + + foreach ($class->properties() as $property) { + if (isset($this->classes[$property->rangeName]) && $this->classes[$property->rangeName]->interfaceName()) { + $class->addUse(sprintf( + '%s\\%s', + $this->classes[$property->rangeName]->interfaceNamespace(), + $this->classes[$property->rangeName]->interfaceName() + )); + } + } + + foreach ($this->attributeGenerators as $generator) { + foreach ($generator->generateUses($class) as $use) { + $class->addUse($use); + } + } + + return $class; + } + + private function generateClassAttributes(Class_ $class): Class_ + { + foreach ($this->attributeGenerators as $generator) { + foreach ($generator->generateClassAttributes($class) as $attribute) { + $class->addAttribute($attribute); + } + } + + return $class; + } + + private function generatePropertiesAttributes(Class_ $class): Class_ + { + foreach ($class->properties() as $name => &$property) { + foreach ($this->attributeGenerators as $attributeGenerator) { + foreach ($attributeGenerator->generatePropertyAttributes($property, $class->name()) as $propertyAttribute) { + $property->addAttribute($propertyAttribute); + } + } + } + + return $class; + } +} diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 76ae6a70..3622d942 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -30,6 +30,8 @@ final class Class_ private array $properties = []; /** @var array|Constant[] */ private array $constants = []; + /** @var array[] */ + private array $attributes = []; private array $annotations = []; private array $operations = []; private bool $hasConstructor = false; @@ -128,6 +130,18 @@ public function addUse(string $use): self return $this; } + /** + * @param array $attribute + */ + public function addAttribute(array $attribute): self + { + if (!\in_array($attribute, $this->attributes, true)) { + $this->attributes[] = $attribute; + } + + return $this; + } + public function addAnnotation(string $annotation): self { if ('' === $annotation || !\in_array($annotation, $this->annotations, true)) { @@ -260,13 +274,13 @@ public function namespace(): string return $this->namespace; } - /** @return Property[] */ + /** @return array */ public function properties(): array { return $this->properties; } - /** @return Property[] */ + /** @return array */ public function uniqueProperties(): array { return array_filter($this->properties, static fn (Property $property) => $property->isUnique); @@ -275,7 +289,7 @@ public function uniqueProperties(): array /** @return string[] */ public function uniquePropertyNames(): array { - return array_map(static fn (Property $property) => $property->name, $this->uniqueProperties()); + return array_map(static fn (Property $property) => $property->name, array_values($this->uniqueProperties())); } public function toNetteFile(array $config, Inflector $inflector): PhpFile @@ -299,6 +313,12 @@ public function toNetteFile(array $config, Inflector $inflector): PhpFile $class = $namespace->addClass($this->name); + foreach ($this->attributes as $attribute) { + foreach ($attribute as $attributeName => $attributeArgs) { + $class->addAttribute($attributeName, $attributeArgs); + } + } + foreach ($this->annotations as $annotation) { $class->addComment($annotation); } diff --git a/src/Model/Property.php b/src/Model/Property.php index 7061c059..d5c1b69e 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -25,7 +25,7 @@ final class Property public string $cardinality; public $range; public $rangeName; - public ?string $ormColumn = null; + public ?array $ormColumn = null; public bool $isArray = false; public bool $isReadable = true; public bool $isWritable = true; @@ -41,12 +41,14 @@ final class Property public ?string $relationTableName = null; public bool $isEnum = false; public ?string $adderRemoverTypeHint = null; + public array $groups = []; + /** @var array[] */ + private array $attributes = []; private array $annotations = []; private array $getterAnnotations = []; private array $setterAnnotations = []; private array $adderAnnotations = []; private array $removerAnnotations = []; - private array $groups = []; public function __construct(string $name) { @@ -58,6 +60,18 @@ public function name(): string return $this->name; } + /** + * @param array $attribute + */ + public function addAttribute(array $attribute): self + { + if (!\in_array($attribute, $this->attributes, true)) { + $this->attributes[] = $attribute; + } + + return $this; + } + public function addAnnotation(string $annotation): self { if ('' === $annotation || !\in_array($annotation, $this->annotations, true)) { @@ -142,6 +156,11 @@ public function toNetteProperty(string $visibility = null, bool $useDoctrineColl $netteProperty->setValue($default); } + foreach ($this->attributes as $attribute) { + foreach ($attribute as $attributeName => $attributeArgs) { + $netteProperty->addAttribute($attributeName, $attributeArgs); + } + } foreach ($this->annotations as $annotation) { $netteProperty->addComment($annotation); } diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index e9e83116..8792126d 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -144,6 +144,7 @@ public function __invoke(array $config, Class_ $class, RdfResource $type, array $schemaGeneratorProperty->columnPrefix = $columnPrefix; $schemaGeneratorProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; $schemaGeneratorProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; + $schemaGeneratorProperty->groups = $propertyConfig['groups'] ?? []; $schemaGeneratorProperty->isId = false; $class->addProperty($schemaGeneratorProperty); diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 733ecf84..b4601336 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -14,6 +14,7 @@ namespace ApiPlatform\SchemaGenerator; use ApiPlatform\SchemaGenerator\ClassMutator\AnnotationsAppender; +use ApiPlatform\SchemaGenerator\ClassMutator\AttributeAppender; use ApiPlatform\SchemaGenerator\ClassMutator\ClassIdAppender; use ApiPlatform\SchemaGenerator\ClassMutator\ClassInterfaceMutator; use ApiPlatform\SchemaGenerator\ClassMutator\ClassParentMutator; @@ -229,11 +230,20 @@ public function generate(array $config): void $annotationGenerators[] = $generator; } + // Initialize attribute generators + $attributeGenerators = []; + foreach ($config['attributeGenerators'] as $attributeGenerator) { + $generator = new $attributeGenerator($this->phpTypeConverter, $this->logger, $this->inflector, $this->graphs, $this->cardinalities, $config, $classes); + + $attributeGenerators[] = $generator; + } + $interfaceMappings = []; $generatedFiles = []; foreach ($classes as $className => &$class) { $class = (new AnnotationsAppender($classes, $annotationGenerators, $typesToGenerate))($class); + $class = (new AttributeAppender($classes, $attributeGenerators))($class); $classDir = $this->namespaceToDir($config, $class->namespace()); $this->filesystem->mkdir($classDir); diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 7330ba10..4f021c79 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -13,11 +13,11 @@ namespace ApiPlatform\SchemaGenerator; -use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; -use ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator; -use ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator; use ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator; -use ApiPlatform\SchemaGenerator\AnnotationGenerator\SerializerGroupsAnnotationGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -109,9 +109,9 @@ static function ($rdf) { ->children() ->booleanNode('useCollection')->defaultTrue()->info('Use Doctrine\'s ArrayCollection instead of standard arrays')->end() ->scalarNode('resolveTargetEntityConfigPath')->defaultNull()->info('The Resolve Target Entity Listener config file pass')->end() - ->arrayNode('inheritanceAnnotations') - ->info('Doctrine inheritance annotations (if set, no other annotations are generated)') - ->prototype('scalar')->end() + ->arrayNode('inheritanceAttributes') + ->info('Doctrine inheritance attributes (if set, no other attributes are generated)') + ->prototype('variable')->end() ->end() ->end() ->end() @@ -161,9 +161,9 @@ static function ($rdf) { ->arrayNode('doctrine') ->addDefaultsIfNotSet() ->children() - ->arrayNode('annotations') - ->info('Doctrine annotations (if set, no other annotations are generated)') - ->prototype('scalar')->end() + ->arrayNode('attributes') + ->info('Doctrine attributes (if set, no other attributes are generated)') + ->prototype('variable')->end() ->end() ->end() ->end() @@ -189,7 +189,11 @@ static function ($rdf) { CardinalitiesExtractor::CARDINALITY_N_N, CardinalitiesExtractor::CARDINALITY_UNKNOWN, ])->end() - ->scalarNode('ormColumn')->defaultNull()->info('The doctrine column annotation content')->example('type="decimal", precision=5, scale=1, options={"comment" = "my comment"}')->end() + ->arrayNode('ormColumn') + ->info('The doctrine column attribute content') + ->example('{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}') + ->prototype('variable')->end() + ->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') ->prototype('scalar')->end() @@ -212,10 +216,16 @@ static function ($rdf) { ->info('Annotation generators to use') ->defaultValue([ PhpDocAnnotationGenerator::class, - DoctrineOrmAnnotationGenerator::class, - ApiPlatformCoreAnnotationGenerator::class, - ConstraintAnnotationGenerator::class, - SerializerGroupsAnnotationGenerator::class, + ]) + ->prototype('scalar')->end() + ->end() + ->arrayNode('attributeGenerators') + ->info('Attribute generators to use') + ->defaultValue([ + DoctrineOrmAttributeGenerator::class, + ApiPlatformCoreAttributeGenerator::class, + ConstraintAttributeGenerator::class, + SerializerGroupsAttributeGenerator::class, ]) ->prototype('scalar')->end() ->end() diff --git a/tests/AnnotationGenerator/DoctrineOrmAnnotationGeneratorTest.php b/tests/AnnotationGenerator/DoctrineOrmAnnotationGeneratorTest.php deleted file mode 100644 index 87db8594..00000000 --- a/tests/AnnotationGenerator/DoctrineOrmAnnotationGeneratorTest.php +++ /dev/null @@ -1,100 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; - -use ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; -use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use ApiPlatform\SchemaGenerator\TypesGenerator; -use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; -use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; - -/** - * @author Erik Saunier - */ -class DoctrineOrmAnnotationGeneratorTest extends TestCase -{ - /** - * @var DoctrineOrmAnnotationGenerator - */ - private $generator; - - private array $classMap = []; - - protected function setUp(): void - { - $graph = new Graph(); - - $product = new Class_('Product', new Resource('https://schema.org/Product', $graph)); - $product->setIsAbstract(true); - $this->classMap[$product->name()] = $product; - - $vehicle = new Class_('Vehicle', new Resource('htts://schema.org/Vehicle', $graph)); - $weightProperty = new Property('weight'); - $weightProperty->isEmbedded = true; - $weightProperty->rangeName = 'QuantitativeValue'; - $weightProperty->range = new Resource('https://schema.org/QuantitativeValue'); - $vehicle->addProperty($weightProperty); - $prefixedWeightProperty = new Property('prefixedWeight'); - $prefixedWeightProperty->columnPrefix = 'weight_'; - $prefixedWeightProperty->isEmbedded = true; - $prefixedWeightProperty->rangeName = 'QuantitativeValue'; - $prefixedWeightProperty->range = new Resource('https://schema.org/QuantitativeValue'); - $vehicle->addProperty($prefixedWeightProperty); - $this->classMap[$vehicle->name()] = $vehicle; - - $quantitativeValue = new Class_('QuantitativeValue', new Resource('https://schema.org/QuantitativeValue', $graph)); - $quantitativeValue->setEmbeddable(true); - $this->classMap[$quantitativeValue->name()] = $quantitativeValue; - - $myEnum = new Resource('https://schema.org/MyEnum', $graph); - $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - $myEnumClass = new Class_('MyEnum', $myEnum); - $this->classMap[$myEnumClass->name()] = $myEnumClass; - - $this->generator = new DoctrineOrmAnnotationGenerator( - new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], - [], - $this->classMap - ); - } - - public function testGenerateClassAnnotations(): void - { - $this->assertSame([], $this->generator->generateClassAnnotations($this->classMap['MyEnum'])); - $this->assertSame(['', '@ORM\MappedSuperclass'], $this->generator->generateClassAnnotations($this->classMap['Product'])); - $this->assertSame(['', '@ORM\Entity'], $this->generator->generateClassAnnotations($this->classMap['Vehicle'])); - $this->assertSame(['', '@ORM\Embeddable'], $this->generator->generateClassAnnotations($this->classMap['QuantitativeValue'])); - } - - public function testGenerateFieldAnnotations(): void - { - $this->assertSame( - ['@ORM\Embedded(class="QuantitativeValue", columnPrefix=false)'], - $this->generator->generatePropertyAnnotations($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') - ); - $this->assertSame( - ['@ORM\Embedded(class="QuantitativeValue", columnPrefix="weight_")'], - $this->generator->generatePropertyAnnotations($this->classMap['Vehicle']->getPropertyByName('prefixedWeight'), 'Vehicle') - ); - } -} diff --git a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php new file mode 100644 index 00000000..cefc5ad4 --- /dev/null +++ b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php @@ -0,0 +1,58 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; + +use ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Interface_; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use Doctrine\Inflector\InflectorFactory; +use EasyRdf\Graph; +use EasyRdf\Resource; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +class PhpDocAnnotationGeneratorTest extends TestCase +{ + private PhpDocAnnotationGenerator $generator; + + protected function setUp(): void + { + $this->generator = new PhpDocAnnotationGenerator( + new PhpTypeConverter(), + new NullLogger(), + InflectorFactory::create()->build(), + [], + [], + ['author' => 'Bill'], + [], + ); + } + + /** + * @dataProvider provideGenerateClassAnnotationsCases + */ + public function testGenerateClassAnnotations(Class_ $class, array $annotations): void + { + $this->assertSame($annotations, $this->generator->generateClassAnnotations($class)); + } + + public function provideGenerateClassAnnotationsCases(): \Generator + { + yield 'with interface' => [(new Class_('Res', new Resource('https://schema.org/Res')))->withInterface(new Interface_('Interface', '/foo')), ['{@inheritdoc}', '', '@author Bill']]; + + $graph = new Graph(); + yield 'with resource' => [new Class_('Res', new Resource('https://schema.org/Res', $graph)), ['', '', '@see https://schema.org/Res', '@author Bill']]; + } +} diff --git a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php similarity index 54% rename from tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php rename to tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 70cec23e..dba091be 100644 --- a/tests/AnnotationGenerator/ApiPlatformCoreAnnotationGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -11,11 +11,11 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\Tests\AnnotationGenerator; +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; -use ApiPlatform\SchemaGenerator\AnnotationGenerator\ApiPlatformCoreAnnotationGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; @@ -29,13 +29,13 @@ /** * @author Kévin Dunglas */ -class ApiPlatformCoreAnnotationGeneratorTest extends TestCase +class ApiPlatformCoreAttributeGeneratorTest extends TestCase { - private ApiPlatformCoreAnnotationGenerator $generator; + private ApiPlatformCoreAttributeGenerator $generator; protected function setUp(): void { - $this->generator = new ApiPlatformCoreAnnotationGenerator( + $this->generator = new ApiPlatformCoreAttributeGenerator( new PhpTypeConverter(), new NullLogger(), InflectorFactory::create()->build(), @@ -46,36 +46,41 @@ protected function setUp(): void ); } - public function testGenerateClassAnnotations(): void + /** + * @dataProvider provideGenerateClassAttributesCases + */ + public function testGenerateClassAttributes(Class_ $class, array $attributes): void { - $this->assertSame(['@ApiResource(iri="https://schema.org/Res")'], $this->generator->generateClassAnnotations(new Class_('Res', new Resource('https://schema.org/Res')))); + $this->assertSame($attributes, $this->generator->generateClassAttributes($class)); } - public function testGenerateClassAnnotationsWithOperations(): void + public function provideGenerateClassAttributesCases(): \Generator { + yield 'classical' => [new Class_('Res', new Resource('https://schema.org/Res')), [['ApiResource' => ['iri' => 'https://schema.org/Res']]]]; + $class = new Class_('WithOperations', new Resource('https://schema.org/WithOperations')); $class->setOperations([ 'item' => ['get' => ['route_name' => 'api_about_get']], 'collection' => [], ]); + yield 'with operations' => [$class, [['ApiResource' => ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []]]]]; - $this->assertSame( - ['@ApiResource(iri="https://schema.org/WithOperations", itemOperations={"get"={"route_name"="api_about_get"}}, collectionOperations={})'], - $this->generator->generateClassAnnotations($class) - ); + yield 'abstract' => [(new Class_('Abstract', new Resource('https://schema.org/Abstract')))->setIsAbstract(true), []]; + + yield 'with short name' => [(new Class_('WithShortName', new Resource('https://schema.org/DifferentLocalName'))), [['ApiResource' => ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName']]]]; } - public function testGeneratePropertyAnnotations(): void + public function testGeneratePropertyAttributes(): void { $property = new Property('prop'); $property->resource = new Resource('https://schema.org/prop'); - $this->assertSame(['@ApiProperty(iri="https://schema.org/prop")'], $this->generator->generatePropertyAnnotations($property, 'Res')); + $this->assertSame([['ApiProperty' => ['iri' => 'https://schema.org/prop']]], $this->generator->generatePropertyAttributes($property, 'Res')); } - public function testGenerateCustomPropertyAnnotations(): void + public function testGenerateCustomPropertyAttributes(): void { - $this->assertSame([], $this->generator->generatePropertyAnnotations((new Property('customProp'))->markAsCustom(), 'Res')); + $this->assertSame([], $this->generator->generatePropertyAttributes((new Property('customProp'))->markAsCustom(), 'Res')); } public function testGenerateUses(): void diff --git a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php new file mode 100644 index 00000000..a664861e --- /dev/null +++ b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php @@ -0,0 +1,121 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\TypesGenerator; +use Doctrine\Inflector\InflectorFactory; +use EasyRdf\Graph; +use EasyRdf\Resource; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; + +class ConstraintAttributeGeneratorTest extends TestCase +{ + private ConstraintAttributeGenerator $generator; + + protected function setUp(): void + { + $this->generator = new ConstraintAttributeGenerator( + new PhpTypeConverter(), + new NullLogger(), + InflectorFactory::create()->build(), + [], + [], + ['id' => ['generationStrategy' => 'uuid']], + [], + ); + } + + /** + * @dataProvider provideGenerateClassAttributesCases + */ + public function testGenerateClassAttributes(Class_ $class, array $attributes): void + { + $this->assertSame($attributes, $this->generator->generateClassAttributes($class)); + } + + public function provideGenerateClassAttributesCases(): \Generator + { + $graph = new Graph(); + $resource = new Resource('https://schema.org/Enum', $graph); + $resource->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); + + yield 'enum' => [new Class_('Enum', $resource), []]; + + $graph = new Graph(); + $class = new Class_('Foo', new Resource('https://schema.org/Foo', $graph)); + $uniqueProperty = new Property('bar'); + $uniqueProperty->isUnique = true; + $class->addProperty($uniqueProperty); + + yield 'one unique property' => [$class, [['UniqueEntity' => ['bar']]]]; + + $graph = new Graph(); + $class = new Class_('Foo', new Resource('https://schema.org/Foo', $graph)); + $uniqueProperty = new Property('bar'); + $uniqueProperty->isUnique = true; + $class->addProperty($uniqueProperty); + $uniqueProperty = new Property('baz'); + $uniqueProperty->isUnique = true; + $class->addProperty($uniqueProperty); + + yield 'multiple unique properties' => [$class, [['UniqueEntity' => ['fields' => ['bar', 'baz']]]]]; + } + + /** + * @dataProvider provideGeneratePropertyAttributesCases + */ + public function testGeneratePropertyAttributes(Property $property, array $attributes): void + { + $this->assertSame($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); + } + + public function provideGeneratePropertyAttributesCases(): \Generator + { + $property = new Property('prop'); + $property->isId = true; + yield 'uuid' => [$property, [['Assert\Uuid' => []]]]; + + $property = new Property('prop'); + $property->range = new Resource('https://schema.org/email'); + $property->resource = new Resource('https://schema.org/email'); + $property->isNullable = false; + yield 'email' => [$property, [['Assert\Email' => []], ['Assert\NotNull' => []]]]; + + $property = new Property('prop'); + $property->range = new Resource('https://schema.org/Enum'); + $property->rangeName = 'Enum'; + $property->isEnum = true; + $property->isArray = true; + yield 'enum' => [$property, [['Assert\Choice' => ['callback' => ['Enum', 'toArray'], 'multiple' => true]]]]; + } + + public function testGenerateUses(): void + { + $this->assertSame(['Symfony\Component\Validator\Constraints as Assert', UniqueEntity::class], $this->generator->generateUses(new Class_('Res', new Resource('https://schema.org/Res', new Graph())))); + } + + public function testGenerateNoUsesForEnum(): void + { + $graph = new Graph(); + $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); + $this->assertSame([], $this->generator->generateUses(new Class_('MyEnum', $myEnum))); + } +} diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php new file mode 100644 index 00000000..2c81b7de --- /dev/null +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineMongoDBAttributeGenerator; +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\TypesGenerator; +use Doctrine\Inflector\InflectorFactory; +use EasyRdf\Graph; +use EasyRdf\Resource; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +class DoctrineMongoDBAttributeGeneratorTest extends TestCase +{ + private DoctrineMongoDBAttributeGenerator $generator; + + private array $classMap = []; + + protected function setUp(): void + { + $graph = new Graph(); + + $product = new Class_('Product', new Resource('https://schema.org/Product', $graph)); + $product->setIsAbstract(true); + $this->classMap[$product->name()] = $product; + + $vehicle = new Class_('Vehicle', new Resource('htts://schema.org/Vehicle', $graph)); + $idProperty = new Property('id'); + $idProperty->rangeName = 'identifier'; + $idProperty->range = new Resource('https://schema.org/identifier'); + $idProperty->isId = true; + $vehicle->addProperty($idProperty); + $enumProperty = new Property('enum'); + $enumProperty->rangeName = 'Thing'; + $enumProperty->range = new Resource('https://schema.org/Thing'); + $enumProperty->isEnum = true; + $enumProperty->isArray = true; + $vehicle->addProperty($enumProperty); + $collectionProperty = new Property('collection'); + $collectionProperty->rangeName = 'Thing'; + $collectionProperty->range = new Resource('https://schema.org/Thing'); + $collectionProperty->isArray = true; + $vehicle->addProperty($collectionProperty); + $weightProperty = new Property('weight'); + $weightProperty->rangeName = 'nonPositiveInteger'; + $weightProperty->range = new Resource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); + $vehicle->addProperty($weightProperty); + $relationProperty = new Property('relation'); + $relationProperty->rangeName = 'Person'; + $relationProperty->range = new Resource('https://schema.org/Person'); + $relationProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $vehicle->addProperty($relationProperty); + $relationsProperty = new Property('relations'); + $relationsProperty->rangeName = 'Person'; + $relationsProperty->range = new Resource('https://schema.org/Person'); + $relationsProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; + $vehicle->addProperty($relationsProperty); + + $this->classMap[$vehicle->name()] = $vehicle; + + $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); + $myEnumClass = new Class_('MyEnum', $myEnum); + $this->classMap[$myEnumClass->name()] = $myEnumClass; + + $this->generator = new DoctrineMongoDBAttributeGenerator( + new PhpTypeConverter(), + new NullLogger(), + InflectorFactory::create()->build(), + [], + [], + ['id' => ['generationStrategy' => 'auto', 'writable' => true]], + $this->classMap + ); + } + + public function testGenerateClassAttributes(): void + { + $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); + $this->assertSame([['MongoDB\MappedSuperclass' => []]], $this->generator->generateClassAttributes($this->classMap['Product'])); + $this->assertSame([['MongoDB\Document' => []]], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); + } + + public function testGenerateFieldAttributes(): void + { + $this->assertSame( + [['MongoDB\Id' => ['strategy' => 'INCREMENT']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('id'), 'Vehicle') + ); + $this->assertSame( + [['MongoDB\Field' => ['type' => 'simple_array']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('enum'), 'Vehicle') + ); + $this->assertSame( + [['MongoDB\Field' => ['type' => 'collection']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('collection'), 'Vehicle') + ); + $this->assertSame( + [['MongoDB\Field' => ['type' => 'integer']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') + ); + $this->assertSame( + [['MongoDB\ReferenceOne' => ['targetDocument' => 'Person', 'simple' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation'), 'Vehicle') + ); + $this->assertSame( + [['MongoDB\ReferenceMany' => ['targetDocument' => 'Person', 'simple' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relations'), 'Vehicle') + ); + } +} diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php new file mode 100644 index 00000000..da7d2c8c --- /dev/null +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -0,0 +1,189 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\TypesGenerator; +use Doctrine\Inflector\InflectorFactory; +use EasyRdf\Graph; +use EasyRdf\Resource; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +/** + * @author Erik Saunier + */ +class DoctrineOrmAttributeGeneratorTest extends TestCase +{ + private DoctrineOrmAttributeGenerator $generator; + + private array $classMap = []; + + protected function setUp(): void + { + $graph = new Graph(); + + $product = new Class_('Product', new Resource('https://schema.org/Product', $graph)); + $product->setIsAbstract(true); + $this->classMap[$product->name()] = $product; + + $vehicle = new Class_('Vehicle', new Resource('htts://schema.org/Vehicle', $graph)); + $idProperty = new Property('id'); + $idProperty->rangeName = 'identifier'; + $idProperty->range = new Resource('https://schema.org/identifier'); + $idProperty->isId = true; + $vehicle->addProperty($idProperty); + $enumProperty = new Property('enum'); + $enumProperty->rangeName = 'Thing'; + $enumProperty->range = new Resource('https://schema.org/Thing'); + $enumProperty->isEnum = true; + $enumProperty->isArray = true; + $vehicle->addProperty($enumProperty); + $collectionProperty = new Property('collection'); + $collectionProperty->rangeName = 'Thing'; + $collectionProperty->range = new Resource('https://schema.org/Thing'); + $collectionProperty->isArray = true; + $vehicle->addProperty($collectionProperty); + $weightProperty = new Property('weight'); + $weightProperty->rangeName = 'nonPositiveInteger'; + $weightProperty->range = new Resource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); + $vehicle->addProperty($weightProperty); + $prefixedWeightProperty = new Property('prefixedWeight'); + $prefixedWeightProperty->columnPrefix = 'weight_'; + $prefixedWeightProperty->isEmbedded = true; + $prefixedWeightProperty->rangeName = 'QuantitativeValue'; + $prefixedWeightProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $vehicle->addProperty($prefixedWeightProperty); + $relation01Property = new Property('relation0_1'); + $relation01Property->rangeName = 'QuantitativeValue'; + $relation01Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relation01Property->cardinality = CardinalitiesExtractor::CARDINALITY_0_1; + $vehicle->addProperty($relation01Property); + $relation11Property = new Property('relation1_1'); + $relation11Property->rangeName = 'QuantitativeValue'; + $relation11Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relation11Property->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $vehicle->addProperty($relation11Property); + $relationN0Property = new Property('relationN_0'); + $relationN0Property->rangeName = 'QuantitativeValue'; + $relationN0Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relationN0Property->cardinality = CardinalitiesExtractor::CARDINALITY_N_0; + $vehicle->addProperty($relationN0Property); + $relationN1Property = new Property('relationN_1'); + $relationN1Property->rangeName = 'QuantitativeValue'; + $relationN1Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relationN1Property->cardinality = CardinalitiesExtractor::CARDINALITY_N_1; + $vehicle->addProperty($relationN1Property); + $relation0NProperty = new Property('relation0_N'); + $relation0NProperty->rangeName = 'QuantitativeValue'; + $relation0NProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $relation0NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_0_N; + $vehicle->addProperty($relation0NProperty); + $relation1NProperty = new Property('relation1_N'); + $relation1NProperty->rangeName = 'QuantitativeValue'; + $relation1NProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $relation1NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; + $vehicle->addProperty($relation1NProperty); + $relationNNProperty = new Property('relationN_N'); + $relationNNProperty->rangeName = 'QuantitativeValue'; + $relationNNProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $relationNNProperty->cardinality = CardinalitiesExtractor::CARDINALITY_N_N; + $vehicle->addProperty($relationNNProperty); + + $this->classMap[$vehicle->name()] = $vehicle; + + $quantitativeValue = new Class_('QuantitativeValue', new Resource('https://schema.org/QuantitativeValue', $graph)); + $quantitativeValue->setEmbeddable(true); + $this->classMap[$quantitativeValue->name()] = $quantitativeValue; + + $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); + $myEnumClass = new Class_('MyEnum', $myEnum); + $this->classMap[$myEnumClass->name()] = $myEnumClass; + + $this->generator = new DoctrineOrmAttributeGenerator( + new PhpTypeConverter(), + new NullLogger(), + InflectorFactory::create()->build(), + [], + [], + ['id' => ['generationStrategy' => 'auto', 'writable' => true]], + $this->classMap + ); + } + + public function testGenerateClassAttributes(): void + { + $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); + $this->assertSame([['ORM\MappedSuperclass' => []]], $this->generator->generateClassAttributes($this->classMap['Product'])); + $this->assertSame([['ORM\Entity' => []]], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); + $this->assertSame([['ORM\Embeddable' => []]], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); + } + + public function testGenerateFieldAttributes(): void + { + $this->assertSame( + [['ORM\Id' => []], ['ORM\Column' => ['type' => 'integer']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('id'), 'Vehicle') + ); + $this->assertSame( + [['ORM\Column' => ['type' => 'simple_array', 'nullable' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('enum'), 'Vehicle') + ); + $this->assertSame( + [['ORM\Column' => ['type' => 'json', 'nullable' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('collection'), 'Vehicle') + ); + $this->assertSame( + [['ORM\Column' => ['type' => 'integer', 'nullable' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') + ); + $this->assertSame( + [['ORM\Embedded' => ['class' => 'QuantitativeValue', 'columnPrefix' => 'weight_']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('prefixedWeight'), 'Vehicle') + ); + $this->assertSame( + [['ORM\OneToOne' => ['targetEntity' => 'QuantitativeValue']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation0_1'), 'Vehicle') + ); + $this->assertSame( + [['ORM\OneToOne' => ['targetEntity' => 'QuantitativeValue']], ['ORM\JoinColumn' => ['nullable' => false]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_1'), 'Vehicle') + ); + $this->assertSame( + [['ORM\ManyToOne' => ['targetEntity' => 'QuantitativeValue']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_0'), 'Vehicle') + ); + $this->assertSame( + [['ORM\ManyToOne' => ['targetEntity' => 'QuantitativeValue']], ['ORM\JoinColumn' => ['nullable' => false]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_1'), 'Vehicle') + ); + $this->assertSame( + [['ORM\ManyToMany' => ['targetEntity' => 'QuantitativeValue']], ['ORM\InverseJoinColumn' => ['unique' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation0_N'), 'Vehicle') + ); + $this->assertSame( + [['ORM\ManyToMany' => ['targetEntity' => 'QuantitativeValue']], ['ORM\InverseJoinColumn' => ['nullable' => false, 'unique' => true]]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N'), 'Vehicle') + ); + $this->assertSame( + [['ORM\ManyToMany' => ['targetEntity' => 'QuantitativeValue']]], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle') + ); + } +} diff --git a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php new file mode 100644 index 00000000..ea5a5984 --- /dev/null +++ b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php @@ -0,0 +1,48 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use Doctrine\Inflector\InflectorFactory; +use PHPUnit\Framework\TestCase; +use Psr\Log\NullLogger; + +class SerializerGroupAttributeGeneratorTest extends TestCase +{ + private SerializerGroupsAttributeGenerator $generator; + + protected function setUp(): void + { + $this->generator = new SerializerGroupsAttributeGenerator( + new PhpTypeConverter(), + new NullLogger(), + InflectorFactory::create()->build(), + [], + [], + [], + [], + ); + } + + public function testGeneratePropertyAttributes(): void + { + $property = new Property('prop'); + $property->isId = false; + $property->groups = ['group']; + + $this->assertSame([['Groups' => [['group']]]], $this->generator->generatePropertyAttributes($property, 'Res')); + } +} diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 8c694c5f..78df65ca 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -101,8 +101,8 @@ interface: App\Model # Example: App\Model # The Resolve Target Entity Listener config file pass resolveTargetEntityConfigPath: null - # Doctrine inheritance annotations (if set, no other annotations are generated) - inheritanceAnnotations: [] + # Doctrine inheritance attributes (if set, no other attributes are generated) + inheritanceAttributes: [] # Symfony Validator Component validator: @@ -157,8 +157,8 @@ class: null 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 @@ -185,8 +185,8 @@ interface: null 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"}}' # Symfony Serialization Groups groups: [] @@ -218,12 +218,17 @@ interface: null # 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/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index ed4ef527..b62456a3 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -198,11 +198,9 @@ public function testGeneratedId(): void $person = file_get_contents("$outputDir/App/Entity/Person.php"); $this->assertStringContainsString(<<<'PHP' - /** - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] private ?int $id = null; PHP , $person); @@ -231,10 +229,8 @@ public function testNonGeneratedId(): void $person = file_get_contents("$outputDir/App/Entity/Person.php"); $this->assertStringContainsString(<<<'PHP' - /** - * @ORM\Id - * @ORM\Column(type="string") - */ + #[ORM\Id] + #[ORM\Column(type: 'string')] private string $id; PHP , $person); @@ -269,12 +265,10 @@ public function testGeneratedUuid(): void $person = file_get_contents("$outputDir/App/Entity/Person.php"); $this->assertStringContainsString(<<<'PHP' - /** - * @ORM\Id - * @ORM\GeneratedValue(strategy="UUID") - * @ORM\Column(type="guid") - * @Assert\Uuid - */ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'UUID')] + #[ORM\Column(type: 'guid')] + #[Assert\Uuid] private ?string $id = null; PHP , $person); @@ -303,11 +297,9 @@ public function testNonGeneratedUuid(): void $person = file_get_contents("$outputDir/App/Entity/Person.php"); $this->assertStringContainsString(<<<'PHP' - /** - * @ORM\Id - * @ORM\Column(type="guid") - * @Assert\Uuid - */ + #[ORM\Id] + #[ORM\Column(type: 'guid')] + #[Assert\Uuid] private string $id; PHP , $person); @@ -422,10 +414,9 @@ public function testSupersededProperties(): void * An award won by or for this item. * * @see https://schema.org/award - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/award") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/award')] private ?string $award = null; PHP , $creativeWork); diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 0b6b8a7d..fb4c783e 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -197,6 +197,8 @@ private function getConfig(string $outputDir): array return [ 'annotationGenerators' => [ ], + 'attributeGenerators' => [ + ], 'checkIsGoodRelations' => false, 'namespaces' => [ 'entity' => 'App\Entity', diff --git a/tests/config/address-book.yaml b/tests/config/address-book.yaml index 3e6bacbe..fc561527 100644 --- a/tests/config/address-book.yaml +++ b/tests/config/address-book.yaml @@ -13,15 +13,15 @@ types: gender: ~ address: { range: PostalAddress } # Custom range and custom ORM\Column content - birthDate: { range: DateTime, ormColumn: 'type="datetimetz", nullable=true, options={"comment" = "Birthdate with timezone."}' } + birthDate: { range: DateTime, ormColumn: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } telephone: ~ email: ~ jobTitle: ~ # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ brand: { relationTableName: "person_brand"} - memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} - worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} + memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof" } + worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor" } # url field is a custom one without definition, it should render error url: ~ friends: { range: "Person", cardinality: (0..*) } @@ -41,4 +41,4 @@ types: properties: name: ~ # Custom property with custom ORM\Column content - adminCode: {range: https://schema.org/Text, ormColumn: 'type="string", length=3, unique=true, nullable=false, options={"comment" = "A code for central administration."}' } + adminCode: { range: https://schema.org/Text, ormColumn: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } diff --git a/tests/config/blog.yaml b/tests/config/blog.yaml index 621bfdbd..5ddcdbbb 100644 --- a/tests/config/blog.yaml +++ b/tests/config/blog.yaml @@ -1,7 +1,8 @@ annotationGenerators: # Generators we want to use - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator +attributeGenerators: # Generators we want to use + - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator namespaces: entity: App\Entity # The default namespace for entities, following API Platform and Symfony best practices types: # The list of type to generated (a PHP entity class by type will be generated) diff --git a/tests/config/fluent-mutators.yaml b/tests/config/fluent-mutators.yaml index afd12fae..b677ea57 100644 --- a/tests/config/fluent-mutators.yaml +++ b/tests/config/fluent-mutators.yaml @@ -9,15 +9,15 @@ types: gender: ~ address: { range: PostalAddress } # Custom range and custom ORM\Column content - birthDate: { range: DateTime, ormColumn: 'type="datetimetz", nullable=true, options={"comment" = "Birthdate with timezone."}' } + birthDate: { range: DateTime, ormColumn: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } telephone: ~ email: ~ jobTitle: ~ # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ brand: { relationTableName: "person_brand"} - memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} - worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} + memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof" } + worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor" } # url field is a custom one without definition, it should render error url: ~ friends: { range: "Person", cardinality: (0..*) } @@ -35,4 +35,4 @@ types: properties: name: ~ # Custom property with custom ORM\Column content - adminCode: {range: Text, ormColumn: 'type="string", length=3, unique=true, nullable=false, options={"comment" = "A code for central administration."}' } + adminCode: { range: https://schema.org/Text, ormColumn: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } diff --git a/tests/config/mongodb/address-book.yaml b/tests/config/mongodb/address-book.yaml index 1f33240f..11d6513d 100644 --- a/tests/config/mongodb/address-book.yaml +++ b/tests/config/mongodb/address-book.yaml @@ -3,8 +3,9 @@ namespaces: entity: 'AddressBook\Document' annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineMongoDBAnnotationGenerator +attributeGenerators: + - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineMongoDBAttributeGenerator id: generationStrategy: uuid # The list of types and properties we want to use diff --git a/tests/config/mongodb/ecommerce.yaml b/tests/config/mongodb/ecommerce.yaml index ff37a3ea..a42d8a67 100644 --- a/tests/config/mongodb/ecommerce.yaml +++ b/tests/config/mongodb/ecommerce.yaml @@ -13,8 +13,9 @@ namespaces: interface: 'Dunglas\EcommerceBundle\Model' annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineMongoDBAnnotationGenerator +attributeGenerators: + - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineMongoDBAttributeGenerator author: 'Kévin Dunglas ' debug: true useInterface: true diff --git a/tests/config/public-properties.yaml b/tests/config/public-properties.yaml index 87278edb..20a34e9f 100644 --- a/tests/config/public-properties.yaml +++ b/tests/config/public-properties.yaml @@ -10,15 +10,15 @@ types: gender: ~ address: { range: PostalAddress } # Custom range and custom ORM\Column content - birthDate: { range: DateTime, ormColumn: 'type="datetimetz", nullable=true, options={"comment" = "Birthdate with timezone."}' } + birthDate: { range: DateTime, ormColumn: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } telephone: ~ email: ~ jobTitle: ~ # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ brand: { relationTableName: "person_brand"} - memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof"} - worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor"} + memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof" } + worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor" } # url field is a custom one without definition, it should render error url: ~ friends: { range: "Person", cardinality: (0..*) } @@ -36,4 +36,4 @@ types: properties: name: ~ # Custom property with custom ORM\Column content - adminCode: {range: Text, ormColumn: 'type="string", length=3, unique=true, nullable=false, options={"comment" = "A code for central administration."}' } + adminCode: { range: https://schema.org/Text, ormColumn: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } diff --git a/tests/config/vgo.yaml b/tests/config/vgo.yaml index 29bcaa5c..ed1d3922 100644 --- a/tests/config/vgo.yaml +++ b/tests/config/vgo.yaml @@ -1,12 +1,13 @@ vocabularies: - - tests/data/vgo.rdf - - uri: tests/data/schema.rdf - format: rdf + - tests/data/vgo.rdf + - uri: tests/data/schema.rdf + format: rdf annotationGenerators: - ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\DoctrineOrmAnnotationGenerator - - ApiPlatform\SchemaGenerator\AnnotationGenerator\ConstraintAnnotationGenerator +attributeGenerators: + - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator namespaces: entity: 'App\Entity' diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 759b8328..97d8042b 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -10,12 +10,13 @@ types: properties: familyName: ~ givenName: ~ - additionalName: ~ + additionalName: { groups: ['extra'] } address: { range: https://schema.org/PostalAddress } birthDate: ~ telephone: ~ - email: ~ + email: { unique: true } url: ~ + customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } PostalAddress: # Disable the generation of the class hierarchy for this type parent: false diff --git a/tests/e2e/src/App/Entity/Person.php b/tests/e2e/src/App/Entity/Person.php index c48ad787..42d7b98e 100644 --- a/tests/e2e/src/App/Entity/Person.php +++ b/tests/e2e/src/App/Entity/Person.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - declare(strict_types=1); namespace App\Entity; @@ -16,108 +7,107 @@ use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; use Doctrine\ORM\Mapping as ORM; +use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; +use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; /** * A person (alive, dead, undead, or fictional). * * @see https://schema.org/Person - * - * @ORM\Entity - * @ApiResource(iri="https://schema.org/Person") */ +#[ORM\Entity] +#[ApiResource(iri: 'https://schema.org/Person')] +#[UniqueEntity('email')] class Person { - /** - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] private ?int $id = null; /** * Family name. In the U.S., the last name of a Person. * * @see https://schema.org/familyName - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/familyName") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/familyName')] private ?string $familyName = null; /** * Given name. In the U.S., the first name of a Person. * * @see https://schema.org/givenName - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/givenName") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/givenName')] private ?string $givenName = null; /** * An additional name for a Person, can be used for a middle name. * * @see https://schema.org/additionalName - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/additionalName") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/additionalName')] + #[Groups(['extra'])] private ?string $additionalName = null; /** * Physical address of the item. * * @see https://schema.org/address - * - * @ORM\ManyToOne(targetEntity="App\Entity\PostalAddress") - * @ApiProperty(iri="https://schema.org/address") */ + #[ORM\ManyToOne(targetEntity: 'App\Entity\PostalAddress')] + #[ApiProperty(iri: 'https://schema.org/address')] private ?PostalAddress $address = null; /** * Date of birth. * * @see https://schema.org/birthDate - * - * @ORM\Column(type="date", nullable=true) - * @ApiProperty(iri="https://schema.org/birthDate") - * @Assert\Date */ + #[ORM\Column(type: 'date', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/birthDate')] + #[Assert\Type(\DateTimeInterface::class)] private ?\DateTimeInterface $birthDate = null; /** * The telephone number. * * @see https://schema.org/telephone - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/telephone") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/telephone')] private ?string $telephone = null; /** * Email address. * * @see https://schema.org/email - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/email") - * @Assert\Email */ + #[ORM\Column(type: 'text', nullable: true, unique: true)] + #[ApiProperty(iri: 'https://schema.org/email')] + #[Assert\Email] private ?string $email = null; /** * URL of the item. * * @see https://schema.org/url - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/url") - * @Assert\Url */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/url')] + #[Assert\Url] private ?string $url = null; + /** + * @see _:customColumn + */ + #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] + private ?Person $customColumn = null; + public function getId(): ?int { return $this->id; @@ -202,4 +192,14 @@ public function getUrl(): ?string { return $this->url; } + + public function setCustomColumn(?Person $customColumn): void + { + $this->customColumn = $customColumn; + } + + public function getCustomColumn(): ?Person + { + return $this->customColumn; + } } diff --git a/tests/e2e/src/App/Entity/PostalAddress.php b/tests/e2e/src/App/Entity/PostalAddress.php index 697feb97..f17cf43e 100644 --- a/tests/e2e/src/App/Entity/PostalAddress.php +++ b/tests/e2e/src/App/Entity/PostalAddress.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - declare(strict_types=1); namespace App\Entity; @@ -21,77 +12,68 @@ * The mailing address. * * @see https://schema.org/PostalAddress - * - * @ORM\Entity - * @ApiResource(iri="https://schema.org/PostalAddress") */ +#[ORM\Entity] +#[ApiResource(iri: 'https://schema.org/PostalAddress')] class PostalAddress { - /** - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] private ?int $id = null; /** * The country. For example, USA. You can also provide the two-letter \[ISO 3166-1 alpha-2 country code\](http://en.wikipedia.org/wiki/ISO\_3166-1). * * @see https://schema.org/addressCountry - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/addressCountry") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/addressCountry')] private ?string $addressCountry = null; /** * The locality in which the street address is, and which is in the region. For example, Mountain View. * * @see https://schema.org/addressLocality - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/addressLocality") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/addressLocality')] private ?string $addressLocality = null; /** * The region in which the locality is, and which is in the country. For example, California or another appropriate first-level \[Administrative division\](https://en.wikipedia.org/wiki/List\_of\_administrative\_divisions\_by\_country). * * @see https://schema.org/addressRegion - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/addressRegion") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/addressRegion')] private ?string $addressRegion = null; /** * The post office box number for PO box addresses. * * @see https://schema.org/postOfficeBoxNumber - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/postOfficeBoxNumber") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/postOfficeBoxNumber')] private ?string $postOfficeBoxNumber = null; /** * The postal code. For example, 94043. * * @see https://schema.org/postalCode - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/postalCode") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/postalCode')] private ?string $postalCode = null; /** * The street address. For example, 1600 Amphitheatre Pkwy. * * @see https://schema.org/streetAddress - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/streetAddress") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/streetAddress')] private ?string $streetAddress = null; public function getId(): ?int diff --git a/tests/e2e/src/App/Entity/Thing.php b/tests/e2e/src/App/Entity/Thing.php index 3311053a..6d37a3b1 100644 --- a/tests/e2e/src/App/Entity/Thing.php +++ b/tests/e2e/src/App/Entity/Thing.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - declare(strict_types=1); namespace App\Entity; @@ -21,27 +12,23 @@ * The most generic type of item. * * @see https://schema.org/Thing - * - * @ORM\Entity - * @ApiResource(iri="https://schema.org/Thing") */ +#[ORM\Entity] +#[ApiResource(iri: 'https://schema.org/Thing')] class Thing { - /** - * @ORM\Id - * @ORM\GeneratedValue(strategy="AUTO") - * @ORM\Column(type="integer") - */ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] private ?int $id = null; /** * The name of the item. * * @see https://schema.org/name - * - * @ORM\Column(type="text", nullable=true) - * @ApiProperty(iri="https://schema.org/name") */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/name')] private ?string $name = null; public function getId(): ?int From 35b4f9bee5a3a8522c5e758b1067b9614e584a36 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Sat, 20 Nov 2021 13:31:38 +0100 Subject: [PATCH 191/258] chore: migrate PHPUnit configuration and update badges (#352) --- README.md | 4 ++-- phpunit.xml.dist | 18 ++++++++---------- 2 files changed, 10 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 2d9ff529..21487cc9 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ `schema` is a command line tool part of [the API Platform framework](https://api-platform.com) that instantly generates a set of PHP classes from vocabularies such as (but not limited to) [Schema.org](https://schema.org) or [ActivityStreams](https://www.w3.org/TR/activitystreams-core/). -[![Build Status](https://travis-ci.org/api-platform/schema-generator.svg?branch=master)](https://travis-ci.org/api-platform/schema-generator) + +[![GitHub Actions](https://github.com/api-platform/schema-generator/workflows/CI/badge.svg?branch=master)](https://github.com/api-platform/schema-generator/actions?query=workflow%3ACI+branch%3Amaster) [![Coverage Status](https://coveralls.io/repos/github/api-platform/schema-generator/badge.svg?branch=master)](https://coveralls.io/github/api-platform/schema-generator?branch=master) -[![SensioLabsInsight](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5/mini.png)](https://insight.sensiolabs.com/projects/87ec89e6-57cd-4ac0-9ab1-d4549c5425c5) ## Documentation diff --git a/phpunit.xml.dist b/phpunit.xml.dist index edfbaf7b..d70bb68e 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,8 +1,6 @@ - - @@ -12,15 +10,15 @@ - + + + src + + + + tests - - - - src - - From 2c372193d58dea8b4b4839e02bd54e6078fc2e54 Mon Sep 17 00:00:00 2001 From: Giorgio Mapelli Date: Sat, 20 Nov 2021 15:21:54 +0100 Subject: [PATCH 192/258] feat: integrate security for the class and property (#138) --- .../ApiPlatformCoreAttributeGenerator.php | 11 +++++++++- src/Model/Class_.php | 1 + src/Model/Property.php | 1 + src/PropertyGenerator/PropertyGenerator.php | 1 + src/TypesGenerator.php | 1 + src/TypesGeneratorConfiguration.php | 2 ++ .../ApiPlatformCoreAttributeGeneratorTest.php | 20 +++++++++++++++++-- tests/Command/DumpConfigurationTest.php | 6 ++++++ tests/e2e/schema.yml | 3 ++- tests/e2e/src/App/Entity/Person.php | 4 ++-- 10 files changed, 44 insertions(+), 6 deletions(-) diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index bfdabc0f..d761187d 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -44,6 +44,9 @@ public function generateClassAttributes(Class_ $class): array $arguments['shortName'] = $localName; } $arguments['iri'] = $class->resourceUri(); + if ($class->security) { + $arguments['security'] = $class->security; + } if ([] !== $class->operations()) { $operations = $this->validateClassOperations($class->operations()); @@ -106,7 +109,13 @@ function (Options $options, $value) { */ public function generatePropertyAttributes(Property $property, string $className): array { - return $property->isCustom ? [] : [['ApiProperty' => ['iri' => $property->resourceUri()]]]; + $arguments['iri'] = $property->resourceUri(); + + if ($property->security) { + $arguments['security'] = $property->security; + } + + return $property->isCustom ? [] : [['ApiProperty' => $arguments]]; } /** diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 3622d942..0449a59d 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -42,6 +42,7 @@ final class Class_ /** @var bool|string|null */ private $parent; private RdfResource $resource; + public ?string $security = null; private const SCHEMA_ORG_ENUMERATION = 'https://schema.org/Enumeration'; diff --git a/src/Model/Property.php b/src/Model/Property.php index d5c1b69e..61707917 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -42,6 +42,7 @@ final class Property public bool $isEnum = false; public ?string $adderRemoverTypeHint = null; public array $groups = []; + public ?string $security = null; /** @var array[] */ private array $attributes = []; private array $annotations = []; diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index 8792126d..7f45fcca 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -145,6 +145,7 @@ public function __invoke(array $config, Class_ $class, RdfResource $type, array $schemaGeneratorProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; $schemaGeneratorProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; $schemaGeneratorProperty->groups = $propertyConfig['groups'] ?? []; + $schemaGeneratorProperty->security = $propertyConfig['security'] ?? null; $schemaGeneratorProperty->isId = false; $class->addProperty($schemaGeneratorProperty); diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index b4601336..ea4c519d 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -143,6 +143,7 @@ public function generate(array $config): void $typeConfig = $config['types'][$typeName] ?? null; $parent = $typeConfig['parent'] ?? null; $class = new Class_($typeName, $type, $parent); + $class->security = $typeConfig['security'] ?? null; if ($class->isEnum()) { $class = (new EnumClassMutator( diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 4f021c79..a833cc8d 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -169,6 +169,7 @@ static function ($rdf) { ->end() ->scalarNode('parent')->defaultFalse()->info('The parent class, set to false for a top level class')->end() ->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end() + ->scalarNode('security')->defaultNull()->info('Security directive for the class')->end() ->booleanNode('allProperties')->defaultFalse()->info('Import all existing properties')->end() ->arrayNode('properties') ->info('Properties of this type to use') @@ -194,6 +195,7 @@ static function ($rdf) { ->example('{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}') ->prototype('variable')->end() ->end() + ->scalarNode('security')->defaultNull()->info('Security directive for the property')->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') ->prototype('scalar')->end() diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index dba091be..df54930c 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -68,14 +68,30 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'abstract' => [(new Class_('Abstract', new Resource('https://schema.org/Abstract')))->setIsAbstract(true), []]; yield 'with short name' => [(new Class_('WithShortName', new Resource('https://schema.org/DifferentLocalName'))), [['ApiResource' => ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName']]]]; + + $class = new Class_('WithSecurity', new Resource('https://schema.org/WithSecurity')); + $class->security = "is_granted('ROLE_USER')"; + yield 'with security' => [$class, [['ApiResource' => ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"]]]]; + } + + /** + * @dataProvider provideGeneratePropertyAttributesCases + */ + public function testGeneratePropertyAttributes(Property $property, array $attributes): void + { + $this->assertSame($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); } - public function testGeneratePropertyAttributes(): void + public function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); $property->resource = new Resource('https://schema.org/prop'); + yield 'classical' => [$property, [['ApiProperty' => ['iri' => 'https://schema.org/prop']]]]; - $this->assertSame([['ApiProperty' => ['iri' => 'https://schema.org/prop']]], $this->generator->generatePropertyAttributes($property, 'Res')); + $property = new Property('WithSecurity'); + $property->resource = new Resource('https://schema.org/WithSecurity'); + $property->security = "is_granted('ROLE_ADMIN')"; + yield 'with security' => [$property, [['ApiProperty' => ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_ADMIN')"]]]]; } public function testGenerateCustomPropertyAttributes(): void diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 78df65ca..04fa6579 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -166,6 +166,9 @@ interface: null # If declaring a custom class, this will be the class from which properties type will be guessed guessFrom: Thing + # Security directive for the class + security: null + # Import all existing properties allProperties: false @@ -188,6 +191,9 @@ interface: null # 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: [] diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 97d8042b..bd6e9e4a 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -7,6 +7,7 @@ types: properties: name: ~ Person: + security: "is_granted('ROLE_USER')" properties: familyName: ~ givenName: ~ @@ -14,7 +15,7 @@ types: address: { range: https://schema.org/PostalAddress } birthDate: ~ telephone: ~ - email: { unique: true } + email: { unique: true, security: "is_granted('ROLE_ADMIN')" } url: ~ customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } PostalAddress: diff --git a/tests/e2e/src/App/Entity/Person.php b/tests/e2e/src/App/Entity/Person.php index 42d7b98e..88f2e942 100644 --- a/tests/e2e/src/App/Entity/Person.php +++ b/tests/e2e/src/App/Entity/Person.php @@ -17,7 +17,7 @@ * @see https://schema.org/Person */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Person')] +#[ApiResource(iri: 'https://schema.org/Person', security: 'is_granted(\'ROLE_USER\')')] #[UniqueEntity('email')] class Person { @@ -88,7 +88,7 @@ class Person * @see https://schema.org/email */ #[ORM\Column(type: 'text', nullable: true, unique: true)] - #[ApiProperty(iri: 'https://schema.org/email')] + #[ApiProperty(iri: 'https://schema.org/email', security: 'is_granted(\'ROLE_ADMIN\')')] #[Assert\Email] private ?string $email = null; From 55ff403272d5aeda701e76279871b12a14127dca Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Sat, 20 Nov 2021 15:33:46 +0100 Subject: [PATCH 193/258] fix: defining operations was not working anymore (#353) --- .../ApiPlatformCoreAttributeGenerator.php | 31 ++----------------- src/Model/Class_.php | 14 +-------- src/TypesGenerator.php | 1 + src/TypesGeneratorConfiguration.php | 4 +++ .../ApiPlatformCoreAttributeGeneratorTest.php | 4 +-- tests/Command/DumpConfigurationTest.php | 3 ++ tests/e2e/schema.yml | 10 ++++++ tests/e2e/src/App/Entity/Person.php | 7 ++++- 8 files changed, 29 insertions(+), 45 deletions(-) diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index d761187d..361a6c9e 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -17,8 +17,6 @@ use ApiPlatform\Core\Annotation\ApiResource; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; -use Symfony\Component\OptionsResolver\Exception\InvalidOptionsException; -use Symfony\Component\OptionsResolver\Options; use Symfony\Component\OptionsResolver\OptionsResolver; /** @@ -48,12 +46,11 @@ public function generateClassAttributes(Class_ $class): array $arguments['security'] = $class->security; } - if ([] !== $class->operations()) { - $operations = $this->validateClassOperations($class->operations()); + if ($class->operations) { + $operations = $this->validateClassOperations($class->operations); foreach ($operations as $operationTarget => $targetOperations) { $targetArguments = []; foreach ($targetOperations as $method => $methodConfig) { - $methodConfig = $this->validateClassOperationMethodConfig($methodConfig); $methodArguments = []; foreach ($methodConfig as $key => $value) { $methodArguments[$key] = $value; @@ -80,30 +77,6 @@ private function validateClassOperations(array $operations): array return $resolver->resolve($operations); } - /** - * Validates the individual method config for an item/collection operation attribute. - */ - private function validateClassOperationMethodConfig(array $methodConfig): array - { - $resolver = new OptionsResolver(); - - $resolver->setDefined(['method', 'route_name']); - $resolver->setAllowedTypes('method', 'string'); - $resolver->setAllowedTypes('route_name', 'string'); - $resolver->setNormalizer( - 'route_name', - function (Options $options, $value) { - if (isset($options['method'])) { - throw new InvalidOptionsException('You must provide only \'method\' or \'route_name\', but not both'); - } - - return $value; - } - ); - - return $resolver->resolve($methodConfig); - } - /** * {@inheritdoc} */ diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 0449a59d..be7b8e79 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -33,7 +33,6 @@ final class Class_ /** @var array[] */ private array $attributes = []; private array $annotations = []; - private array $operations = []; private bool $hasConstructor = false; private bool $parentHasConstructor = false; private bool $isAbstract = false; @@ -43,6 +42,7 @@ final class Class_ private $parent; private RdfResource $resource; public ?string $security = null; + public array $operations = []; private const SCHEMA_ORG_ENUMERATION = 'https://schema.org/Enumeration'; @@ -174,18 +174,6 @@ public function constants(): array return $this->constants; } - public function operations(): array - { - return $this->operations; - } - - public function setOperations(array $operations): self - { - $this->operations = $operations; - - return $this; - } - public function resource(): RdfResource { return $this->resource; diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index ea4c519d..c9237f52 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -143,6 +143,7 @@ public function generate(array $config): void $typeConfig = $config['types'][$typeName] ?? null; $parent = $typeConfig['parent'] ?? null; $class = new Class_($typeName, $type, $parent); + $class->operations = $typeConfig['operations'] ?? []; $class->security = $typeConfig['security'] ?? null; if ($class->isEnum()) { diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index a833cc8d..bdcf91de 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -169,6 +169,10 @@ static function ($rdf) { ->end() ->scalarNode('parent')->defaultFalse()->info('The parent class, set to false for a top level class')->end() ->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end() + ->arrayNode('operations') + ->info('Operations for the class') + ->prototype('variable')->end() + ->end() ->scalarNode('security')->defaultNull()->info('Security directive for the class')->end() ->booleanNode('allProperties')->defaultFalse()->info('Import all existing properties')->end() ->arrayNode('properties') diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index df54930c..550c95f1 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -59,10 +59,10 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'classical' => [new Class_('Res', new Resource('https://schema.org/Res')), [['ApiResource' => ['iri' => 'https://schema.org/Res']]]]; $class = new Class_('WithOperations', new Resource('https://schema.org/WithOperations')); - $class->setOperations([ + $class->operations = [ 'item' => ['get' => ['route_name' => 'api_about_get']], 'collection' => [], - ]); + ]; yield 'with operations' => [$class, [['ApiResource' => ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []]]]]; yield 'abstract' => [(new Class_('Abstract', new Resource('https://schema.org/Abstract')))->setIsAbstract(true), []]; diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 04fa6579..965e6924 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -166,6 +166,9 @@ interface: null # If declaring a custom class, this will be the class from which properties type will be guessed guessFrom: Thing + # Operations for the class + operations: [] + # Security directive for the class security: null diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index bd6e9e4a..168ab15d 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -7,6 +7,16 @@ types: properties: name: ~ Person: + operations: + item: + get: + method: GET + delete: + method: DELETE + security: "is_granted('ROLE_ADMIN')" + collection: + get: + route_name: get_person_collection security: "is_granted('ROLE_USER')" properties: familyName: ~ diff --git a/tests/e2e/src/App/Entity/Person.php b/tests/e2e/src/App/Entity/Person.php index 88f2e942..454e6a6a 100644 --- a/tests/e2e/src/App/Entity/Person.php +++ b/tests/e2e/src/App/Entity/Person.php @@ -17,7 +17,12 @@ * @see https://schema.org/Person */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Person', security: 'is_granted(\'ROLE_USER\')')] +#[ApiResource( + iri: 'https://schema.org/Person', + security: 'is_granted(\'ROLE_USER\')', + itemOperations: ['get' => ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], + collectionOperations: ['get' => ['route_name' => 'get_person_collection']] +)] #[UniqueEntity('email')] class Person { From 93b49001a77635ce5f28af6dbf3cacc35f88b6da Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Sun, 21 Nov 2021 18:12:23 +0100 Subject: [PATCH 194/258] chore: improve codebase (#354) PHPStan to level 8 Uniformize models Update dependencies --- composer.json | 9 +- composer.lock | 1860 ++++++++++------- phpstan.neon | 64 +- .../AbstractAnnotationGenerator.php | 14 +- .../AnnotationGeneratorInterface.php | 24 +- .../PhpDocAnnotationGenerator.php | 8 +- .../AbstractAttributeGenerator.php | 14 +- .../ApiPlatformCoreAttributeGenerator.php | 16 +- .../AttributeGeneratorInterface.php | 8 +- .../ConstraintAttributeGenerator.php | 30 +- .../DoctrineMongoDBAttributeGenerator.php | 55 +- .../DoctrineOrmAttributeGenerator.php | 101 +- .../SerializerGroupsAttributeGenerator.php | 8 +- src/CardinalitiesExtractor.php | 13 +- src/ClassMutator/AnnotationsAppender.php | 19 +- src/ClassMutator/AttributeAppender.php | 16 +- src/ClassMutator/ClassIdAppender.php | 10 +- src/ClassMutator/ClassInterfaceMutator.php | 4 +- src/ClassMutator/ClassParentMutator.php | 11 +- src/ClassMutator/ClassPropertiesAppender.php | 29 +- .../ClassPropertiesTypehintMutator.php | 8 +- src/ClassMutator/EnumClassMutator.php | 13 +- src/Command/ExtractCardinalitiesCommand.php | 4 +- src/Command/GenerateCommand.php | 43 +- src/GoodRelationsBridge.php | 13 +- src/Model/Attribute.php | 44 + src/Model/Class_.php | 260 +-- src/Model/Interface_.php | 1 + src/Model/Property.php | 48 +- src/Model/Use_.php | 37 + src/PhpTypeConverter.php | 14 +- src/PhpTypeConverterInterface.php | 8 +- src/Printer.php | 2 + src/PropertyGenerator/PropertyGenerator.php | 38 +- src/TypesGenerator.php | 51 +- src/TypesGeneratorConfiguration.php | 4 +- .../PhpDocAnnotationGeneratorTest.php | 12 +- .../ApiPlatformCoreAttributeGeneratorTest.php | 40 +- .../ConstraintAttributeGeneratorTest.php | 44 +- .../DoctrineMongoDBAttributeGeneratorTest.php | 63 +- .../DoctrineOrmAttributeGeneratorTest.php | 105 +- .../SerializerGroupAttributeGeneratorTest.php | 3 +- tests/Command/DumpConfigurationTest.php | 4 +- tests/Model/ClassTest.php | 34 +- tests/TypesGeneratorTest.php | 70 +- tests/config/address-book.yaml | 4 - tests/config/ecommerce.yaml | 7 +- tests/config/enum.yaml | 1 - tests/config/fluent-mutators.yaml | 1 - tests/config/mongodb/address-book.yaml | 4 - tests/config/mongodb/ecommerce.yaml | 7 +- tests/config/public-properties.yaml | 1 - tests/e2e/schema.yml | 2 - 53 files changed, 1918 insertions(+), 1385 deletions(-) create mode 100644 src/Model/Attribute.php create mode 100644 src/Model/Use_.php diff --git a/composer.json b/composer.json index 427e5948..12a376ff 100644 --- a/composer.json +++ b/composer.json @@ -35,14 +35,14 @@ "doctrine/inflector": "^1.4.3 || ^2.0", "easyrdf/easyrdf": "^1.1", "friendsofphp/php-cs-fixer": "^2.15 || ^3.0", - "league/html-to-markdown": "^4.9", + "league/html-to-markdown": "^5.0", "psr/log": "^1.0", "symfony/config": "^5.2", "symfony/console": "^5.2", "symfony/yaml": "^5.2", "symfony/filesystem": "^5.2", "twig/twig": "^3.0", - "nette/php-generator": "3.6" + "nette/php-generator": "^3.6" }, "require-dev": { "api-platform/core": "^2.5", @@ -53,10 +53,9 @@ "symfony/serializer": "^5.2", "symfony/validator": "^5.2", "phpspec/prophecy-phpunit": "^2.0", - "phpstan/phpstan": "^0.12" + "phpstan/phpstan": "^1.2.0" }, "bin": [ "bin/schema" - ], - "minimum-stability": "dev" + ] } diff --git a/composer.lock b/composer.lock index 85032a9a..3c39903b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "14c6983fc20f52961ccc10437f2fc46d", + "content-hash": "2a748e8ceaccc7ceb34d59ecfc529707", "packages": [ { "name": "composer/semver", - "version": "dev-main", + "version": "3.2.6", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "dd61cb4efbd0cff1700b217faf24ce596af4fc4e" + "reference": "83e511e247de329283478496f7a1e114c9517506" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/dd61cb4efbd0cff1700b217faf24ce596af4fc4e", - "reference": "dd61cb4efbd0cff1700b217faf24ce596af4fc4e", + "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", + "reference": "83e511e247de329283478496f7a1e114c9517506", "shasum": "" }, "require": { @@ -66,6 +66,11 @@ "validation", "versioning" ], + "support": { + "irc": "irc://irc.freenode.org/composer", + "issues": "https://github.com/composer/semver/issues", + "source": "https://github.com/composer/semver/tree/3.2.6" + }, "funding": [ { "url": "https://packagist.com/", @@ -80,7 +85,7 @@ "type": "tidelift" } ], - "time": "2020-12-10T07:55:43+00:00" + "time": "2021-10-25T11:34:17+00:00" }, { "name": "composer/xdebug-handler", @@ -148,28 +153,30 @@ }, { "name": "doctrine/annotations", - "version": "1.12.x-dev", + "version": "1.13.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" + "reference": "5b668aef16090008790395c02c893b1ba13f7e08" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", - "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", + "reference": "5b668aef16090008790395c02c893b1ba13f7e08", "shasum": "" }, "require": { "doctrine/lexer": "1.*", "ext-tokenizer": "*", - "php": "^7.1 || ^8.0" + "php": "^7.1 || ^8.0", + "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "1.*", + "doctrine/cache": "^1.11 || ^2.0", "doctrine/coding-standard": "^6.0 || ^8.1", "phpstan/phpstan": "^0.12.20", - "phpunit/phpunit": "^7.5 || ^9.1.5" + "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", + "symfony/cache": "^4.4 || ^5.2" }, "type": "library", "autoload": { @@ -210,38 +217,38 @@ "docblock", "parser" ], - "time": "2021-02-21T21:00:45+00:00" + "support": { + "issues": "https://github.com/doctrine/annotations/issues", + "source": "https://github.com/doctrine/annotations/tree/1.13.2" + }, + "time": "2021-08-05T19:00:23+00:00" }, { "name": "doctrine/inflector", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210" + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/9cf661f4eb38f7c881cac67c75ea9b00bf97b210", - "reference": "9cf661f4eb38f7c881cac67c75ea9b00bf97b210", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^7.0", - "phpstan/phpstan": "^0.11", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-strict-rules": "^0.11", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "doctrine/coding-standard": "^8.2", + "phpstan/phpstan": "^0.12", + "phpstan/phpstan-phpunit": "^0.12", + "phpstan/phpstan-strict-rules": "^0.12", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", + "vimeo/psalm": "^4.10" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Inflector\\": "lib/Doctrine/Inflector" @@ -287,6 +294,10 @@ "uppercase", "words" ], + "support": { + "issues": "https://github.com/doctrine/inflector/issues", + "source": "https://github.com/doctrine/inflector/tree/2.0.4" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -301,31 +312,36 @@ "type": "tidelift" } ], - "time": "2020-05-29T15:13:26+00:00" + "time": "2021-10-22T20:16:43+00:00" }, { "name": "doctrine/lexer", - "version": "1.3.x-dev", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "59bfb3b9be04237be4cd1afea9bbb58794c25ce8" + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/59bfb3b9be04237be4cd1afea9bbb58794c25ce8", - "reference": "59bfb3b9be04237be4cd1afea9bbb58794c25ce8", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", + "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", - "phpstan/phpstan": "^0.12", - "phpunit/phpunit": "^8.2 || ^9.4" + "doctrine/coding-standard": "^6.0", + "phpstan/phpstan": "^0.11.8", + "phpunit/phpunit": "^8.2" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" @@ -358,6 +374,10 @@ "parser", "php" ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/1.2.1" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -372,7 +392,7 @@ "type": "tidelift" } ], - "time": "2021-01-20T07:15:06+00:00" + "time": "2020-05-25T17:44:05+00:00" }, { "name": "easyrdf/easyrdf", @@ -442,20 +462,25 @@ "rdfa", "sparql" ], + "support": { + "forum": "http://groups.google.com/group/easyrdf/", + "issues": "http://github.com/easyrdf/easyrdf/issues", + "source": "https://github.com/easyrdf/easyrdf/tree/1.1.1" + }, "time": "2020-12-02T08:47:31+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.0.2", + "version": "v3.3.2", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "990b979379502feb7f393d6c9aa36cc9b9765f24" + "reference": "06bdbdfcd619183dd7a1a6948360f8af73b9ecec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/990b979379502feb7f393d6c9aa36cc9b9765f24", - "reference": "990b979379502feb7f393d6c9aa36cc9b9765f24", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/06bdbdfcd619183dd7a1a6948360f8af73b9ecec", + "reference": "06bdbdfcd619183dd7a1a6948360f8af73b9ecec", "shasum": "" }, "require": { @@ -464,20 +489,23 @@ "doctrine/annotations": "^1.12", "ext-json": "*", "ext-tokenizer": "*", - "php": "^7.1.3 || ^8.0", + "php": "^7.2.5 || ^8.0", "php-cs-fixer/diff": "^2.0", - "symfony/console": "^4.4.20 || ^5.1.3", - "symfony/event-dispatcher": "^4.4.20 || ^5.0", - "symfony/filesystem": "^4.4.20 || ^5.0", - "symfony/finder": "^4.4.20 || ^5.0", - "symfony/options-resolver": "^4.4.20 || ^5.0", - "symfony/polyfill-php72": "^1.22", - "symfony/process": "^4.4.20 || ^5.0", - "symfony/stopwatch": "^4.4.20 || ^5.0" + "symfony/console": "^5.1.3", + "symfony/event-dispatcher": "^5.0", + "symfony/filesystem": "^5.0", + "symfony/finder": "^5.0", + "symfony/options-resolver": "^5.0", + "symfony/polyfill-mbstring": "^1.23", + "symfony/polyfill-php72": "^1.23", + "symfony/polyfill-php80": "^1.23", + "symfony/polyfill-php81": "^1.23", + "symfony/process": "^5.0", + "symfony/stopwatch": "^5.0" }, "require-dev": { "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.4", + "keradus/cli-executor": "^1.5", "mikey179/vfsstream": "^1.6.8", "php-coveralls/php-coveralls": "^2.4.3", "php-cs-fixer/accessible-object": "^1.1", @@ -489,12 +517,11 @@ "phpunitgoodpractices/polyfill": "^1.5", "phpunitgoodpractices/traits": "^1.9.1", "symfony/phpunit-bridge": "^5.2.4", - "symfony/yaml": "^4.4.20 || ^5.0" + "symfony/yaml": "^5.0" }, "suggest": { "ext-dom": "For handling output formats in XML", - "ext-mbstring": "For handling non-UTF8 characters.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." + "ext-mbstring": "For handling non-UTF8 characters." }, "bin": [ "php-cs-fixer" @@ -522,7 +549,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.0.2" + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.3.2" }, "funding": [ { @@ -530,31 +557,34 @@ "type": "github" } ], - "time": "2021-08-04T19:28:19+00:00" + "time": "2021-11-15T18:06:47+00:00" }, { "name": "league/html-to-markdown", - "version": "4.10.0", + "version": "5.0.2", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "0868ae7a552e809e5cd8f93ba022071640408e88" + "reference": "4d0394e120dc14b0d5c52fd1755fd48656da2ec9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/0868ae7a552e809e5cd8f93ba022071640408e88", - "reference": "0868ae7a552e809e5cd8f93ba022071640408e88", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/4d0394e120dc14b0d5c52fd1755fd48656da2ec9", + "reference": "4d0394e120dc14b0d5c52fd1755fd48656da2ec9", "shasum": "" }, "require": { "ext-dom": "*", "ext-xml": "*", - "php": ">=5.3.3" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "mikehaertl/php-shellcommand": "~1.1.0", - "phpunit/phpunit": "^4.8|^5.7", - "scrutinizer/ocular": "~1.1" + "mikehaertl/php-shellcommand": "^1.1.0", + "phpstan/phpstan": "^0.12.82", + "phpunit/phpunit": "^8.5 || ^9.2", + "scrutinizer/ocular": "^1.6", + "unleashedtech/php-coding-standard": "^2.7", + "vimeo/psalm": "^4.6" }, "bin": [ "bin/html-to-markdown" @@ -562,7 +592,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.10-dev" + "dev-master": "5.1-dev" } }, "autoload": { @@ -594,6 +624,10 @@ "html", "markdown" ], + "support": { + "issues": "https://github.com/thephpleague/html-to-markdown/issues", + "source": "https://github.com/thephpleague/html-to-markdown/tree/5.0.2" + }, "funding": [ { "url": "https://www.colinodell.com/sponsor", @@ -608,24 +642,24 @@ "type": "github" }, { - "url": "https://www.patreon.com/colinodell", - "type": "patreon" + "url": "https://tidelift.com/funding/github/packagist/league/html-to-markdown", + "type": "tidelift" } ], - "time": "2020-07-01T00:34:03+00:00" + "time": "2021-11-06T05:38:26+00:00" }, { "name": "nette/php-generator", - "version": "v3.6.0", + "version": "v3.6.4", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "2f28a34203ea2e730371d913fc06ae45b6e9baaa" + "reference": "b8375ac20760c62b6816f8c2eaeabbbca305eed7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/2f28a34203ea2e730371d913fc06ae45b6e9baaa", - "reference": "2f28a34203ea2e730371d913fc06ae45b6e9baaa", + "url": "https://api.github.com/repos/nette/php-generator/zipball/b8375ac20760c62b6816f8c2eaeabbbca305eed7", + "reference": "b8375ac20760c62b6816f8c2eaeabbbca305eed7", "shasum": "" }, "require": { @@ -633,10 +667,10 @@ "php": ">=7.2 <8.2" }, "require-dev": { - "nette/tester": "^2.0", - "nikic/php-parser": "^4.4", + "nette/tester": "^2.4", + "nikic/php-parser": "^4.13", "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.3" + "tracy/tracy": "^2.8" }, "suggest": { "nikic/php-parser": "to use ClassType::withBodiesFrom() & GlobalFunction::withBodyFrom()" @@ -678,22 +712,22 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v3.6.0" + "source": "https://github.com/nette/php-generator/tree/v3.6.4" }, - "time": "2021-08-29T15:43:46+00:00" + "time": "2021-10-15T10:28:31+00:00" }, { "name": "nette/utils", - "version": "v3.2.x-dev", + "version": "v3.2.5", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "9b199305a4f3019313703fc63458396a2cffcd65" + "reference": "9cd80396ca58d7969ab44fc7afcf03624dfa526e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/9b199305a4f3019313703fc63458396a2cffcd65", - "reference": "9b199305a4f3019313703fc63458396a2cffcd65", + "url": "https://api.github.com/repos/nette/utils/zipball/9cd80396ca58d7969ab44fc7afcf03624dfa526e", + "reference": "9cd80396ca58d7969ab44fc7afcf03624dfa526e", "shasum": "" }, "require": { @@ -763,9 +797,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2" + "source": "https://github.com/nette/utils/tree/v3.2.5" }, - "time": "2021-09-24T09:44:55+00:00" + "time": "2021-09-20T10:50:11+00:00" }, { "name": "php-cs-fixer/diff", @@ -819,22 +853,71 @@ }, "time": "2020-10-14T08:32:19+00:00" }, + { + "name": "psr/cache", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" + }, { "name": "psr/container", - "version": "1.1.x-dev", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", + "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.4.0" }, "type": "library", "autoload": { @@ -861,28 +944,29 @@ "container-interop", "psr" ], - "time": "2021-03-05T17:36:06+00:00" + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/1.1.2" + }, + "time": "2021-11-05T16:50:12+00:00" }, { "name": "psr/event-dispatcher", - "version": "dev-master", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "aa4f89e91c423b516ff226c50dc83f824011c253" + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/aa4f89e91c423b516ff226c50dc83f824011c253", - "reference": "aa4f89e91c423b516ff226c50dc83f824011c253", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", "shasum": "" }, "require": { "php": ">=7.2.0" }, - "suggest": { - "fig/event-dispatcher-util": "Provides some useful PSR-14 utilities" - }, "type": "library", "extra": { "branch-alias": { @@ -901,7 +985,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], "description": "Standard interfaces for event handling.", @@ -910,20 +994,24 @@ "psr", "psr-14" ], - "time": "2021-02-08T21:15:39+00:00" + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" }, { "name": "psr/log", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + "reference": "d49695b909c3b7628b6289db5479a1c204601f11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", + "reference": "d49695b909c3b7628b6289db5479a1c204601f11", "shasum": "" }, "require": { @@ -947,7 +1035,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -957,20 +1045,23 @@ "psr", "psr-3" ], - "time": "2020-03-23T09:12:05+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/1.1.4" + }, + "time": "2021-05-03T11:20:27+00:00" }, { "name": "symfony/config", - "version": "v5.2.2", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "50e0e1314a3b2609d32b6a5a0d0fb5342494c4ab" + "reference": "ac23c2f24d5634966d665d836c3933d54347e5d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/50e0e1314a3b2609d32b6a5a0d0fb5342494c4ab", - "reference": "50e0e1314a3b2609d32b6a5a0d0fb5342494c4ab", + "url": "https://api.github.com/repos/symfony/config/zipball/ac23c2f24d5634966d665d836c3933d54347e5d4", + "reference": "ac23c2f24d5634966d665d836c3933d54347e5d4", "shasum": "" }, "require": { @@ -978,7 +1069,8 @@ "symfony/deprecation-contracts": "^2.1", "symfony/filesystem": "^4.4|^5.0", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16", + "symfony/polyfill-php81": "^1.22" }, "conflict": { "symfony/finder": "<4.4" @@ -1018,6 +1110,9 @@ ], "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/config/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1032,31 +1127,33 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:15:41+00:00" + "time": "2021-10-22T09:06:52+00:00" }, { "name": "symfony/console", - "version": "v5.2.2", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a" + "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d62ec79478b55036f65e2602e282822b8eaaff0a", - "reference": "d62ec79478b55036f65e2602e282822b8eaaff0a", + "url": "https://api.github.com/repos/symfony/console/zipball/d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", + "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2", "symfony/string": "^5.1" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -1064,10 +1161,10 @@ "symfony/process": "<4.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/event-dispatcher": "^4.4|^5.0", @@ -1112,6 +1209,9 @@ "console", "terminal" ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1126,11 +1226,11 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:15:41+00:00" + "time": "2021-10-26T09:30:15+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "dev-main", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -1176,6 +1276,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1194,23 +1297,23 @@ }, { "name": "symfony/event-dispatcher", - "version": "5.x-dev", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "36b7381b24e5dd64f561073186cfffedb2d988db" + "reference": "ce7b20d69c66a20939d8952b617506a44d102130" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/36b7381b24e5dd64f561073186cfffedb2d988db", - "reference": "36b7381b24e5dd64f561073186cfffedb2d988db", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ce7b20d69c66a20939d8952b617506a44d102130", + "reference": "ce7b20d69c66a20939d8952b617506a44d102130", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/dependency-injection": "<4.4" @@ -1220,7 +1323,7 @@ "symfony/event-dispatcher-implementation": "2.0" }, "require-dev": { - "psr/log": "~1.0", + "psr/log": "^1|^2|^3", "symfony/config": "^4.4|^5.0", "symfony/dependency-injection": "^4.4|^5.0", "symfony/error-handler": "^4.4|^5.0", @@ -1258,6 +1361,9 @@ ], "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.7" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1272,11 +1378,11 @@ "type": "tidelift" } ], - "time": "2021-03-15T18:33:21+00:00" + "time": "2021-08-04T21:20:46+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "dev-main", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", @@ -1334,6 +1440,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1352,21 +1461,22 @@ }, { "name": "symfony/filesystem", - "version": "v5.2.2", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "262d033b57c73e8b59cd6e68a45c528318b15038" + "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/262d033b57c73e8b59cd6e68a45c528318b15038", - "reference": "262d033b57c73e8b59cd6e68a45c528318b15038", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/343f4fe324383ca46792cae728a3b6e2f708fb32", + "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -1393,6 +1503,9 @@ ], "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.3.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1407,24 +1520,25 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-07-21T12:40:44+00:00" }, { "name": "symfony/finder", - "version": "5.x-dev", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "0d639a0943822626290d169965804f79400e6a04" + "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04", - "reference": "0d639a0943822626290d169965804f79400e6a04", + "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=7.2.5", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -1451,6 +1565,9 @@ ], "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/finder/tree/v5.3.7" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1465,27 +1582,27 @@ "type": "tidelift" } ], - "time": "2021-02-15T18:55:04+00:00" + "time": "2021-08-04T21:20:46+00:00" }, { "name": "symfony/options-resolver", - "version": "5.x-dev", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce" + "reference": "4b78e55b179003a42523a362cc0e8327f7a69b5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce", - "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4b78e55b179003a42523a362cc0e8327f7a69b5e", + "reference": "4b78e55b179003a42523a362cc0e8327f7a69b5e", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -1517,6 +1634,9 @@ "configuration", "options" ], + "support": { + "source": "https://github.com/symfony/options-resolver/tree/v5.3.7" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1531,20 +1651,20 @@ "type": "tidelift" } ], - "time": "2021-01-27T12:56:27+00:00" + "time": "2021-08-04T21:20:46+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "dev-main", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -1556,7 +1676,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1593,6 +1713,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1607,20 +1730,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "dev-main", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170" + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/5601e09b69f26c1828b13b6bb87cb07cddba3170", - "reference": "5601e09b69f26c1828b13b6bb87cb07cddba3170", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", "shasum": "" }, "require": { @@ -1632,7 +1755,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1671,6 +1794,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1685,20 +1811,20 @@ "type": "tidelift" } ], - "time": "2021-01-22T09:19:47+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "dev-main", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248" + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/43a0283138253ed1d48d352ab6d0bdb3f809f248", - "reference": "43a0283138253ed1d48d352ab6d0bdb3f809f248", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", "shasum": "" }, "require": { @@ -1710,7 +1836,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1752,6 +1878,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1766,20 +1895,20 @@ "type": "tidelift" } ], - "time": "2021-01-22T09:19:47+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "dev-main", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/5232de97ee3b75b0360528dae24e73db49566ab1", - "reference": "5232de97ee3b75b0360528dae24e73db49566ab1", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -1791,7 +1920,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1829,6 +1958,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1843,20 +1975,20 @@ "type": "tidelift" } ], - "time": "2021-01-22T09:19:47+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-php72", - "version": "dev-main", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", - "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", "shasum": "" }, "require": { @@ -1865,7 +1997,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1902,6 +2034,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1916,20 +2051,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-05-27T09:17:38+00:00" }, { "name": "symfony/polyfill-php73", - "version": "dev-main", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", "shasum": "" }, "require": { @@ -1938,7 +2073,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1978,6 +2113,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1992,20 +2130,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-php80", - "version": "dev-main", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "shasum": "" }, "require": { @@ -2014,7 +2152,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2058,6 +2196,88 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2021-07-28T13:41:28+00:00" + }, + { + "name": "symfony/polyfill-php81", + "version": "v1.23.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php81.git", + "reference": "e66119f3de95efc359483f810c4c3e6436279436" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", + "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.1+ features to lower PHP versions", + "homepage": "https://symfony.com/", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2072,25 +2292,25 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-05-21T13:25:03+00:00" }, { "name": "symfony/process", - "version": "5.x-dev", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "98cb8eeb72e55d4196dd1e36f1f16e7b3a9a088e" + "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/98cb8eeb72e55d4196dd1e36f1f16e7b3a9a088e", - "reference": "98cb8eeb72e55d4196dd1e36f1f16e7b3a9a088e", + "url": "https://api.github.com/repos/symfony/process/zipball/38f26c7d6ed535217ea393e05634cb0b244a1967", + "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -2117,6 +2337,9 @@ ], "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/process/tree/v5.3.7" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2131,25 +2354,25 @@ "type": "tidelift" } ], - "time": "2021-04-08T10:27:02+00:00" + "time": "2021-08-04T21:20:46+00:00" }, { "name": "symfony/service-contracts", - "version": "dev-main", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bf99754c6182a126968b1c2709d18548489f27eb" + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bf99754c6182a126968b1c2709d18548489f27eb", - "reference": "bf99754c6182a126968b1c2709d18548489f27eb", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.0" + "psr/container": "^1.1" }, "suggest": { "symfony/service-implementation": "" @@ -2157,7 +2380,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -2193,6 +2416,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2207,20 +2433,20 @@ "type": "tidelift" } ], - "time": "2021-01-27T16:27:53+00:00" + "time": "2021-04-01T10:43:52+00:00" }, { "name": "symfony/stopwatch", - "version": "5.x-dev", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "d99310c33e833def36419c284f60e8027d359678" + "reference": "b24c6a92c6db316fee69e38c80591e080e41536c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/d99310c33e833def36419c284f60e8027d359678", - "reference": "d99310c33e833def36419c284f60e8027d359678", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b24c6a92c6db316fee69e38c80591e080e41536c", + "reference": "b24c6a92c6db316fee69e38c80591e080e41536c", "shasum": "" }, "require": { @@ -2252,6 +2478,9 @@ ], "description": "Provides a way to profile code", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/stopwatch/tree/v5.3.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2266,20 +2495,20 @@ "type": "tidelift" } ], - "time": "2021-03-29T15:28:41+00:00" + "time": "2021-07-10T08:58:57+00:00" }, { "name": "symfony/string", - "version": "5.x-dev", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "01454c66c88a6bb4449dcdeb913e463e075f331b" + "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/01454c66c88a6bb4449dcdeb913e463e075f331b", - "reference": "01454c66c88a6bb4449dcdeb913e463e075f331b", + "url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", + "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", "shasum": "" }, "require": { @@ -2332,6 +2561,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2346,20 +2578,20 @@ "type": "tidelift" } ], - "time": "2021-03-17T17:12:23+00:00" + "time": "2021-10-27T18:21:46+00:00" }, { "name": "symfony/yaml", - "version": "v5.2.2", + "version": "v5.3.6", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "6bb8b36c6dea8100268512bf46e858c8eb5c545e" + "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/6bb8b36c6dea8100268512bf46e858c8eb5c545e", - "reference": "6bb8b36c6dea8100268512bf46e858c8eb5c545e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", + "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", "shasum": "" }, "require": { @@ -2404,6 +2636,9 @@ ], "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/yaml/tree/v5.3.6" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -2418,20 +2653,20 @@ "type": "tidelift" } ], - "time": "2021-01-27T10:01:46+00:00" + "time": "2021-07-29T06:20:01+00:00" }, { "name": "twig/twig", - "version": "v3.2.1", + "version": "v3.3.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "f795ca686d38530045859b0350b5352f7d63447d" + "reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/f795ca686d38530045859b0350b5352f7d63447d", - "reference": "f795ca686d38530045859b0350b5352f7d63447d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/a27fa056df8a6384316288ca8b0fa3a35fdeb569", + "reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569", "shasum": "" }, "require": { @@ -2441,12 +2676,12 @@ }, "require-dev": { "psr/container": "^1.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9" + "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "3.3-dev" } }, "autoload": { @@ -2480,6 +2715,10 @@ "keywords": [ "templating" ], + "support": { + "issues": "https://github.com/twigphp/Twig/issues", + "source": "https://github.com/twigphp/Twig/tree/v3.3.3" + }, "funding": [ { "url": "https://github.com/fabpot", @@ -2490,22 +2729,22 @@ "type": "tidelift" } ], - "time": "2021-01-05T15:40:36+00:00" + "time": "2021-09-17T08:44:23+00:00" } ], "packages-dev": [ { "name": "api-platform/core", - "version": "v2.6.4", + "version": "v2.6.6", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "be971e5d0257a8c01a824ee01cfc217ba04c3200" + "reference": "25c71b216473844cdbe5bf284ccbeeb26acd76e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/be971e5d0257a8c01a824ee01cfc217ba04c3200", - "reference": "be971e5d0257a8c01a824ee01cfc217ba04c3200", + "url": "https://api.github.com/repos/api-platform/core/zipball/25c71b216473844cdbe5bf284ccbeeb26acd76e7", + "reference": "25c71b216473844cdbe5bf284ccbeeb26acd76e7", "shasum": "" }, "require": { @@ -2524,17 +2763,19 @@ }, "conflict": { "doctrine/common": "<2.7", - "doctrine/mongodb-odm": "<2.0", + "doctrine/dbal": "<2.10", + "doctrine/mongodb-odm": "<2.2", "doctrine/persistence": "<1.3" }, "require-dev": { "behat/behat": "^3.1", "behat/mink": "^1.7", "doctrine/annotations": "^1.7", + "doctrine/cache": "^1.11", "doctrine/common": "^2.11 || ^3.0", "doctrine/data-fixtures": "^1.2.2", "doctrine/doctrine-bundle": "^1.12 || ^2.0", - "doctrine/mongodb-odm": "^2.0", + "doctrine/mongodb-odm": "^2.2", "doctrine/mongodb-odm-bundle": "^4.0", "doctrine/orm": "^2.6.4 || ^3.0", "elasticsearch/elasticsearch": "^6.0 || ^7.0", @@ -2623,7 +2864,7 @@ "authors": [ { "name": "Kévin Dunglas", - "email": "dunglas@gmail.com", + "email": "kevin@dunglas.fr", "homepage": "https://dunglas.fr/" } ], @@ -2640,26 +2881,30 @@ "rest", "swagger" ], + "support": { + "issues": "https://github.com/api-platform/core/issues", + "source": "https://github.com/api-platform/core/tree/v2.6.6" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/api-platform/core", "type": "tidelift" } ], - "time": "2021-04-12T14:53:14+00:00" + "time": "2021-09-29T19:11:04+00:00" }, { "name": "composer/package-versions-deprecated", - "version": "1.11.99.1", + "version": "1.11.99.4", "source": { "type": "git", "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6" + "reference": "b174585d1fe49ceed21928a945138948cb394600" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/7413f0b55a051e89485c5cb9f765fe24bb02a7b6", - "reference": "7413f0b55a051e89485c5cb9f765fe24bb02a7b6", + "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", + "reference": "b174585d1fe49ceed21928a945138948cb394600", "shasum": "" }, "require": { @@ -2701,6 +2946,10 @@ } ], "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", + "support": { + "issues": "https://github.com/composer/package-versions-deprecated/issues", + "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" + }, "funding": [ { "url": "https://packagist.com/", @@ -2715,28 +2964,27 @@ "type": "tidelift" } ], - "time": "2020-11-11T10:22:58+00:00" + "time": "2021-09-13T08:41:34+00:00" }, { "name": "doctrine/cache", - "version": "dev-master", + "version": "2.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "cf07cdb79d6acc6469aa2a4e88d9ae34172a67ce" + "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/cf07cdb79d6acc6469aa2a4e88d9ae34172a67ce", - "reference": "cf07cdb79d6acc6469aa2a4e88d9ae34172a67ce", + "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", + "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", "shasum": "" }, "require": { "php": "~7.1 || ^8.0" }, "conflict": { - "doctrine/common": ">2.2,<2.4", - "psr/cache": ">=3" + "doctrine/common": ">2.2,<2.4" }, "require-dev": { "alcaeus/mongo-php-adapter": "^1.1", @@ -2745,17 +2993,14 @@ "mongodb/mongodb": "^1.1", "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", "predis/predis": "~1.0", - "psr/cache": "^1.0 || ^2.0" + "psr/cache": "^1.0 || ^2.0 || ^3.0", + "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", + "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" }, "suggest": { "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" @@ -2800,6 +3045,10 @@ "redis", "xcache" ], + "support": { + "issues": "https://github.com/doctrine/cache/issues", + "source": "https://github.com/doctrine/cache/tree/2.1.1" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -2814,27 +3063,27 @@ "type": "tidelift" } ], - "time": "2021-03-01T08:49:01+00:00" + "time": "2021-07-17T14:49:29+00:00" }, { "name": "doctrine/collections", - "version": "1.7.x-dev", + "version": "1.6.8", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "436a4eb4535f141c6c52a3099016cb22ceca05b5" + "reference": "1958a744696c6bb3bb0d28db2611dc11610e78af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/436a4eb4535f141c6c52a3099016cb22ceca05b5", - "reference": "436a4eb4535f141c6c52a3099016cb22ceca05b5", + "url": "https://api.github.com/repos/doctrine/collections/zipball/1958a744696c6bb3bb0d28db2611dc11610e78af", + "reference": "1958a744696c6bb3bb0d28db2611dc11610e78af", "shasum": "" }, "require": { "php": "^7.1.3 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0 || ^8.0", + "doctrine/coding-standard": "^9.0", "phpstan/phpstan": "^0.12", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", "vimeo/psalm": "^4.2.1" @@ -2879,20 +3128,24 @@ "iterators", "php" ], - "time": "2021-02-10T21:28:26+00:00" + "support": { + "issues": "https://github.com/doctrine/collections/issues", + "source": "https://github.com/doctrine/collections/tree/1.6.8" + }, + "time": "2021-08-10T18:51:53+00:00" }, { "name": "doctrine/common", - "version": "3.1.1", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "2afde5a9844126bc311cd5f548b5475e75f800d3" + "reference": "6d970a11479275300b5144e9373ce5feacfa9b91" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/2afde5a9844126bc311cd5f548b5475e75f800d3", - "reference": "2afde5a9844126bc311cd5f548b5475e75f800d3", + "url": "https://api.github.com/repos/doctrine/common/zipball/6d970a11479275300b5144e9373ce5feacfa9b91", + "reference": "6d970a11479275300b5144e9373ce5feacfa9b91", "shasum": "" }, "require": { @@ -2905,7 +3158,8 @@ "phpstan/phpstan-phpunit": "^0.12", "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^4.0.5" + "symfony/phpunit-bridge": "^4.0.5", + "vimeo/psalm": "^4.4" }, "type": "library", "autoload": { @@ -2950,6 +3204,10 @@ "doctrine", "php" ], + "support": { + "issues": "https://github.com/doctrine/common/issues", + "source": "https://github.com/doctrine/common/tree/3.2.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -2964,36 +3222,40 @@ "type": "tidelift" } ], - "time": "2021-01-20T19:58:05+00:00" + "time": "2021-10-19T06:47:22+00:00" }, { "name": "doctrine/dbal", - "version": "2.12.1", + "version": "3.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "adce7a954a1c2f14f85e94aed90c8489af204086" + "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/adce7a954a1c2f14f85e94aed90c8489af204086", - "reference": "adce7a954a1c2f14f85e94aed90c8489af204086", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/821b4f01a36ce63ed36c090ea74767b72db367e9", + "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9", "shasum": "" }, "require": { - "doctrine/cache": "^1.0", + "composer/package-versions-deprecated": "^1.11.99", + "doctrine/cache": "^1.0|^2.0", + "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", - "ext-pdo": "*", - "php": "^7.3 || ^8" + "php": "^7.3 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.1", - "jetbrains/phpstorm-stubs": "^2019.1", - "phpstan/phpstan": "^0.12.40", - "phpunit/phpunit": "^9.4", - "psalm/plugin-phpunit": "^0.10.0", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0", - "vimeo/psalm": "^3.17.2" + "doctrine/coding-standard": "9.0.0", + "jetbrains/phpstorm-stubs": "2021.1", + "phpstan/phpstan": "1.1.1", + "phpstan/phpstan-strict-rules": "^1", + "phpunit/phpunit": "9.5.10", + "psalm/plugin-phpunit": "0.16.1", + "squizlabs/php_codesniffer": "3.6.1", + "symfony/cache": "^5.2|^6.0", + "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0", + "vimeo/psalm": "4.12.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -3002,14 +3264,9 @@ "bin/doctrine-dbal" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0.x-dev" - } - }, "autoload": { "psr-4": { - "Doctrine\\DBAL\\": "lib/Doctrine/DBAL" + "Doctrine\\DBAL\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3052,11 +3309,14 @@ "queryobject", "sasql", "sql", - "sqlanywhere", "sqlite", "sqlserver", "sqlsrv" ], + "support": { + "issues": "https://github.com/doctrine/dbal/issues", + "source": "https://github.com/doctrine/dbal/tree/3.1.4" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -3071,34 +3331,81 @@ "type": "tidelift" } ], - "time": "2020-11-14T20:26:58+00:00" + "time": "2021-11-15T16:44:33+00:00" }, { - "name": "doctrine/event-manager", - "version": "1.2.x-dev", + "name": "doctrine/deprecations", + "version": "v0.5.3", "source": { "type": "git", - "url": "https://github.com/doctrine/event-manager.git", - "reference": "eb044d4b27d552d4065fbc0548183e24815240a8" + "url": "https://github.com/doctrine/deprecations.git", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb044d4b27d552d4065fbc0548183e24815240a8", - "reference": "eb044d4b27d552d4065fbc0548183e24815240a8", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314", + "reference": "9504165960a1f83cc1480e2be1dd0a0478561314", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": "<2.9@dev" + "php": "^7.1|^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", - "phpstan/phpstan": "^0.12.58", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "doctrine/coding-standard": "^6.0|^7.0|^8.0", + "phpunit/phpunit": "^7.0|^8.0|^9.0", + "psr/log": "^1.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" }, "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v0.5.3" + }, + "time": "2021-03-21T12:59:47+00:00" + }, + { + "name": "doctrine/event-manager", + "version": "1.1.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/event-manager.git", + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", + "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/common": "<2.9@dev" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" @@ -3143,6 +3450,10 @@ "event system", "events" ], + "support": { + "issues": "https://github.com/doctrine/event-manager/issues", + "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -3157,7 +3468,7 @@ "type": "tidelift" } ], - "time": "2021-01-20T18:51:22+00:00" + "time": "2020-05-29T18:28:51+00:00" }, { "name": "doctrine/instantiator", @@ -3208,6 +3519,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -3226,53 +3541,60 @@ }, { "name": "doctrine/orm", - "version": "2.8.1", + "version": "2.10.2", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "242cf1a33df1b8bc5e1b86c3ebd01db07851c833" + "reference": "81d472f6f96b8b571cafefe8d2fef89ed9446a62" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/242cf1a33df1b8bc5e1b86c3ebd01db07851c833", - "reference": "242cf1a33df1b8bc5e1b86c3ebd01db07851c833", + "url": "https://api.github.com/repos/doctrine/orm/zipball/81d472f6f96b8b571cafefe8d2fef89ed9446a62", + "reference": "81d472f6f96b8b571cafefe8d2fef89ed9446a62", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.8", - "doctrine/annotations": "^1.11.1", - "doctrine/cache": "^1.9.1", + "doctrine/cache": "^1.12.1 || ^2.1.1", "doctrine/collections": "^1.5", - "doctrine/common": "^3.0", - "doctrine/dbal": "^2.10.0", + "doctrine/common": "^3.0.3", + "doctrine/dbal": "^2.13.1 || ^3.1.1", + "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.1", - "doctrine/inflector": "^1.4|^2.0", + "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3", "doctrine/lexer": "^1.0", - "doctrine/persistence": "^2.0", + "doctrine/persistence": "^2.2", + "ext-ctype": "*", "ext-pdo": "*", - "php": "^7.2|^8.0", - "symfony/console": "^3.0|^4.0|^5.0" + "php": "^7.1 ||^8.0", + "psr/cache": "^1 || ^2 || ^3", + "symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "symfony/polyfill-php72": "^1.23", + "symfony/polyfill-php80": "^1.15" + }, + "conflict": { + "doctrine/annotations": "<1.13 || >= 2.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", - "phpstan/phpstan": "^0.12.18", - "phpunit/phpunit": "^8.5|^9.4", - "symfony/yaml": "^3.4|^4.0|^5.0", - "vimeo/psalm": "4.1.1" + "doctrine/annotations": "^1.13", + "doctrine/coding-standard": "^9.0", + "phpbench/phpbench": "^0.16.10 || ^1.0", + "phpstan/phpstan": "0.12.99", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "squizlabs/php_codesniffer": "3.6.1", + "symfony/cache": "^4.4 || ^5.2", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", + "vimeo/psalm": "4.10.0" }, "suggest": { + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" }, "bin": [ "bin/doctrine" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.7.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\ORM\\": "lib/Doctrine/ORM" @@ -3310,41 +3632,46 @@ "database", "orm" ], - "time": "2020-12-04T19:53:07+00:00" + "support": { + "issues": "https://github.com/doctrine/orm/issues", + "source": "https://github.com/doctrine/orm/tree/2.10.2" + }, + "time": "2021-10-21T17:57:02+00:00" }, { "name": "doctrine/persistence", - "version": "2.2.x-dev", + "version": "2.2.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "d8de1720d6f526f90042d11a7c74773a0524bb3a" + "reference": "5e7bdbbfe9811c06e1f745d1c166647d5c47d6ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/d8de1720d6f526f90042d11a7c74773a0524bb3a", - "reference": "d8de1720d6f526f90042d11a7c74773a0524bb3a", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/5e7bdbbfe9811c06e1f745d1c166647d5c47d6ee", + "reference": "5e7bdbbfe9811c06e1f745d1c166647d5c47d6ee", "shasum": "" }, "require": { "doctrine/annotations": "^1.0", - "doctrine/cache": "^1.0", + "doctrine/cache": "^1.11 || ^2.0", "doctrine/collections": "^1.0", + "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", "php": "^7.1 || ^8.0", - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/cache": "^4.4|^5.0" + "psr/cache": "^1.0|^2.0|^3.0" }, "conflict": { "doctrine/common": "<2.10@dev" }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "doctrine/coding-standard": "^6.0 || ^8.0", + "doctrine/coding-standard": "^6.0 || ^9.0", "doctrine/common": "^3.0", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "0.12.84", "phpunit/phpunit": "^7.5.20 || ^8.0 || ^9.0", - "vimeo/psalm": "^4.3.1" + "symfony/cache": "^4.4|^5.0", + "vimeo/psalm": "4.7.0" }, "type": "library", "autoload": { @@ -3392,7 +3719,11 @@ "orm", "persistence" ], - "time": "2021-04-05T20:43:02+00:00" + "support": { + "issues": "https://github.com/doctrine/persistence/issues", + "source": "https://github.com/doctrine/persistence/tree/2.2.3" + }, + "time": "2021-10-25T19:59:10+00:00" }, { "name": "fig/link-util", @@ -3449,6 +3780,10 @@ "psr-13", "rest" ], + "support": { + "issues": "https://github.com/php-fig/link-util/issues", + "source": "https://github.com/php-fig/link-util/tree/1.1.2" + }, "time": "2021-02-03T23:36:04+00:00" }, { @@ -3497,6 +3832,10 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", @@ -3507,26 +3846,26 @@ }, { "name": "myclabs/php-enum", - "version": "1.7.7", + "version": "1.8.3", "source": { "type": "git", "url": "https://github.com/myclabs/php-enum.git", - "reference": "d178027d1e679832db9f38248fcc7200647dc2b7" + "reference": "b942d263c641ddb5190929ff840c68f78713e937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/d178027d1e679832db9f38248fcc7200647dc2b7", - "reference": "d178027d1e679832db9f38248fcc7200647dc2b7", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937", + "reference": "b942d263c641ddb5190929ff840c68f78713e937", "shasum": "" }, "require": { "ext-json": "*", - "php": ">=7.1" + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^7", + "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^3.8" + "vimeo/psalm": "^4.6.2" }, "type": "library", "autoload": { @@ -3549,6 +3888,10 @@ "keywords": [ "enum" ], + "support": { + "issues": "https://github.com/myclabs/php-enum/issues", + "source": "https://github.com/myclabs/php-enum/tree/1.8.3" + }, "funding": [ { "url": "https://github.com/mnapoli", @@ -3559,20 +3902,20 @@ "type": "tidelift" } ], - "time": "2020-11-14T18:14:52+00:00" + "time": "2021-07-05T08:18:36+00:00" }, { "name": "nikic/php-parser", - "version": "v4.10.4", + "version": "v4.13.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", "shasum": "" }, "require": { @@ -3611,20 +3954,24 @@ "parser", "php" ], - "time": "2020-12-20T10:01:03+00:00" + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + }, + "time": "2021-11-03T20:52:16+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { @@ -3667,20 +4014,24 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2020-06-27T14:33:11+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", - "version": "3.0.4", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "e4782611070e50613683d2b9a57730e9a3ba5451" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451", - "reference": "e4782611070e50613683d2b9a57730e9a3ba5451", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { @@ -3714,7 +4065,11 @@ } ], "description": "Library for handling version information and constraints", - "time": "2020-12-13T23:18:30+00:00" + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.0" + }, + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -3763,20 +4118,24 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { @@ -3787,7 +4146,8 @@ "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -3815,20 +4175,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-09-03T19:13:55+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { @@ -3836,7 +4200,8 @@ "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "*" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -3860,37 +4225,41 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-09-17T18:55:26+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + }, + "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", - "version": "1.12.2", + "version": "1.14.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "245710e971a030f42e08f4912863805570f23d39" + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/245710e971a030f42e08f4912863805570f23d39", - "reference": "245710e971a030f42e08f4912863805570f23d39", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.1", + "php": "^7.2 || ~8.0, <8.2", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", + "phpspec/phpspec": "^6.0 || ^7.0", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -3923,7 +4292,11 @@ "spy", "stub" ], - "time": "2020-12-19T10:15:11+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + }, + "time": "2021-09-10T09:02:12+00:00" }, { "name": "phpspec/prophecy-phpunit", @@ -3971,20 +4344,24 @@ "phpunit", "prophecy" ], + "support": { + "issues": "https://github.com/phpspec/prophecy-phpunit/issues", + "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.0.1" + }, "time": "2020-07-09T08:33:42+00:00" }, { "name": "phpstan/phpstan", - "version": "0.12.71", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d508fa3b0ecc5fc91ac70c6c7ac2862f968ba2b5" + "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d508fa3b0ecc5fc91ac70c6c7ac2862f968ba2b5", - "reference": "d508fa3b0ecc5fc91ac70c6c7ac2862f968ba2b5", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", + "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", "shasum": "" }, "require": { @@ -4000,7 +4377,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "0.12-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -4013,11 +4390,19 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.2.0" + }, "funding": [ { "url": "https://github.com/ondrejmirtes", "type": "github" }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, { "url": "https://www.patreon.com/phpstan", "type": "patreon" @@ -4027,27 +4412,27 @@ "type": "tidelift" } ], - "time": "2021-02-01T18:24:00+00:00" + "time": "2021-11-18T14:09:01+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.5", + "version": "9.2.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" + "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.10.2", + "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4094,13 +4479,17 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.9" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-11-28T06:44:49+00:00" + "time": "2021-11-19T15:21:02+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4150,6 +4539,10 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4209,6 +4602,10 @@ "keywords": [ "process" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4264,6 +4661,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4319,6 +4720,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4329,16 +4734,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.1", + "version": "9.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360" + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/e7bdf4085de85a825f4424eae52c99a1cec2f360", - "reference": "e7bdf4085de85a825f4424eae52c99a1cec2f360", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "shasum": "" }, "require": { @@ -4350,11 +4755,11 @@ "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.1", + "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-code-coverage": "^9.2.7", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -4368,7 +4773,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3", + "sebastian/type": "^2.3.4", "sebastian/version": "^3.0.2" }, "require-dev": { @@ -4414,6 +4819,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + }, "funding": [ { "url": "https://phpunit.de/donate.html", @@ -4424,53 +4833,7 @@ "type": "github" } ], - "time": "2021-01-17T07:42:25+00:00" - }, - { - "name": "psr/cache", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", - "shasum": "" - }, - "require": { - "php": ">=5.3.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "time": "2016-08-06T20:24:11+00:00" + "time": "2021-09-25T07:38:51+00:00" }, { "name": "psr/link", @@ -4519,6 +4882,9 @@ "psr-13", "rest" ], + "support": { + "source": "https://github.com/php-fig/link/tree/master" + }, "time": "2016-10-28T16:06:13+00:00" }, { @@ -4565,6 +4931,10 @@ ], "description": "Library for parsing CLI options", "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4617,6 +4987,10 @@ ], "description": "Collection of value objects that represent the PHP code units", "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4668,6 +5042,10 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4738,6 +5116,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4791,6 +5173,10 @@ ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4853,6 +5239,10 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4912,6 +5302,10 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4922,16 +5316,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -4980,31 +5374,35 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "require": { @@ -5045,13 +5443,17 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-10-26T15:55:19+00:00" + "time": "2021-06-11T13:31:12+00:00" }, { "name": "sebastian/lines-of-code", @@ -5098,6 +5500,10 @@ ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -5151,6 +5557,10 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -5202,6 +5612,10 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -5261,6 +5675,10 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -5312,6 +5730,10 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -5322,16 +5744,16 @@ }, { "name": "sebastian/type", - "version": "2.3.1", + "version": "2.3.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", "shasum": "" }, "require": { @@ -5364,13 +5786,17 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-10-26T13:18:59+00:00" + "time": "2021-06-15T12:49:02+00:00" }, { "name": "sebastian/version", @@ -5413,6 +5839,10 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -5421,187 +5851,18 @@ ], "time": "2020-09-28T06:39:44+00:00" }, - { - "name": "symfony/cache", - "version": "5.x-dev", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache.git", - "reference": "9dbbb222bff08fd081179d04bd16a0501d22f040" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache/zipball/9dbbb222bff08fd081179d04bd16a0501d22f040", - "reference": "9dbbb222bff08fd081179d04bd16a0501d22f040", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0|^2.0", - "psr/log": "^1.1", - "symfony/cache-contracts": "^1.1.7|^2", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" - }, - "conflict": { - "doctrine/dbal": "<2.10", - "symfony/dependency-injection": "<4.4", - "symfony/http-kernel": "<4.4", - "symfony/var-dumper": "<4.4" - }, - "provide": { - "psr/cache-implementation": "1.0|2.0", - "psr/simple-cache-implementation": "1.0", - "symfony/cache-implementation": "1.0|2.0" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/cache": "^1.6", - "doctrine/dbal": "^2.10|^3.0", - "predis/predis": "^1.1", - "psr/simple-cache": "^1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Cache\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an extended PSR-6, PSR-16 (and tags) implementation", - "homepage": "https://symfony.com/", - "keywords": [ - "caching", - "psr6" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-04-11T23:07:08+00:00" - }, - { - "name": "symfony/cache-contracts", - "version": "dev-main", - "source": { - "type": "git", - "url": "https://github.com/symfony/cache-contracts.git", - "reference": "c0446463729b89dd4fa62e9aeecc80287323615d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/cache-contracts/zipball/c0446463729b89dd4fa62e9aeecc80287323615d", - "reference": "c0446463729b89dd4fa62e9aeecc80287323615d", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/cache": "^1.0|^2.0|^3.0" - }, - "suggest": { - "symfony/cache-implementation": "" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.4-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Contracts\\Cache\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to caching", - "homepage": "https://symfony.com/", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-03-23T23:28:01+00:00" - }, { "name": "symfony/doctrine-bridge", - "version": "v5.2.2", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "793cfa617c55c68c492712b773e5e5262d1e97e0" + "reference": "212521017d81686bdc84a132fb5de2b03867a7e7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/793cfa617c55c68c492712b773e5e5262d1e97e0", - "reference": "793cfa617c55c68c492712b773e5e5262d1e97e0", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/212521017d81686bdc84a132fb5de2b03867a7e7", + "reference": "212521017d81686bdc84a132fb5de2b03867a7e7", "shasum": "" }, "require": { @@ -5611,11 +5872,12 @@ "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/service-contracts": "^1.1|^2" }, "conflict": { "doctrine/dbal": "<2.10", + "doctrine/orm": "<2.7.3", "phpunit/phpunit": "<5.4.3", "symfony/dependency-injection": "<4.4", "symfony/form": "<5.1", @@ -5623,13 +5885,12 @@ "symfony/messenger": "<4.4", "symfony/property-info": "<5", "symfony/security-bundle": "<5", - "symfony/security-core": "<5", + "symfony/security-core": "<5.3", "symfony/validator": "<5.2" }, "require-dev": { "composer/package-versions-deprecated": "^1.8", "doctrine/annotations": "^1.10.4", - "doctrine/cache": "~1.6", "doctrine/collections": "~1.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.10|^3.0", @@ -5645,7 +5906,7 @@ "symfony/property-access": "^4.4|^5.0", "symfony/property-info": "^5.0", "symfony/proxy-manager-bridge": "^4.4|^5.0", - "symfony/security-core": "^5.0", + "symfony/security-core": "^5.3", "symfony/stopwatch": "^4.4|^5.0", "symfony/translation": "^4.4|^5.0", "symfony/uid": "^5.1", @@ -5685,6 +5946,9 @@ ], "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/doctrine-bridge/tree/v5.3.8" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5699,26 +5963,25 @@ "type": "tidelift" } ], - "time": "2021-01-27T11:24:50+00:00" + "time": "2021-09-11T18:11:56+00:00" }, { "name": "symfony/error-handler", - "version": "5.x-dev", + "version": "v5.3.7", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "841308ee616b12ddd71da08559e5b2fa66bbaf7b" + "reference": "3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/841308ee616b12ddd71da08559e5b2fa66bbaf7b", - "reference": "841308ee616b12ddd71da08559e5b2fa66bbaf7b", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321", + "reference": "3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/log": "^1.0", - "symfony/polyfill-php80": "^1.15", + "psr/log": "^1|^2|^3", "symfony/var-dumper": "^4.4|^5.0" }, "require-dev": { @@ -5751,6 +6014,9 @@ ], "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/error-handler/tree/v5.3.7" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5765,11 +6031,11 @@ "type": "tidelift" } ], - "time": "2021-04-07T15:57:56+00:00" + "time": "2021-08-28T15:07:08+00:00" }, { "name": "symfony/http-client-contracts", - "version": "dev-main", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", @@ -5826,6 +6092,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5844,23 +6113,23 @@ }, { "name": "symfony/http-foundation", - "version": "5.x-dev", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f60c2e55bebe18bb54c11d1d91c914ddc8d80995" + "reference": "9f34f02e8a5fdc7a56bafe011cea1ce97300e54c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f60c2e55bebe18bb54c11d1d91c914ddc8d80995", - "reference": "f60c2e55bebe18bb54c11d1d91c914ddc8d80995", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9f34f02e8a5fdc7a56bafe011cea1ce97300e54c", + "reference": "9f34f02e8a5fdc7a56bafe011cea1ce97300e54c", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "require-dev": { "predis/predis": "~1.0", @@ -5896,6 +6165,9 @@ ], "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/http-foundation/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -5910,40 +6182,40 @@ "type": "tidelift" } ], - "time": "2021-04-08T10:31:48+00:00" + "time": "2021-10-11T15:41:55+00:00" }, { "name": "symfony/http-kernel", - "version": "5.x-dev", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "8778d54296280d2ce610af7b71d5d5c5c6ddf60c" + "reference": "703e4079920468e9522b72cf47fd76ce8d795e86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8778d54296280d2ce610af7b71d5d5c5c6ddf60c", - "reference": "8778d54296280d2ce610af7b71d5d5c5c6ddf60c", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/703e4079920468e9522b72cf47fd76ce8d795e86", + "reference": "703e4079920468e9522b72cf47fd76ce8d795e86", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/log": "~1.0", + "psr/log": "^1|^2", "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4|^5.0", "symfony/event-dispatcher": "^5.0", "symfony/http-client-contracts": "^1.1|^2", - "symfony/http-foundation": "^5.3", + "symfony/http-foundation": "^5.3.7", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/browser-kit": "<4.4", "symfony/cache": "<5.0", "symfony/config": "<5.0", "symfony/console": "<4.4", - "symfony/dependency-injection": "<5.1.8", + "symfony/dependency-injection": "<5.3", "symfony/doctrine-bridge": "<5.0", "symfony/form": "<5.0", "symfony/http-client": "<5.0", @@ -5955,7 +6227,7 @@ "twig/twig": "<2.13" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", @@ -5963,7 +6235,7 @@ "symfony/config": "^5.0", "symfony/console": "^4.4|^5.0", "symfony/css-selector": "^4.4|^5.0", - "symfony/dependency-injection": "^5.1.8", + "symfony/dependency-injection": "^5.3", "symfony/dom-crawler": "^4.4|^5.0", "symfony/expression-language": "^4.4|^5.0", "symfony/finder": "^4.4|^5.0", @@ -6005,6 +6277,9 @@ ], "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/http-kernel/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6019,30 +6294,30 @@ "type": "tidelift" } ], - "time": "2021-04-12T08:56:19+00:00" + "time": "2021-10-29T08:36:48+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v5.2.2", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "587f2b6bbcda8c473b91c18165958ffbb8af3c4c" + "reference": "325aaf6302501ed3673cffbd3ba88db5949de8ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/587f2b6bbcda8c473b91c18165958ffbb8af3c4c", - "reference": "587f2b6bbcda8c473b91c18165958ffbb8af3c4c", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/325aaf6302501ed3673cffbd3ba88db5949de8ae", + "reference": "325aaf6302501ed3673cffbd3ba88db5949de8ae", "shasum": "" }, "require": { - "php": ">=5.5.9" + "php": ">=7.1.3", + "symfony/deprecation-contracts": "^2.1" }, "conflict": { - "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0|<6.4,>=6.0|9.1.2" + "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1", "symfony/error-handler": "^4.4|^5.0" }, "suggest": { @@ -6085,6 +6360,9 @@ ], "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/phpunit-bridge/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6099,26 +6377,26 @@ "type": "tidelift" } ], - "time": "2021-01-25T13:54:05+00:00" + "time": "2021-10-28T19:22:18+00:00" }, { "name": "symfony/property-access", - "version": "5.x-dev", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "3a9a100a1fefd454bb0fe38de524023e8390da13" + "reference": "2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/3a9a100a1fefd454bb0fe38de524023e8390da13", - "reference": "3a9a100a1fefd454bb0fe38de524023e8390da13", + "url": "https://api.github.com/repos/symfony/property-access/zipball/2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66", + "reference": "2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/property-info": "^5.2" }, "require-dev": { @@ -6163,6 +6441,9 @@ "property path", "reflection" ], + "support": { + "source": "https://github.com/symfony/property-access/tree/v5.3.8" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6177,26 +6458,26 @@ "type": "tidelift" } ], - "time": "2021-03-09T08:10:03+00:00" + "time": "2021-09-10T11:55:24+00:00" }, { "name": "symfony/property-info", - "version": "5.x-dev", + "version": "v5.3.8", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "7bddc12761dc76ca0dbbe14c46f9c444d02ee615" + "reference": "39de5bed8c036f76ec0457ec52908e45d5497947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/7bddc12761dc76ca0dbbe14c46f9c444d02ee615", - "reference": "7bddc12761dc76ca0dbbe14c46f9c444d02ee615", + "url": "https://api.github.com/repos/symfony/property-info/zipball/39de5bed8c036f76ec0457ec52908e45d5497947", + "reference": "39de5bed8c036f76ec0457ec52908e45d5497947", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/string": "^5.1" }, "conflict": { @@ -6250,6 +6531,9 @@ "type", "validator" ], + "support": { + "source": "https://github.com/symfony/property-info/tree/v5.3.8" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6264,38 +6548,39 @@ "type": "tidelift" } ], - "time": "2021-03-15T18:33:21+00:00" + "time": "2021-09-07T07:41:40+00:00" }, { "name": "symfony/serializer", - "version": "v5.2.2", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "4218dd0902543dc454b2eac0db37044f187283d7" + "reference": "5d7f068253ac3e7c62964ebdda491b06d401059a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/4218dd0902543dc454b2eac0db37044f187283d7", - "reference": "4218dd0902543dc454b2eac0db37044f187283d7", + "url": "https://api.github.com/repos/symfony/serializer/zipball/5d7f068253ac3e7c62964ebdda491b06d401059a", + "reference": "5d7f068253ac3e7c62964ebdda491b06d401059a", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { + "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", "symfony/dependency-injection": "<4.4", "symfony/property-access": "<4.4", - "symfony/property-info": "<4.4", + "symfony/property-info": "<5.3", "symfony/yaml": "<4.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4", - "doctrine/cache": "~1.0", + "doctrine/annotations": "^1.12", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", "symfony/cache": "^4.4|^5.0", "symfony/config": "^4.4|^5.0", @@ -6307,15 +6592,14 @@ "symfony/http-kernel": "^4.4|^5.0", "symfony/mime": "^4.4|^5.0", "symfony/property-access": "^4.4.9|^5.0.9", - "symfony/property-info": "^4.4|^5.0", + "symfony/property-info": "^5.3", "symfony/uid": "^5.1", "symfony/validator": "^4.4|^5.0", + "symfony/var-dumper": "^4.4|^5.0", "symfony/var-exporter": "^4.4|^5.0", "symfony/yaml": "^4.4|^5.0" }, "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader and metadata cache.", "psr/cache-implementation": "For using the metadata cache.", "symfony/config": "For using the XML mapping loader.", "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.", @@ -6349,6 +6633,9 @@ ], "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/serializer/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6363,20 +6650,20 @@ "type": "tidelift" } ], - "time": "2021-01-27T11:32:03+00:00" + "time": "2021-09-29T17:19:25+00:00" }, { "name": "symfony/translation-contracts", - "version": "dev-main", + "version": "v2.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "3664aa20bd5f99d7e59e0eb34b7e62cf5b772a00" + "reference": "95c812666f3e91db75385749fe219c5e494c7f95" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/3664aa20bd5f99d7e59e0eb34b7e62cf5b772a00", - "reference": "3664aa20bd5f99d7e59e0eb34b7e62cf5b772a00", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", + "reference": "95c812666f3e91db75385749fe219c5e494c7f95", "shasum": "" }, "require": { @@ -6388,7 +6675,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -6424,6 +6711,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/translation-contracts/tree/v2.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6438,20 +6728,20 @@ "type": "tidelift" } ], - "time": "2021-01-27T16:29:32+00:00" + "time": "2021-03-23T23:28:01+00:00" }, { "name": "symfony/validator", - "version": "v5.2.2", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "c2c234d80dad3925247b0a3fbbcecfe676e2b551" + "reference": "a85f3ba9e1c883253fc00a2e3d111e6e82a0baf5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/c2c234d80dad3925247b0a3fbbcecfe676e2b551", - "reference": "c2c234d80dad3925247b0a3fbbcecfe676e2b551", + "url": "https://api.github.com/repos/symfony/validator/zipball/a85f3ba9e1c883253fc00a2e3d111e6e82a0baf5", + "reference": "a85f3ba9e1c883253fc00a2e3d111e6e82a0baf5", "shasum": "" }, "require": { @@ -6460,7 +6750,7 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.15", + "symfony/polyfill-php80": "^1.16", "symfony/translation-contracts": "^1.1|^2" }, "conflict": { @@ -6470,13 +6760,14 @@ "symfony/expression-language": "<5.1", "symfony/http-kernel": "<4.4", "symfony/intl": "<4.4", + "symfony/property-info": "<5.3", "symfony/translation": "<4.4", "symfony/yaml": "<4.4" }, "require-dev": { "doctrine/annotations": "^1.10.4", - "doctrine/cache": "~1.0", - "egulias/email-validator": "^2.1.10", + "doctrine/cache": "^1.0|^2.0", + "egulias/email-validator": "^2.1.10|^3", "symfony/cache": "^4.4|^5.0", "symfony/config": "^4.4|^5.0", "symfony/console": "^4.4|^5.0", @@ -6489,13 +6780,11 @@ "symfony/intl": "^4.4|^5.0", "symfony/mime": "^4.4|^5.0", "symfony/property-access": "^4.4|^5.0", - "symfony/property-info": "^4.4|^5.0", + "symfony/property-info": "^5.3", "symfony/translation": "^4.4|^5.0", "symfony/yaml": "^4.4|^5.0" }, "suggest": { - "doctrine/annotations": "For using the annotation mapping. You will also need doctrine/cache.", - "doctrine/cache": "For using the default cached annotation reader.", "egulias/email-validator": "Strict (RFC compliant) email validation", "psr/cache-implementation": "For using the mapping cache.", "symfony/config": "", @@ -6532,6 +6821,9 @@ ], "description": "Provides tools to validate values", "homepage": "https://symfony.com/", + "support": { + "source": "https://github.com/symfony/validator/tree/v5.3.10" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6546,26 +6838,26 @@ "type": "tidelift" } ], - "time": "2021-01-27T12:56:27+00:00" + "time": "2021-10-28T19:22:18+00:00" }, { "name": "symfony/var-dumper", - "version": "5.x-dev", + "version": "v5.3.10", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "aea088986fc140f7ee44e50f9b8d9595d4fadfa7" + "reference": "875432adb5f5570fff21036fd22aee244636b7d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/aea088986fc140f7ee44e50f9b8d9595d4fadfa7", - "reference": "aea088986fc140f7ee44e50f9b8d9595d4fadfa7", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/875432adb5f5570fff21036fd22aee244636b7d1", + "reference": "875432adb5f5570fff21036fd22aee244636b7d1", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "phpunit/phpunit": "<5.4.3", @@ -6617,76 +6909,9 @@ "debug", "dump" ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-04-01T10:43:52+00:00" - }, - { - "name": "symfony/var-exporter", - "version": "5.x-dev", - "source": { - "type": "git", - "url": "https://github.com/symfony/var-exporter.git", - "reference": "01184a5ab95eb9500b9b0ef3e525979e003d9c81" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/var-exporter/zipball/01184a5ab95eb9500b9b0ef3e525979e003d9c81", - "reference": "01184a5ab95eb9500b9b0ef3e525979e003d9c81", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" - }, - "require-dev": { - "symfony/var-dumper": "^4.4.9|^5.0.9" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\VarExporter\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "support": { + "source": "https://github.com/symfony/var-dumper/tree/v5.3.10" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Allows exporting any serializable PHP data structure to plain PHP code", - "homepage": "https://symfony.com/", - "keywords": [ - "clone", - "construct", - "export", - "hydrate", - "instantiate", - "serialize" - ], "funding": [ { "url": "https://symfony.com/sponsor", @@ -6701,25 +6926,26 @@ "type": "tidelift" } ], - "time": "2021-04-01T10:42:13+00:00" + "time": "2021-10-26T09:30:15+00:00" }, { "name": "symfony/web-link", - "version": "5.x-dev", + "version": "v5.3.4", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "cb6b0f0c7e3a7918821f89fe1db07280f2ddbdc0" + "reference": "0075c9949c30a61d9b9e7483686d72d261480ef1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/cb6b0f0c7e3a7918821f89fe1db07280f2ddbdc0", - "reference": "cb6b0f0c7e3a7918821f89fe1db07280f2ddbdc0", + "url": "https://api.github.com/repos/symfony/web-link/zipball/0075c9949c30a61d9b9e7483686d72d261480ef1", + "reference": "0075c9949c30a61d9b9e7483686d72d261480ef1", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/link": "^1.0" + "psr/link": "^1.0", + "symfony/polyfill-php80": "^1.16" }, "conflict": { "symfony/http-kernel": "<5.3" @@ -6770,6 +6996,9 @@ "psr13", "push" ], + "support": { + "source": "https://github.com/symfony/web-link/tree/v5.3.4" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -6784,20 +7013,20 @@ "type": "tidelift" } ], - "time": "2021-03-22T15:30:12+00:00" + "time": "2021-07-21T12:40:44+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { @@ -6824,40 +7053,49 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, "funding": [ { "url": "https://github.com/theseer", "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2021-07-28T10:34:58+00:00" }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -6879,20 +7117,24 @@ "check", "validate" ], - "time": "2020-07-08T17:02:28+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" }, { "name": "willdurand/negotiation", - "version": "dev-master", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/willdurand/Negotiation.git", - "reference": "da5e7a3e7b2ae9f56e1d57af01e83124e069d3b9" + "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/da5e7a3e7b2ae9f56e1d57af01e83124e069d3b9", - "reference": "da5e7a3e7b2ae9f56e1d57af01e83124e069d3b9", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/04e14f38d4edfcc974114a07d2777d90c98f3d9c", + "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c", "shasum": "" }, "require": { @@ -6931,11 +7173,15 @@ "header", "negotiation" ], - "time": "2021-04-12T08:32:46+00:00" + "support": { + "issues": "https://github.com/willdurand/Negotiation/issues", + "source": "https://github.com/willdurand/Negotiation/tree/3.0.0" + }, + "time": "2020-09-25T08:01:41+00:00" } ], "aliases": [], - "minimum-stability": "dev", + "minimum-stability": "stable", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, diff --git a/phpstan.neon b/phpstan.neon index 6eac8cc5..f023f010 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,7 +1,69 @@ parameters: - level: 5 + level: 8 paths: - src + typeAliases: + PropertyConfiguration: ''' + array{ + exclude: boolean, + range: ?string, + relationTableName: ?string, + cardinality: string, + ormColumn: array, + security: ?string, + groups: string[], + mappedBy: ?string, + inversedBy: ?string, + readable: boolean, + writable: boolean, + nullable: boolean, + unique: boolean, + embedded: boolean, + columnPrefix: false|string + } + ''' + TypeConfiguration: ''' + array{ + exclude: boolean, + vocabularyNamespace: ?string, + abstract: ?boolean, + embeddable: boolean, + namespaces: array{class: ?string, interface: ?string}, + doctrine: array{attributes: array}, + parent: false|string, + guessFrom: string, + operations: array>, + security: ?string, + allProperties: boolean, + properties: array + } + ''' + Configuration: ''' + array{ + vocabularies: array{uri: string, format: string}[], + vocabularyNamespace: string, + relations: string[], + debug: boolean, + id: array{generate: boolean, generationStrategy: string, writable: boolean, onClass: string}, + useInterface: boolean, + checkIsGoodRelations: boolean, + header: ?string, + namespaces: array{prefix: ?string, entity: string, enum: string, interface: string}, + doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, inheritanceAttributes: array}, + validator: array{assertType: boolean}, + author: false|string, + fieldVisibility: string, + accessorMethods: boolean, + fluentMutatorMethods: boolean, + rangeMapping: array, + allTypes: boolean, + types: array, + annotationGenerators: class-string[], + attributeGenerators: class-string[], + generatorTemplates: string[], + output: string + } + ''' inferPrivatePropertyTypeFromConstructor: true ignoreErrors: # False positive diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php index 67c6b282..8f3d6534 100644 --- a/src/AnnotationGenerator/AbstractAnnotationGenerator.php +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -18,7 +18,7 @@ use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; use Doctrine\Inflector\Inflector; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use Psr\Log\LoggerInterface; /** @@ -31,15 +31,21 @@ abstract class AbstractAnnotationGenerator implements AnnotationGeneratorInterfa protected PhpTypeConverterInterface $phpTypeConverter; protected Inflector $inflector; protected LoggerInterface $logger; - /** - * @var Graph[] - */ + /** @var RdfGraph[] */ protected array $graphs; + /** @var array */ protected array $cardinalities; + /** @var Configuration */ protected array $config; /** @var Class_[] */ protected array $classes; + /** + * @param RdfGraph[] $graphs + * @param array $cardinalities + * @param Configuration $config + * @param Class_[] $classes + */ public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes) { $this->phpTypeConverter = $phpTypeConverter; diff --git a/src/AnnotationGenerator/AnnotationGeneratorInterface.php b/src/AnnotationGenerator/AnnotationGeneratorInterface.php index dcfad1c3..43c4448c 100644 --- a/src/AnnotationGenerator/AnnotationGeneratorInterface.php +++ b/src/AnnotationGenerator/AnnotationGeneratorInterface.php @@ -16,9 +16,7 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Constant; use ApiPlatform\SchemaGenerator\Model\Property; -use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use Doctrine\Inflector\Inflector; -use Psr\Log\LoggerInterface; +use ApiPlatform\SchemaGenerator\Model\Use_; /** * Annotation Generator Interface. @@ -27,50 +25,66 @@ */ interface AnnotationGeneratorInterface { - public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes); - /** * Generates class's annotations. + * + * @return string[] */ public function generateClassAnnotations(Class_ $class): array; /** * Generates interface's annotations. + * + * @return string[] */ public function generateInterfaceAnnotations(Class_ $class): array; /** * Generates constant's annotations. + * + * @return string[] */ public function generateConstantAnnotations(Constant $constant): array; /** * Generates field's annotation. + * + * @return string[] */ public function generatePropertyAnnotations(Property $property, string $className): array; /** * Generates getter's annotation. + * + * @return string[] */ public function generateGetterAnnotations(Property $property): array; /** * Generates setter's annotation. + * + * @return string[] */ public function generateSetterAnnotations(Property $property): array; /** * Generates adder's annotation. + * + * @return string[] */ public function generateAdderAnnotations(Property $property): array; /** * Generates remover's annotation. + * + * @return string[] */ public function generateRemoverAnnotations(Property $property): array; /** * Generates uses. + * + * @return Use_[] */ public function generateUses(Class_ $class): array; } diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index b4b60acd..babf2735 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -116,7 +116,7 @@ public function generateSetterAnnotations(Property $property): array return []; } - return [sprintf('@param %s $%s', $this->toPhpDocType($property), $property->name)]; + return [sprintf('@param %s $%s', $this->toPhpDocType($property), $property->name())]; } /** @@ -143,7 +143,7 @@ public function generateRemoverAnnotations(Property $property): array return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name()))]; } - private function isDocUseful(Property $property, $adderOrRemover = false): bool + private function isDocUseful(Property $property, bool $adderOrRemover = false): bool { $typeHint = $adderOrRemover ? $property->adderRemoverTypeHint ?? false : $property->typeHint ?? false; @@ -152,6 +152,8 @@ private function isDocUseful(Property $property, $adderOrRemover = false): bool /** * Generates class or interface PHPDoc. + * + * @return string[] */ private function generateDoc(Class_ $class, bool $interface = false): array { @@ -175,6 +177,8 @@ private function generateDoc(Class_ $class, bool $interface = false): array /** * Converts HTML to Markdown and explode. + * + * @return string[] */ private function formatDoc(string $doc, bool $indent = false): array { diff --git a/src/AttributeGenerator/AbstractAttributeGenerator.php b/src/AttributeGenerator/AbstractAttributeGenerator.php index 1b25b6f2..baadd19a 100644 --- a/src/AttributeGenerator/AbstractAttributeGenerator.php +++ b/src/AttributeGenerator/AbstractAttributeGenerator.php @@ -17,7 +17,7 @@ use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; use Doctrine\Inflector\Inflector; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use Psr\Log\LoggerInterface; /** @@ -30,15 +30,21 @@ abstract class AbstractAttributeGenerator implements AttributeGeneratorInterface protected PhpTypeConverterInterface $phpTypeConverter; protected Inflector $inflector; protected LoggerInterface $logger; - /** - * @var Graph[] - */ + /** @var RdfGraph[] */ protected array $graphs; + /** @var array */ protected array $cardinalities; + /** @var Configuration */ protected array $config; /** @var Class_[] */ protected array $classes; + /** + * @param RdfGraph[] $graphs + * @param array $cardinalities + * @param Configuration $config + * @param Class_[] $classes + */ public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes) { $this->phpTypeConverter = $phpTypeConverter; diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 361a6c9e..1832cc53 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -15,8 +15,10 @@ use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; use Symfony\Component\OptionsResolver\OptionsResolver; /** @@ -33,7 +35,7 @@ final class ApiPlatformCoreAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($class->isAbstract()) { + if ($class->isAbstract) { return []; } @@ -61,11 +63,17 @@ public function generateClassAttributes(Class_ $class): array } } - return [['ApiResource' => $arguments]]; + return [new Attribute('ApiResource', $arguments)]; } /** * Verifies that the operations config is valid. + * + * @template T of array + * + * @param T $operations + * + * @return T */ private function validateClassOperations(array $operations): array { @@ -88,7 +96,7 @@ public function generatePropertyAttributes(Property $property, string $className $arguments['security'] = $property->security; } - return $property->isCustom ? [] : [['ApiProperty' => $arguments]]; + return $property->isCustom ? [] : [new Attribute('ApiProperty', $arguments)]; } /** @@ -96,6 +104,6 @@ public function generatePropertyAttributes(Property $property, string $className */ public function generateUses(Class_ $class): array { - return !$class->isEnum() ? [ApiResource::class, ApiProperty::class] : []; + return !$class->isEnum() ? [new Use_(ApiResource::class), new Use_(ApiProperty::class)] : []; } } diff --git a/src/AttributeGenerator/AttributeGeneratorInterface.php b/src/AttributeGenerator/AttributeGeneratorInterface.php index f32f2dcd..b5ae2b5d 100644 --- a/src/AttributeGenerator/AttributeGeneratorInterface.php +++ b/src/AttributeGenerator/AttributeGeneratorInterface.php @@ -13,8 +13,10 @@ namespace ApiPlatform\SchemaGenerator\AttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; /** * Attribute Generator Interface. @@ -26,19 +28,21 @@ interface AttributeGeneratorInterface /** * Generates class's attributes. * - * @return array[] + * @return Attribute[] */ public function generateClassAttributes(Class_ $class): array; /** * Generates field's attributes. * - * @return array[] + * @return Attribute[] */ public function generatePropertyAttributes(Property $property, string $className): array; /** * Generates uses. + * + * @return Use_[] */ public function generateUses(Class_ $class): array; } diff --git a/src/AttributeGenerator/ConstraintAttributeGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php index 3da2ca56..aefc9ae8 100644 --- a/src/AttributeGenerator/ConstraintAttributeGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -13,8 +13,10 @@ namespace ApiPlatform\SchemaGenerator\AttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; use Nette\PhpGenerator\Literal; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -32,7 +34,7 @@ public function generatePropertyAttributes(Property $property, string $className { if ($property->isId) { if ('uuid' === $this->config['id']['generationStrategy']) { - return [['Assert\Uuid' => []]]; + return [new Attribute('Assert\Uuid')]; } return []; @@ -43,39 +45,39 @@ public function generatePropertyAttributes(Property $property, string $className if (!$property->isArray && $property->range) { switch ($property->range->getUri()) { case 'https://schema.org/URL': - $asserts[] = ['Assert\Url' => []]; + $asserts[] = new Attribute('Assert\Url'); break; case 'https://schema.org/Date': case 'https://schema.org/DateTime': case 'https://schema.org/Time': - $asserts[] = ['Assert\Type' => [new Literal('\DateTimeInterface::class')]]; + $asserts[] = new Attribute('Assert\Type', [new Literal('\DateTimeInterface::class')]); break; } if (null !== $property->resource && 'https://schema.org/email' === $property->resourceUri()) { - $asserts[] = ['Assert\Email' => []]; + $asserts[] = new Attribute('Assert\Email'); } if (!$asserts && $this->config['validator']['assertType']) { $phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []); if (\in_array($phpType, ['bool', 'float', 'int', 'string'], true)) { - $asserts[] = ['Assert\Type' => [$phpType]]; + $asserts[] = new Attribute('Assert\Type', [$phpType]); } } } if (!$property->isNullable) { - $asserts[] = ['Assert\NotNull' => []]; + $asserts[] = new Attribute('Assert\NotNull'); } - if ($property->isEnum && $property->range) { + if ($property->isEnum && $property->range && $property->rangeName) { $args = ['callback' => [$property->rangeName, 'toArray']]; if ($property->isArray) { $args['multiple'] = true; } - $asserts[] = ['Assert\Choice' => $args]; + $asserts[] = new Attribute('Assert\Choice', $args); } return $asserts; @@ -91,15 +93,15 @@ public function generateUses(Class_ $class): array } $uses = []; - $uses[] = 'Symfony\Component\Validator\Constraints as Assert'; - $uses[] = UniqueEntity::class; + $uses[] = new Use_('Symfony\Component\Validator\Constraints', 'Assert'); + $uses[] = new Use_(UniqueEntity::class); foreach ($class->properties() as $property) { if ($property->isEnum && $property->range) { $rangeName = $property->rangeName; $enumClass = $this->classes[$rangeName]; - $enumNamespace = $enumClass->namespace() ?? $this->config['namespaces']['enum']; - $use = sprintf('%s\%s', $enumNamespace, $rangeName); + $enumNamespace = $enumClass->namespace ?? $this->config['namespaces']['enum']; + $use = new Use_(sprintf('%s\%s', $enumNamespace, $rangeName)); if (!\in_array($use, $uses, true)) { $uses[] = $use; @@ -127,9 +129,9 @@ public function generateClassAttributes(Class_ $class): array } if (1 === \count($uniqueProperties)) { - $attributes[] = ['UniqueEntity' => [$uniqueProperties[0]]]; + $attributes[] = new Attribute('UniqueEntity', [$uniqueProperties[0]]); } else { - $attributes[] = ['UniqueEntity' => ['fields' => $uniqueProperties]]; + $attributes[] = new Attribute('UniqueEntity', ['fields' => $uniqueProperties]); } return $attributes; diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index a7f4328b..c2c74ed8 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -14,8 +14,10 @@ namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; /** * Doctrine MongoDB attribute generator. @@ -29,8 +31,13 @@ final class DoctrineMongoDBAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($doctrineAttributes = ($this->config['types'][$class->name()]['doctrine']['attributes'] ?? false)) { - return $doctrineAttributes; + if ($doctrineAttributes = $this->config['types'][$class->name()]['doctrine']['attributes']) { + $attributes = []; + foreach ($doctrineAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs); + } + + return $attributes; } if ($class->isEnum()) { @@ -38,14 +45,19 @@ public function generateClassAttributes(Class_ $class): array } $attributes = []; - if ($class->isAbstract()) { - if ($inheritanceAttributes = ($this->config['doctrine']['inheritanceAttributes'] ?? [])) { - return $inheritanceAttributes; + if ($class->isAbstract) { + if ($inheritanceAttributes = ($this->config['doctrine']['inheritanceAttributes'])) { + $attributes = []; + foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs); + } + + return $attributes; } - $attributes[] = ['MongoDB\MappedSuperclass' => []]; + $attributes[] = new Attribute('MongoDB\MappedSuperclass'); } else { - $attributes[] = ['MongoDB\Document' => []]; + $attributes[] = new Attribute('MongoDB\Document'); } return $attributes; @@ -100,20 +112,20 @@ public function generatePropertyAttributes(Property $property, string $className } if (null !== $type) { - return [['MongoDB\Field' => ['type' => $type]]]; + return [new Attribute('MongoDB\Field', ['type' => $type])]; } - if (CardinalitiesExtractor::CARDINALITY_0_1 === $property->cardinality + if ((CardinalitiesExtractor::CARDINALITY_0_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_0 === $property->cardinality - || CardinalitiesExtractor::CARDINALITY_N_1 === $property->cardinality) { - return [['MongoDB\ReferenceOne' => ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true]]]; + || CardinalitiesExtractor::CARDINALITY_N_1 === $property->cardinality) && $property->rangeName) { + return [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true])]; } - if (CardinalitiesExtractor::CARDINALITY_0_N === $property->cardinality + if ((CardinalitiesExtractor::CARDINALITY_0_N === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_N === $property->cardinality - || CardinalitiesExtractor::CARDINALITY_N_N === $property->cardinality) { - return [['MongoDB\ReferenceMany' => ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true]]]; + || CardinalitiesExtractor::CARDINALITY_N_N === $property->cardinality) && $property->rangeName) { + return [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true])]; } return []; @@ -124,7 +136,7 @@ public function generatePropertyAttributes(Property $property, string $className */ public function generateUses(Class_ $class): array { - return $class->isEnum() ? [] : ['Doctrine\ODM\MongoDB\Mapping\Annotations as MongoDB']; + return $class->isEnum() ? [] : [new Use_('Doctrine\ODM\MongoDB\Mapping\Annotations', 'MongoDB')]; } /** @@ -136,21 +148,24 @@ private function getRelationName(string $rangeName): string ? $this->classes[$rangeName]->interfaceName() : $rangeName; } + /** + * @return Attribute[] + */ private function generateIdAttributes(): array { switch ($this->config['id']['generationStrategy']) { case 'uuid': if ($this->config['id']['writable']) { - return [['MongoDB\Id' => ['strategy' => 'NONE', 'type' => 'bin_uuid']]]; + return [new Attribute('MongoDB\Id', ['strategy' => 'NONE', 'type' => 'bin_uuid'])]; } - return [['MongoDB\Id' => ['strategy' => 'UUID']]]; + return [new Attribute('MongoDB\Id', ['strategy' => 'UUID'])]; case 'auto': - return [['MongoDB\Id' => ['strategy' => 'INCREMENT']]]; + return [new Attribute('MongoDB\Id', ['strategy' => 'INCREMENT'])]; case 'mongoid': - return [['MongoDB\Id' => []]]; + return [new Attribute('MongoDB\Id')]; default: - return [['MongoDB\Id' => ['strategy' => 'NONE', 'type' => 'string']]]; + return [new Attribute('MongoDB\Id', ['strategy' => 'NONE', 'type' => 'string'])]; } } } diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index bdc6e134..b58406a3 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -14,8 +14,10 @@ namespace ApiPlatform\SchemaGenerator\AttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; /** * Doctrine attribute generator. @@ -40,27 +42,37 @@ final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($doctrineAttributes = ($this->config['types'][$class->name()]['doctrine']['attributes'] ?? false)) { - return $doctrineAttributes; + if ($doctrineAttributes = $this->config['types'][$class->name()]['doctrine']['attributes']) { + $attributes = []; + foreach ($doctrineAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs); + } + + return $attributes; } if ($class->isEnum()) { return []; } - if ($class->isEmbeddable()) { - return [['ORM\Embeddable' => []]]; + if ($class->isEmbeddable) { + return [new Attribute('ORM\Embeddable')]; } $attributes = []; - if ($class->isAbstract()) { - if ($inheritanceAttributes = ($this->config['doctrine']['inheritanceAttributes'] ?? [])) { - return $inheritanceAttributes; + if ($class->isAbstract) { + if ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes']) { + $attributes = []; + foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs); + } + + return $attributes; } - $attributes[] = ['ORM\MappedSuperclass' => []]; + $attributes[] = new Attribute('ORM\MappedSuperclass'); } else { - $attributes[] = ['ORM\Entity' => []]; + $attributes[] = new Attribute('ORM\Entity'); } foreach (self::RESERVED_KEYWORDS as $keyword) { @@ -68,7 +80,7 @@ public function generateClassAttributes(Class_ $class): array continue; } - $attributes[] = ['ORM\Table' => ['name' => strtolower($class->name())]]; + $attributes[] = new Attribute('ORM\Table', ['name' => strtolower($class->name())]); return $attributes; } @@ -86,7 +98,7 @@ public function generatePropertyAttributes(Property $property, string $className } if ($property->ormColumn) { - return [['ORM\Column' => $property->ormColumn]]; + return [new Attribute('ORM\Column', $property->ormColumn)]; } if ($property->isId) { @@ -102,7 +114,7 @@ public function generatePropertyAttributes(Property $property, string $className $type = $property->isArray ? 'simple_array' : 'string'; } elseif ($property->isArray) { $type = 'json'; - } elseif (null !== $phpType = $this->phpTypeConverter->getPhpType($property, $this->config, [])) { + } elseif ($property->range && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { switch ($property->range->getUri()) { // TODO: use more precise types for int (smallint, bigint...) case 'http://www.w3.org/2001/XMLSchema#time': @@ -157,70 +169,70 @@ public function generatePropertyAttributes(Property $property, string $className } } - return [['ORM\Column' => $args]]; + return [new Attribute('ORM\Column', $args)]; } if (null === $relationName = $this->getRelationName($property->rangeName)) { - $this->logger->error('The type "{type}" of the property "{property}" from the class "{class}" doesn\'t exist', ['type' => $property->range->getUri(), 'property' => $property->name(), 'class' => $className]); + $this->logger->error('The type "{type}" of the property "{property}" from the class "{class}" doesn\'t exist', ['type' => $property->range ? $property->range->getUri() : $property->rangeName, 'property' => $property->name(), 'class' => $className]); return []; } if ($property->isEmbedded) { - return [['ORM\Embedded' => ['class' => $relationName, 'columnPrefix' => $property->columnPrefix]]]; + return [new Attribute('ORM\Embedded', ['class' => $relationName, 'columnPrefix' => $property->columnPrefix])]; } $attributes = []; switch ($property->cardinality) { case CardinalitiesExtractor::CARDINALITY_0_1: - $attributes[] = ['ORM\OneToOne' => ['targetEntity' => $relationName]]; + $attributes[] = new Attribute('ORM\OneToOne', ['targetEntity' => $relationName]); break; case CardinalitiesExtractor::CARDINALITY_1_1: - $attributes[] = ['ORM\OneToOne' => ['targetEntity' => $relationName]]; - $attributes[] = ['ORM\JoinColumn' => ['nullable' => false]]; + $attributes[] = new Attribute('ORM\OneToOne', ['targetEntity' => $relationName]); + $attributes[] = new Attribute('ORM\JoinColumn', ['nullable' => false]); break; case CardinalitiesExtractor::CARDINALITY_UNKNOWN: case CardinalitiesExtractor::CARDINALITY_N_0: if (null !== $property->inversedBy) { - $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName, 'inversedBy' => $property->inversedBy]]; + $attributes[] = new Attribute('ORM\ManyToOne', ['targetEntity' => $relationName, 'inversedBy' => $property->inversedBy]); } else { - $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName]]; + $attributes[] = new Attribute('ORM\ManyToOne', ['targetEntity' => $relationName]); } break; case CardinalitiesExtractor::CARDINALITY_N_1: if (null !== $property->inversedBy) { - $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName, 'inversedBy' => $property->inversedBy]]; + $attributes[] = new Attribute('ORM\ManyToOne', ['targetEntity' => $relationName, 'inversedBy' => $property->inversedBy]); } else { - $attributes[] = ['ORM\ManyToOne' => ['targetEntity' => $relationName]]; + $attributes[] = new Attribute('ORM\ManyToOne', ['targetEntity' => $relationName]); } - $attributes[] = ['ORM\JoinColumn' => ['nullable' => false]]; + $attributes[] = new Attribute('ORM\JoinColumn', ['nullable' => false]); break; case CardinalitiesExtractor::CARDINALITY_0_N: if (null !== $property->mappedBy) { - $attributes[] = ['ORM\OneToMany' => ['targetEntity' => $relationName, 'mappedBy' => $property->mappedBy]]; + $attributes[] = new Attribute('ORM\OneToMany', ['targetEntity' => $relationName, 'mappedBy' => $property->mappedBy]); } else { - $attributes[] = ['ORM\ManyToMany' => ['targetEntity' => $relationName]]; + $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); } if ($property->relationTableName) { - $attributes[] = ['ORM\JoinTable' => ['name' => $property->relationTableName]]; + $attributes[] = new Attribute('ORM\JoinTable', ['name' => $property->relationTableName]); } - $attributes[] = ['ORM\InverseJoinColumn' => ['unique' => true]]; + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['unique' => true]); break; case CardinalitiesExtractor::CARDINALITY_1_N: if (null !== $property->mappedBy) { - $attributes[] = ['ORM\OneToMany' => ['targetEntity' => $relationName, 'mappedBy' => $property->mappedBy]]; + $attributes[] = new Attribute('ORM\OneToMany', ['targetEntity' => $relationName, 'mappedBy' => $property->mappedBy]); } else { - $attributes[] = ['ORM\ManyToMany' => ['targetEntity' => $relationName]]; + $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); } if ($property->relationTableName) { - $attributes[] = ['ORM\JoinTable' => ['name' => $property->relationTableName]]; + $attributes[] = new Attribute('ORM\JoinTable', ['name' => $property->relationTableName]); } - $attributes[] = ['ORM\InverseJoinColumn' => ['nullable' => false, 'unique' => true]]; + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true]); break; case CardinalitiesExtractor::CARDINALITY_N_N: - $attributes[] = ['ORM\ManyToMany' => ['targetEntity' => $relationName]]; + $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); if ($property->relationTableName) { - $attributes[] = ['ORM\JoinTable' => ['name' => $property->relationTableName]]; + $attributes[] = new Attribute('ORM\JoinTable', ['name' => $property->relationTableName]); } break; } @@ -233,14 +245,17 @@ public function generatePropertyAttributes(Property $property, string $className */ public function generateUses(Class_ $class): array { - return $class->isEnum() ? [] : ['Doctrine\ORM\Mapping as ORM']; + return $class->isEnum() ? [] : [new Use_('Doctrine\ORM\Mapping', 'ORM')]; } + /** + * @return Attribute[] + */ private function generateIdAttributes(): array { - $attributes = [['ORM\Id' => []]]; + $attributes = [new Attribute('ORM\Id')]; if ('none' !== $this->config['id']['generationStrategy'] && !$this->config['id']['writable']) { - $attributes[] = ['ORM\GeneratedValue' => ['strategy' => strtoupper($this->config['id']['generationStrategy'])]]; + $attributes[] = new Attribute('ORM\GeneratedValue', ['strategy' => strtoupper($this->config['id']['generationStrategy'])]); } switch ($this->config['id']['generationStrategy']) { @@ -255,7 +270,7 @@ private function generateIdAttributes(): array break; } - $attributes[] = ['ORM\Column' => ['type' => $type]]; + $attributes[] = new Attribute('ORM\Column', ['type' => $type]); return $attributes; } @@ -276,21 +291,13 @@ private function getRelationName(string $rangeName): ?string return sprintf('%s\\%s', $this->config['types'][$class->name()]['namespaces']['interface'], $class->interfaceName()); } - if (isset($this->config['namespaces']['interface'])) { - return sprintf('%s\\%s', $this->config['namespaces']['interface'], $class->interfaceName()); - } - - return $class->interfaceName(); + return sprintf('%s\\%s', $this->config['namespaces']['interface'], $class->interfaceName()); } if (isset($this->config['types'][$rangeName]['namespaces']['class'])) { return sprintf('%s\\%s', $this->config['types'][$class->name()]['namespaces']['class'], $class->name()); } - if (isset($this->config['namespaces']['entity'])) { - return sprintf('%s\\%s', $this->config['namespaces']['entity'], $rangeName); - } - - return $rangeName; + return sprintf('%s\\%s', $this->config['namespaces']['entity'], $rangeName); } } diff --git a/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php b/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php index 4b53ac0c..aa3c4817 100644 --- a/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php +++ b/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php @@ -13,8 +13,10 @@ namespace ApiPlatform\SchemaGenerator\AttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; use Symfony\Component\Serializer\Annotation\Groups; /** @@ -32,8 +34,8 @@ final class SerializerGroupsAttributeGenerator extends AbstractAttributeGenerato */ public function generatePropertyAttributes(Property $property, string $className): array { - if (false === $property->isId && $property->groups()) { - return [['Groups' => [$property->groups()]]]; + if (false === $property->isId && $property->groups) { + return [new Attribute('Groups', [$property->groups])]; } return []; @@ -44,6 +46,6 @@ public function generatePropertyAttributes(Property $property, string $className */ public function generateUses(Class_ $class): array { - return [Groups::class]; + return [new Use_(Groups::class)]; } } diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index fd0a8d8f..b2ebc6ec 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -13,8 +13,8 @@ namespace ApiPlatform\SchemaGenerator; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; /** * Extracts cardinalities from the OWL definition, from GoodRelations or from Schema.org's comments. @@ -33,13 +33,13 @@ class CardinalitiesExtractor public const CARDINALITY_UNKNOWN = 'unknown'; /** - * @var Graph[] + * @var RdfGraph[] */ private array $graphs; private GoodRelationsBridge $goodRelationsBridge; /** - * @param Graph[] $graphs + * @param RdfGraph[] $graphs */ public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBridge) { @@ -49,6 +49,8 @@ public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBri /** * Extracts cardinality of properties. + * + * @return array */ public function extract(): array { @@ -56,6 +58,7 @@ public function extract(): array foreach ($this->graphs as $graph) { foreach (TypesGenerator::$propertyTypes as $propertyType) { + /** @var RdfResource $property */ foreach ($graph->allOfType($propertyType) as $property) { if ($property->isBNode()) { continue; @@ -76,7 +79,7 @@ public function extract(): array * * @return string The cardinality */ - private function extractForProperty(Resource $property): string + private function extractForProperty(RdfResource $property): string { $minCardinality = $property->get('owl:minCardinality'); $maxCardinality = $property->get('owl:maxCardinality'); diff --git a/src/ClassMutator/AnnotationsAppender.php b/src/ClassMutator/AnnotationsAppender.php index 1d77155b..fb8a23d8 100644 --- a/src/ClassMutator/AnnotationsAppender.php +++ b/src/ClassMutator/AnnotationsAppender.php @@ -15,17 +15,22 @@ use ApiPlatform\SchemaGenerator\AnnotationGenerator\AnnotationGeneratorInterface; use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Use_; +use EasyRdf\Resource as RdfResource; final class AnnotationsAppender implements ClassMutatorInterface { - /** @var AnnotationGeneratorInterface[] */ - private array $annotationGenerators; /** @var Class_[] */ private array $classes; + /** @var AnnotationGeneratorInterface[] */ + private array $annotationGenerators; + /** @var RdfResource[] */ private array $typesToGenerate; /** + * @param Class_[] $classes * @param AnnotationGeneratorInterface[] $annotationGenerators + * @param RdfResource[] $typesToGenerate */ public function __construct(array $classes, array $annotationGenerators, array $typesToGenerate) { @@ -51,17 +56,17 @@ public function __invoke(Class_ $class): Class_ private function generateClassUses(Class_ $class): Class_ { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; - if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace()) { - $class->addUse(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName())); + if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace) { + $class->addUse(new Use_(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName()))); } foreach ($class->properties() as $property) { if (isset($this->classes[$property->rangeName]) && $this->classes[$property->rangeName]->interfaceName()) { - $class->addUse(sprintf( + $class->addUse(new Use_(sprintf( '%s\\%s', $this->classes[$property->rangeName]->interfaceNamespace(), $this->classes[$property->rangeName]->interfaceName() - )); + ))); } } @@ -87,7 +92,7 @@ private function generateClassAnnotations(Class_ $class): Class_ private function generateConstantAnnotations(Class_ $class): Class_ { - foreach ($class->constants() as $name => &$constant) { + foreach ($class->constants() as $constant) { foreach ($this->annotationGenerators as $generator) { foreach ($generator->generateConstantAnnotations($constant) as $constantAnnotation) { $constant->addAnnotation($constantAnnotation); diff --git a/src/ClassMutator/AttributeAppender.php b/src/ClassMutator/AttributeAppender.php index 6df99000..d707658f 100644 --- a/src/ClassMutator/AttributeAppender.php +++ b/src/ClassMutator/AttributeAppender.php @@ -15,15 +15,17 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\AttributeGeneratorInterface; use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Use_; final class AttributeAppender implements ClassMutatorInterface { - /** @var AttributeGeneratorInterface[] */ - private array $attributeGenerators; /** @var Class_[] */ private array $classes; + /** @var AttributeGeneratorInterface[] */ + private array $attributeGenerators; /** + * @param Class_[] $classes * @param AttributeGeneratorInterface[] $attributeGenerators */ public function __construct(array $classes, array $attributeGenerators) @@ -44,17 +46,17 @@ public function __invoke(Class_ $class): Class_ private function generateClassUses(Class_ $class): Class_ { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; - if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace()) { - $class->addUse(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName())); + if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace) { + $class->addUse(new Use_(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName()))); } foreach ($class->properties() as $property) { if (isset($this->classes[$property->rangeName]) && $this->classes[$property->rangeName]->interfaceName()) { - $class->addUse(sprintf( + $class->addUse(new Use_(sprintf( '%s\\%s', $this->classes[$property->rangeName]->interfaceNamespace(), $this->classes[$property->rangeName]->interfaceName() - )); + ))); } } @@ -80,7 +82,7 @@ private function generateClassAttributes(Class_ $class): Class_ private function generatePropertiesAttributes(Class_ $class): Class_ { - foreach ($class->properties() as $name => &$property) { + foreach ($class->properties() as $property) { foreach ($this->attributeGenerators as $attributeGenerator) { foreach ($attributeGenerator->generatePropertyAttributes($property, $class->name()) as $propertyAttribute) { $property->addAttribute($propertyAttribute); diff --git a/src/ClassMutator/ClassIdAppender.php b/src/ClassMutator/ClassIdAppender.php index 97729efc..ea02384f 100644 --- a/src/ClassMutator/ClassIdAppender.php +++ b/src/ClassMutator/ClassIdAppender.php @@ -18,8 +18,12 @@ final class ClassIdAppender implements ClassMutatorInterface { + /** @var Configuration */ private array $config; + /** + * @param Configuration $config + */ public function __construct(array $config) { $this->config = $config; @@ -29,13 +33,13 @@ public function __invoke(Class_ $class): Class_ { if ( $class->isEnum() - || $class->isEmbeddable() + || $class->isEmbeddable || ($class->hasParent() && 'parent' === $this->config['id']['onClass']) - || ($class->hasChild() && 'child' === $this->config['id']['onClass']) + || ($class->hasChild && 'child' === $this->config['id']['onClass']) ) { return $class; } - return $class->addProperty((new IdPropertyGenerator())($this->config['id']['generationStrategy'], $this->config['id']['writable'] ?? false)); + return $class->addProperty((new IdPropertyGenerator())($this->config['id']['generationStrategy'], $this->config['id']['writable'])); } } diff --git a/src/ClassMutator/ClassInterfaceMutator.php b/src/ClassMutator/ClassInterfaceMutator.php index 0b044d4e..e1838f47 100644 --- a/src/ClassMutator/ClassInterfaceMutator.php +++ b/src/ClassMutator/ClassInterfaceMutator.php @@ -27,6 +27,8 @@ public function __construct(string $desiredNamespace) public function __invoke(Class_ $class): Class_ { - return $class->withInterface(new Interface_(sprintf('%sInterface', $class->name()), $this->desiredNamespace)); + $class->interface = new Interface_(sprintf('%sInterface', $class->name()), $this->desiredNamespace); + + return $class; } } diff --git a/src/ClassMutator/ClassParentMutator.php b/src/ClassMutator/ClassParentMutator.php index 2d5b7417..f56911f4 100644 --- a/src/ClassMutator/ClassParentMutator.php +++ b/src/ClassMutator/ClassParentMutator.php @@ -14,6 +14,7 @@ namespace ApiPlatform\SchemaGenerator\ClassMutator; use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; use Psr\Log\LoggerInterface; @@ -21,8 +22,12 @@ final class ClassParentMutator implements ClassMutatorInterface { private PhpTypeConverterInterface $phpTypeConverter; private LoggerInterface $logger; + /** @var Configuration */ private array $config; + /** + * @param Configuration $config + */ public function __construct(array $config, PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger) { $this->phpTypeConverter = $phpTypeConverter; @@ -33,21 +38,21 @@ public function __construct(array $config, PhpTypeConverterInterface $phpTypeCon public function __invoke(Class_ $class): Class_ { $typeConfig = $this->config['types'][$class->name()]; - $class->withParent($typeConfig['parent'] ?? null); + $class->withParent($typeConfig['parent']); if (null === $class->parent() && $subclassOf = $class->getSubClassOf()) { if (\count($subclassOf) > 1) { $this->logger->warning(sprintf('The type "%s" has several supertypes. Using the first one.', $class->resourceUri())); } - $class->setParent($this->phpTypeConverter->escapeIdentifier($subclassOf[0]->localName())); + $class = $class->withParent($this->phpTypeConverter->escapeIdentifier($subclassOf[0]->localName())); } if ($class->hasParent() && isset($this->config['types'][$class->parent()]['namespaces']['class'])) { $parentNamespace = $this->config['types'][$class->parent()]['namespaces']['class']; if ($class->isInNamespace($parentNamespace)) { - $class->addUse($parentNamespace.'\\'.$class->parent()); + $class->addUse(new Use_($parentNamespace.'\\'.$class->parent())); } } diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 6ab3b6be..3344aff3 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -15,7 +15,7 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use Psr\Log\LoggerInterface; @@ -23,16 +23,25 @@ final class ClassPropertiesAppender implements ClassMutatorInterface { private PropertyGenerator $propertyGenerator; private LoggerInterface $logger; + /** @var array */ private array $propertiesMap; + /** @var Configuration */ private array $config; private const SCHEMA_ORG_SUPERSEDED_BY = 'schema:supersededBy'; + /** @var string[] */ private static array $classTypes = [ 'rdfs:Class', 'owl:Class', ]; + /** @var RdfGraph[] */ private array $graphs; + /** + * @param Configuration $config + * @param array $propertiesMap + * @param RdfGraph[] $graphs + */ public function __construct(PropertyGenerator $propertyGenerator, LoggerInterface $logger, array $config, array $propertiesMap, array $graphs) { $this->propertiesMap = $propertiesMap; @@ -46,9 +55,9 @@ public function __invoke(Class_ $class): Class_ { $typeConfig = $this->config['types'][$class->name()]; - if (!($typeConfig['allProperties'] ?? false) && \is_array($typeConfig['properties'] ?? null)) { + if (!$typeConfig['allProperties']) { foreach ($typeConfig['properties'] as $key => $value) { - if ($value['exclude'] ?? false) { + if ($value['exclude']) { continue; } @@ -66,7 +75,7 @@ public function __invoke(Class_ $class): Class_ $class = $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); } } else { - $remainingProperties = $typeConfig['properties'] ?? []; + $remainingProperties = $typeConfig['properties']; // All properties foreach ($this->propertiesMap[$class->resourceUri()] as $property) { unset($remainingProperties[$property->localName()]); @@ -79,7 +88,7 @@ public function __invoke(Class_ $class): Class_ } foreach ($remainingProperties as $key => $remainingProperty) { - if ($remainingProperty['exclude'] ?? false) { + if ($remainingProperty['exclude']) { continue; } $class = $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); @@ -91,11 +100,14 @@ public function __invoke(Class_ $class): Class_ /** * Add custom fields (not defined in the vocabulary). + * + * @param TypeConfiguration $typeConfig + * @param Configuration $config */ private function generateCustomField(string $propertyName, RdfResource $type, array $typeConfig, Class_ $class, array $config): Class_ { $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())); - $customResource = new RdfResource('_:'.$propertyName, new Graph()); + $customResource = new RdfResource('_:'.$propertyName, new RdfGraph()); $customResource->add('rdfs:range', $type); return $this->generateField($config, $class, $type, $typeConfig, $customResource, true); @@ -103,6 +115,9 @@ private function generateCustomField(string $propertyName, RdfResource $type, ar /** * Updates generated $class with given field config. + * + * @param Configuration $config + * @param TypeConfiguration $typeConfig */ private function generateField(array $config, Class_ $class, RdfResource $type, array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ { @@ -112,6 +127,8 @@ private function generateField(array $config, Class_ $class, RdfResource $type, /** * Gets the parent classes of the current one and add them to $parentClasses array. * + * @param RdfResource[] $parentClasses + * * @return RdfResource[] */ private function getParentClasses(RdfResource $resource, array $parentClasses = []): array diff --git a/src/ClassMutator/ClassPropertiesTypehintMutator.php b/src/ClassMutator/ClassPropertiesTypehintMutator.php index 8b7d97ff..022a17f2 100644 --- a/src/ClassMutator/ClassPropertiesTypehintMutator.php +++ b/src/ClassMutator/ClassPropertiesTypehintMutator.php @@ -18,13 +18,15 @@ final class ClassPropertiesTypehintMutator implements ClassMutatorInterface { - /** @var Class_[]|array */ + /** @var Class_[] */ private array $classes; private PhpTypeConverterInterface $phpTypeConverter; + /** @var Configuration */ private array $config; /** - * @param Class_[]|array $classes + * @param Configuration $config + * @param Class_[] $classes */ public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $config, array $classes) { @@ -36,7 +38,7 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $ public function __invoke(Class_ $class): Class_ { foreach ($class->properties() as $property) { - $property->isEnum = isset($this->classes[$property->rangeName]) ? ($this->classes[$property->rangeName])->isEnum() : false; + $property->isEnum = isset($this->classes[$property->rangeName]) && ($this->classes[$property->rangeName])->isEnum(); $property->typeHint = $this->phpTypeConverter->getPhpType( $property, $this->config, diff --git a/src/ClassMutator/EnumClassMutator.php b/src/ClassMutator/EnumClassMutator.php index 2f5db4fb..2ed99ead 100644 --- a/src/ClassMutator/EnumClassMutator.php +++ b/src/ClassMutator/EnumClassMutator.php @@ -15,8 +15,9 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Constant; +use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use MyCLabs\Enum\Enum; final class EnumClassMutator implements ClassMutatorInterface @@ -24,11 +25,14 @@ final class EnumClassMutator implements ClassMutatorInterface private PhpTypeConverterInterface $phpTypeConverter; /** - * @var Graph[] + * @var RdfGraph[] */ private array $graphs; private string $desiredNamespace; + /** + * @param RdfGraph[] $graphs + */ public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $graphs, string $desiredNamespace) { $this->phpTypeConverter = $phpTypeConverter; @@ -38,9 +42,10 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $ public function __invoke(Class_ $class): Class_ { - $class = $class->withNamespace($this->desiredNamespace) + $class->namespace = $this->desiredNamespace; + $class = $class ->withParent('Enum') - ->addUse(Enum::class); + ->addUse(new Use_(Enum::class)); foreach ($this->graphs as $graph) { foreach ($graph->allOfType($class->resourceUri()) as $instance) { diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 442d7b70..2e70f6b9 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -16,7 +16,7 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; @@ -50,7 +50,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $vocabFile = $input->getOption('vocabulary-file'); $relations = []; - $graph = new Graph(); + $graph = new RdfGraph(); $format = pathinfo($vocabFile, \PATHINFO_EXTENSION) ?: 'guess'; if (0 === strpos($vocabFile, 'http://') || 0 === strpos($vocabFile, 'https://')) { diff --git a/src/Command/GenerateCommand.php b/src/Command/GenerateCommand.php index e6801f46..fdd9dae3 100644 --- a/src/Command/GenerateCommand.php +++ b/src/Command/GenerateCommand.php @@ -20,7 +20,7 @@ use ApiPlatform\SchemaGenerator\TypesGenerator; use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -50,9 +50,23 @@ final class GenerateCommand extends Command * {@inheritdoc} */ protected function configure(): void + { + $this->readComposer(); + + $this + ->setName('generate') + ->setDescription('Generate the PHP code') + ->addArgument('output', $this->defaultOutput ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The output directory', $this->defaultOutput) + ->addArgument('config', InputArgument::OPTIONAL, 'The config file to use (default to "schema.yaml" in the current directory, will generate all types if no config file exists)'); + } + + private function readComposer(): void { if (file_exists('composer.json') && is_file('composer.json') && is_readable('composer.json')) { - $composer = json_decode(file_get_contents('composer.json'), true, 512, \JSON_THROW_ON_ERROR); + if (false === ($composerContent = file_get_contents('composer.json'))) { + throw new \RuntimeException('Cannot read composer.json content.'); + } + $composer = json_decode($composerContent, true, 512, \JSON_THROW_ON_ERROR); foreach ($composer['autoload']['psr-4'] ?? [] as $prefix => $output) { if ('' === $prefix) { continue; @@ -64,12 +78,6 @@ protected function configure(): void break; } } - - $this - ->setName('generate') - ->setDescription('Generate the PHP code') - ->addArgument('output', $this->defaultOutput ? InputArgument::OPTIONAL : InputArgument::REQUIRED, 'The output directory', $this->defaultOutput) - ->addArgument('config', InputArgument::OPTIONAL, 'The config file to use (default to "schema.yaml" in the current directory, will generate all types if no config file exists)'); } /** @@ -81,9 +89,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int $outputDir = $input->getArgument('output'); $configArgument = $input->getArgument('config'); - if ($dir = realpath($input->getArgument('output'))) { + if ($dir = realpath($outputDir)) { if (!is_dir($dir)) { - if (!$this->defaultOutput) { + if (!$defaultOutput) { throw new \InvalidArgumentException(sprintf('The file "%s" is not a directory.', $dir)); } @@ -114,12 +122,20 @@ protected function execute(InputInterface $input, OutputInterface $output): int throw new \InvalidArgumentException(sprintf('The file "%s" isn\'t readable.', $configArgument)); } + if (false === ($configContent = file_get_contents($configArgument))) { + throw new \RuntimeException(sprintf('Cannot read "%s" content.', $configArgument)); + } + $parser = new Parser(); - $config = $parser->parse(file_get_contents($configArgument)); + $config = $parser->parse($configContent); unset($parser); } elseif (is_readable(self::DEFAULT_CONFIG_FILE)) { + if (false === ($defaultConfigContent = file_get_contents(self::DEFAULT_CONFIG_FILE))) { + throw new \RuntimeException(sprintf('Cannot read "%s" content.', self::DEFAULT_CONFIG_FILE)); + } + $parser = new Parser(); - $config = $parser->parse(file_get_contents(self::DEFAULT_CONFIG_FILE)); + $config = $parser->parse($defaultConfigContent); unset($parser); } else { $helper = $this->getHelper('question'); @@ -134,6 +150,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $processor = new Processor(); $configuration = new TypesGeneratorConfiguration($dir === $defaultOutput ? $this->namespacePrefix : null); + /** @var Configuration */ $processedConfiguration = $processor->processConfiguration($configuration, [$config]); $processedConfiguration['output'] = $outputDir; if (!$processedConfiguration['output']) { @@ -142,7 +159,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $graphs = []; foreach ($processedConfiguration['vocabularies'] as $vocab) { - $graph = new Graph(); + $graph = new RdfGraph(); if (0 === strpos($vocab['uri'], 'http://') || 0 === strpos($vocab['uri'], 'https://')) { $graph->load($vocab['uri'], $vocab['format']); } else { diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index 57f4a589..64ffd87f 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -28,6 +28,7 @@ class GoodRelationsBridge */ private array $relations; + /** @var array */ private array $objectPropertiesTable = [ 'priceSpecification' => 'hasPriceSpecification', 'businessFunction' => 'hasBusinessFunction', @@ -46,6 +47,7 @@ class GoodRelationsBridge 'acceptedPaymentMethod' => 'acceptedPaymentMethods', ]; + /** @var array */ private array $datatypePropertiesTable = [ 'minPrice' => 'hasMinCurrencyValue', 'unitCode' => 'hasUnitOfMeasurement', @@ -97,14 +99,21 @@ public function exists(string $id): bool /** * Extracts cardinality from the Good Relations OWL. * - * @return string|bool + * @return string|false */ public function extractCardinality(string $id) { foreach ($this->relations as $relation) { $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', $this->getPropertyUrl($id))); + if (false === $result) { + continue; + } if (\count($result)) { - preg_match('/\(.\.\..\)/', $result[0]->asXML(), $matches); + $xmlResult = $result[0]->asXML(); + if (false === $xmlResult) { + continue; + } + preg_match('/\(.\.\..\)/', $xmlResult, $matches); return $matches[0]; } diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php new file mode 100644 index 00000000..fe152f03 --- /dev/null +++ b/src/Model/Attribute.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model; + +final class Attribute +{ + private string $name; + + /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] */ + private array $args; + + /** + * @param (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] $args + */ + public function __construct(string $name, array $args = []) + { + $this->name = $name; + $this->args = $args; + } + + public function name(): string + { + return $this->name; + } + + /** + * @return (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] + */ + public function args(): array + { + return $this->args; + } +} diff --git a/src/Model/Class_.php b/src/Model/Class_.php index be7b8e79..6bd1db95 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -15,7 +15,6 @@ use Doctrine\Inflector\Inflector; use EasyRdf\Resource as RdfResource; -use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Helpers; use Nette\PhpGenerator\Method; use Nette\PhpGenerator\PhpFile; @@ -23,29 +22,35 @@ final class Class_ { private string $name; - private string $namespace = ''; - private ?Interface_ $interface = null; - private array $uses = []; + private RdfResource $resource; + public string $namespace = ''; + /** @var false|string|null */ + private $parent; + public ?Interface_ $interface = null; /** @var Property[] */ private array $properties = []; - /** @var array|Constant[] */ - private array $constants = []; - /** @var array[] */ + /** @var Use_[] */ + private array $uses = []; + /** @var Attribute[] */ private array $attributes = []; + /** @var string[] */ private array $annotations = []; - private bool $hasConstructor = false; - private bool $parentHasConstructor = false; - private bool $isAbstract = false; - private bool $hasChild = false; - private bool $embeddable = false; - /** @var bool|string|null */ - private $parent; - private RdfResource $resource; + /** @var array|Constant[] */ + private array $constants = []; + public bool $hasConstructor = false; + public bool $parentHasConstructor = false; + public bool $isAbstract = false; + public bool $hasChild = false; + public bool $isEmbeddable = false; public ?string $security = null; + /** @var array> */ public array $operations = []; private const SCHEMA_ORG_ENUMERATION = 'https://schema.org/Enumeration'; + /** + * @param false|string|null $parent + */ public function __construct(string $name, RdfResource $resource, $parent = null) { $this->name = $name; @@ -58,6 +63,55 @@ public function name(): string return $this->name; } + public function resource(): RdfResource + { + return $this->resource; + } + + public function resourceUri(): string + { + return $this->resource->getUri(); + } + + public function resourceComment(): ?string + { + return (string) $this->resource->get('rdfs:comment'); + } + + public function resourceLocalName(): string + { + return $this->resource->localName(); + } + + public function isInNamespace(string $namespace): bool + { + return $this->namespace === $namespace; + } + + public function parent(): ?string + { + if (false === $this->parent) { + return ''; + } + + return $this->parent; + } + + public function hasParent(): bool + { + return '' !== $this->parent && null !== $this->parent && false !== $this->parent; + } + + /** + * @param false|string|null $parent + */ + public function withParent($parent): self + { + $this->parent = $parent; + + return $this; + } + public function interfaceName(): ?string { return $this->interface ? $this->interface->name() : null; @@ -77,30 +131,27 @@ public function interfaceToNetteFile(string $fileHeader = null): PhpFile return $this->interface->toNetteFile($fileHeader); } - public function withNamespace(string $namespace): self + /** @return array */ + public function properties(): array { - $this->namespace = $namespace; - - return $this; + return $this->properties; } - public function withParent($parent): self + /** @return array */ + public function uniqueProperties(): array { - $this->parent = $parent; - - return $this; + return array_filter($this->properties, static fn (Property $property) => $property->isUnique); } - public function withInterface(Interface_ $interface): self + /** @return string[] */ + public function uniquePropertyNames(): array { - $this->interface = $interface; - - return $this; + return array_map(static fn (Property $property) => $property->name(), array_values($this->uniqueProperties())); } public function addProperty(Property $property): self { - $this->properties[$property->name] = $property; + $this->properties[$property->name()] = $property; return $this; } @@ -122,7 +173,7 @@ public function hasProperty(string $propertyName): bool return isset($this->properties[$propertyName]); } - public function addUse(string $use): self + public function addUse(Use_ $use): self { if (!\in_array($use, $this->uses, true)) { $this->uses[] = $use; @@ -131,10 +182,7 @@ public function addUse(string $use): self return $this; } - /** - * @param array $attribute - */ - public function addAttribute(array $attribute): self + public function addAttribute(Attribute $attribute): self { if (!\in_array($attribute, $this->attributes, true)) { $this->attributes[] = $attribute; @@ -174,64 +222,9 @@ public function constants(): array return $this->constants; } - public function resource(): RdfResource - { - return $this->resource; - } - - public function resourceUri(): string - { - return $this->resource->getUri(); - } - - public function resourceComment(): ?string - { - return (string) $this->resource->get('rdfs:comment'); - } - - public function resourceLocalName(): string - { - return $this->resource->localName(); - } - - public function parent(): ?string - { - if (false === $this->parent) { - return ''; - } - - return $this->parent; - } - - public function setParent(?string $parent): void - { - $this->parent = $parent; - } - - public function hasParent(): bool - { - return '' !== $this->parent && null !== $this->parent && false !== $this->parent; - } - - public function markWithConstructor(): self - { - $this->hasConstructor = true; - - return $this; - } - - public function setIsAbstract(bool $isAbstract): self - { - $this->isAbstract = $isAbstract; - - return $this; - } - - public function isAbstract(): bool - { - return $this->isAbstract; - } - + /** + * @return RdfResource[] + */ public function getSubClassOf(): array { return array_filter($this->resource->all('rdfs:subClassOf', 'resource'), static fn (RdfResource $resource) => !$resource->isBNode()); @@ -253,41 +246,16 @@ public function isParentEnum(): bool return 'Enum' === $this->parent; } - public function isInNamespace(string $namespace): bool - { - return $this->namespace === $namespace; - } - - public function namespace(): string - { - return $this->namespace; - } - - /** @return array */ - public function properties(): array - { - return $this->properties; - } - - /** @return array */ - public function uniqueProperties(): array - { - return array_filter($this->properties, static fn (Property $property) => $property->isUnique); - } - - /** @return string[] */ - public function uniquePropertyNames(): array - { - return array_map(static fn (Property $property) => $property->name, array_values($this->uniqueProperties())); - } - + /** + * @param Configuration $config + */ public function toNetteFile(array $config, Inflector $inflector): PhpFile { - $useDoctrineCollections = $config['doctrine']['useCollection'] ?? true; - $useAccessors = $config['accessorMethods'] ?? true; - $useFluentMutators = $config['fluentMutatorMethods'] ?? false; + $useDoctrineCollections = $config['doctrine']['useCollection']; + $useAccessors = $config['accessorMethods']; + $useFluentMutators = $config['fluentMutatorMethods']; $fileHeader = $config['header'] ?? null; - $fieldVisibility = $config['fieldVisibility'] ?? ClassType::VISIBILITY_PRIVATE; + $fieldVisibility = $config['fieldVisibility']; $file = new PhpFile(); if (null !== $fileHeader && false !== $fileHeader) { @@ -297,15 +265,13 @@ public function toNetteFile(array $config, Inflector $inflector): PhpFile $namespace = $file->addNamespace($this->namespace); foreach ($this->uses as $use) { - $namespace->addUse($use); + $namespace->addUse($use->name(), $use->alias()); } $class = $namespace->addClass($this->name); foreach ($this->attributes as $attribute) { - foreach ($attribute as $attributeName => $attributeArgs) { - $class->addAttribute($attributeName, $attributeArgs); - } + $class->addAttribute($attribute->name(), $attribute->args()); } foreach ($this->annotations as $annotation) { @@ -314,11 +280,11 @@ public function toNetteFile(array $config, Inflector $inflector): PhpFile $class->setAbstract($this->isAbstract); - if (null !== $this->interface) { + if (null !== $this->interfaceName()) { $class->setImplements([$this->interfaceName()]); } - if ($this->hasParent()) { + if ($this->parent()) { $class->setExtends($this->parent()); } @@ -361,40 +327,4 @@ static function (Property $property) use ($useDoctrineCollections, $fieldVisibil return $file; } - - public function isEmbeddable(): bool - { - return $this->embeddable; - } - - public function setEmbeddable(bool $embeddable): self - { - $this->embeddable = $embeddable; - - return $this; - } - - public function hasChild(): bool - { - return $this->hasChild; - } - - public function hasConstructor(): bool - { - return $this->hasConstructor; - } - - public function markAsHasChild(): self - { - $this->hasChild = true; - - return $this; - } - - public function setParentHasConstructor(bool $parentHasConstructor): self - { - $this->parentHasConstructor = $parentHasConstructor; - - return $this; - } } diff --git a/src/Model/Interface_.php b/src/Model/Interface_.php index 2fcd2cd5..6edee947 100644 --- a/src/Model/Interface_.php +++ b/src/Model/Interface_.php @@ -20,6 +20,7 @@ final class Interface_ { private string $name; private string $namespace; + /** @var string[] */ private array $annotations = []; public function __construct(string $name, string $namespace) diff --git a/src/Model/Property.php b/src/Model/Property.php index 61707917..bb440e35 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -20,11 +20,12 @@ final class Property { - public string $name; + private string $name; public ?RdfResource $resource = null; public string $cardinality; - public $range; - public $rangeName; + public ?RdfResource $range = null; + public ?string $rangeName = null; + /** @var array */ public ?array $ormColumn = null; public bool $isArray = false; public bool $isReadable = true; @@ -35,20 +36,27 @@ final class Property public bool $isEmbedded = false; public ?string $mappedBy = null; public ?string $inversedBy = null; + /** @var string|bool */ public $columnPrefix = false; public bool $isId = false; public ?string $typeHint = null; public ?string $relationTableName = null; public bool $isEnum = false; public ?string $adderRemoverTypeHint = null; + /** @var string[] */ public array $groups = []; public ?string $security = null; - /** @var array[] */ + /** @var Attribute[] */ private array $attributes = []; + /** @var string[] */ private array $annotations = []; + /** @var string[] */ private array $getterAnnotations = []; + /** @var string[] */ private array $setterAnnotations = []; + /** @var string[] */ private array $adderAnnotations = []; + /** @var string[] */ private array $removerAnnotations = []; public function __construct(string $name) @@ -61,10 +69,7 @@ public function name(): string return $this->name; } - /** - * @param array $attribute - */ - public function addAttribute(array $attribute): self + public function addAttribute(Attribute $attribute): self { if (!\in_array($attribute, $this->attributes, true)) { $this->attributes[] = $attribute; @@ -109,6 +114,9 @@ public function addAdderAnnotation(string $annotation): self return $this; } + /** + * @return string[] + */ public function adderAnnotations(): array { return $this->adderAnnotations; @@ -123,11 +131,6 @@ public function addRemoverAnnotation(string $annotation): self return $this; } - public function groups(): array - { - return $this->groups; - } - public function resourceUri(): ?string { return $this->resource ? $this->resource->getUri() : null; @@ -149,7 +152,7 @@ public function toNetteProperty(string $visibility = null, bool $useDoctrineColl $netteProperty->setType($this->typeHint); } - if (!$this->isArray || $this->isTypehintedAsCollection()) { + if (!$this->isArray || $this->isTypeHintedAsCollection()) { $netteProperty->setNullable($this->isNullable); } @@ -158,9 +161,7 @@ public function toNetteProperty(string $visibility = null, bool $useDoctrineColl } foreach ($this->attributes as $attribute) { - foreach ($attribute as $attributeName => $attributeArgs) { - $netteProperty->addAttribute($attributeName, $attributeArgs); - } + $netteProperty->addAttribute($attribute->name(), $attribute->args()); } foreach ($this->annotations as $annotation) { $netteProperty->addComment($annotation); @@ -169,6 +170,9 @@ public function toNetteProperty(string $visibility = null, bool $useDoctrineColl return $netteProperty; } + /** + * @return Method[] + */ public function generateNetteMethods( \Closure $singularize, bool $useDoctrineCollections = true, @@ -201,6 +205,9 @@ private function generateGetter(): Method return $getter; } + /** + * @return Method[] + */ private function generateMutators( \Closure $singularize, bool $useDoctrineCollections = true, @@ -284,9 +291,12 @@ private function generateMutators( return $mutators; } + /** + * @return array{}|int|null + */ private function guessDefaultGeneratedValue(bool $useDoctrineCollections = true) { - if ($this->isArray && !$this->isTypehintedAsCollection() && ($this->isEnum || !$this->typeHint || 'array' === $this->typeHint || !$useDoctrineCollections)) { + if ($this->isArray && !$this->isTypeHintedAsCollection() && ($this->isEnum || !$this->typeHint || 'array' === $this->typeHint || !$useDoctrineCollections)) { return []; } @@ -297,7 +307,7 @@ private function guessDefaultGeneratedValue(bool $useDoctrineCollections = true) return -1; } - private function isTypehintedAsCollection(): bool + private function isTypeHintedAsCollection(): bool { return 'Collection' === $this->typeHint; } diff --git a/src/Model/Use_.php b/src/Model/Use_.php new file mode 100644 index 00000000..849146a7 --- /dev/null +++ b/src/Model/Use_.php @@ -0,0 +1,37 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model; + +final class Use_ +{ + private string $name; + + private ?string $alias; + + public function __construct(string $name, ?string $alias = null) + { + $this->name = $name; + $this->alias = $alias; + } + + public function name(): string + { + return $this->name; + } + + public function alias(): ?string + { + return $this->alias; + } +} diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index 8cf787c4..c0bd8026 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -13,22 +13,23 @@ namespace ApiPlatform\SchemaGenerator; +use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; -use EasyRdf\Resource; +use EasyRdf\Resource as RdfResource; final class PhpTypeConverter implements PhpTypeConverterInterface { /** * Is this type a datatype? */ - public function isDatatype(Resource $range): bool + public function isDatatype(RdfResource $range): bool { return isset(PhpTypeConverterInterface::BASE_MAPPING[$this->getUri($range)]) || $this->isLangString($range); } public function getPhpType(Property $property, array $config = [], array $classes = []): ?string { - if ($property->isArray) { + if ($property->isArray && $property->range) { return ($config['doctrine']['useCollection'] ?? false) && !$this->isDatatype($property->range) ? 'Collection' : 'array'; } @@ -46,6 +47,9 @@ public function escapeIdentifier(string $identifier): string return $identifier; } + /** + * @param Class_[] $classes + */ private function getNonArrayType(Property $property, array $classes): ?string { if ($property->isEnum) { @@ -78,7 +82,7 @@ private function getNonArrayType(Property $property, array $classes): ?string * * @todo find something smarter to detect this kind of strings */ - private function isLangString(Resource $range): bool + private function isLangString(RdfResource $range): bool { return $range->isBNode() && null !== ($unionOf = $range->get('owl:unionOf')) && @@ -86,7 +90,7 @@ private function isLangString(Resource $range): bool 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString' === $rdfFirst->getUri(); } - private function getUri(Resource $range): string + private function getUri(RdfResource $range): string { if ($range->isBNode() && $onDatatype = $range->get('owl:onDatatype')) { return $onDatatype->getUri(); diff --git a/src/PhpTypeConverterInterface.php b/src/PhpTypeConverterInterface.php index 1994f981..50ea0581 100644 --- a/src/PhpTypeConverterInterface.php +++ b/src/PhpTypeConverterInterface.php @@ -13,8 +13,9 @@ namespace ApiPlatform\SchemaGenerator; +use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; -use EasyRdf\Resource; +use EasyRdf\Resource as RdfResource; interface PhpTypeConverterInterface { @@ -92,10 +93,13 @@ interface PhpTypeConverterInterface /** * Is this type a datatype? */ - public function isDatatype(Resource $range): bool; + public function isDatatype(RdfResource $range): bool; /** * Gets the PHP type of this field. + * + * @param Configuration|array{} $config + * @param Class_[] $classes */ public function getPhpType(Property $property, array $config = [], array $classes = []): ?string; diff --git a/src/Printer.php b/src/Printer.php index 865489f5..71f88375 100644 --- a/src/Printer.php +++ b/src/Printer.php @@ -22,6 +22,8 @@ final class Printer extends NettePrinter public function __construct() { + parent::__construct(); + $this->setTypeResolving(false); } } diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index 7f45fcca..30da2509 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -17,6 +17,7 @@ use ApiPlatform\SchemaGenerator\GoodRelationsBridge; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -25,6 +26,7 @@ final class PropertyGenerator { + /** @var string[] */ private static array $rangeProperties = [ 'schema:rangeIncludes', 'rdfs:range', @@ -33,8 +35,12 @@ final class PropertyGenerator private GoodRelationsBridge $goodRelationsBridge; private LoggerInterface $logger; private PhpTypeConverterInterface $phpTypeConverter; + /** @var array */ private array $cardinalities; + /** + * @param array $cardinalities + */ public function __construct(GoodRelationsBridge $goodRelationsBridge, PhpTypeConverterInterface $phpTypeConverter, $cardinalities, LoggerInterface $logger) { $this->goodRelationsBridge = $goodRelationsBridge; @@ -43,6 +49,10 @@ public function __construct(GoodRelationsBridge $goodRelationsBridge, PhpTypeCon $this->logger = $logger; } + /** + * @param Configuration $config + * @param TypeConfiguration $typeConfig + */ public function __invoke(array $config, Class_ $class, RdfResource $type, array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ { $typeUri = $type->getUri(); @@ -54,24 +64,16 @@ public function __invoke(array $config, Class_ $class, RdfResource $type, array $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyUri, $typeUri)); } - // Ignore or warn when properties are legacy - if (null !== $property && preg_match('/legacy spelling/', (string) $property->get('rdfs:comment'))) { - if (isset($typeConfig['properties'])) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyUri, $typeUri)); - } else { - $this->logger->debug(sprintf('The property "%s" (type "%s") is legacy. Ignoring.', $propertyUri, $typeUri)); - - return $class; - } + // Warn when properties are legacy + if (preg_match('/legacy spelling/', (string) $property->get('rdfs:comment'))) { + $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyUri, $typeUri)); } $propertyConfig = $typeConfig['properties'][$propertyName] ?? []; $ranges = []; foreach (self::$rangeProperties as $rangePropertyType) { - /** - * @var RdfResource $range - */ + /** @var RdfResource $range */ foreach ($property->all($rangePropertyType, 'resource') as $range) { $ranges[] = $this->getRanges($range, $propertyConfig, $config); } @@ -150,17 +152,23 @@ public function __invoke(array $config, Class_ $class, RdfResource $type, array $class->addProperty($schemaGeneratorProperty); if ($isArray) { - $class->markWithConstructor(); + $class->hasConstructor = true; if ($config['doctrine']['useCollection']) { - $class->addUse(ArrayCollection::class); - $class->addUse(Collection::class); + $class->addUse(new Use_(ArrayCollection::class)); + $class->addUse(new Use_(Collection::class)); } } return $class; } + /** + * @param PropertyConfiguration|array{} $propertyConfig + * @param Configuration $config + * + * @return RdfResource[] + */ private function getRanges(RdfResource $range, array $propertyConfig, array $config): array { $localName = $range->localName(); diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index c9237f52..d1d3c80f 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -24,7 +24,7 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator; use Doctrine\Inflector\Inflector; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; use EasyRdf\RdfNamespace; use EasyRdf\Resource as RdfResource; use PhpCsFixer\Cache\NullCacheManager; @@ -80,12 +80,11 @@ class TypesGenerator private Environment $twig; private LoggerInterface $logger; - /** - * @var Graph[] - */ + /** @var RdfGraph[] */ private array $graphs; private PhpTypeConverterInterface $phpTypeConverter; private GoodRelationsBridge $goodRelationsBridge; + /** @var array */ private array $cardinalities; private Inflector $inflector; private Filesystem $filesystem; @@ -93,7 +92,7 @@ class TypesGenerator private Printer $printer; /** - * @param Graph[] $graphs + * @param RdfGraph[] $graphs */ public function __construct(Inflector $inflector, Environment $twig, LoggerInterface $logger, array $graphs, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge, Printer $printer) { @@ -117,6 +116,8 @@ public function __construct(Inflector $inflector, Environment $twig, LoggerInter /** * Generates files. + * + * @param Configuration $config */ public function generate(array $config): void { @@ -150,10 +151,10 @@ public function generate(array $config): void $class = (new EnumClassMutator( $this->phpTypeConverter, $this->graphs, - $typeConfig['namespace'] ?? $config['namespaces']['enum'] + $config['namespaces']['enum'] ))($class); } else { - $class->withNamespace($typeConfig['namespaces']['class'] ?? $config['namespaces']['entity']); + $class->namespace = $typeConfig['namespaces']['class'] ?? $config['namespaces']['entity']; // Interfaces if ($config['useInterface']) { @@ -165,7 +166,7 @@ public function generate(array $config): void } $class = (new ClassPropertiesAppender($this->propertyGenerator, $this->logger, $config, $propertiesMap, $this->graphs))($class); - $class->setEmbeddable($typeConfig['embeddable'] ?? false); + $class->isEmbeddable = $typeConfig['embeddable'] ?? false; $classes[$typeName] = $class; } @@ -176,8 +177,8 @@ public function generate(array $config): void if ($class->hasParent() && !$class->isParentEnum()) { $parentClass = $classes[$class->parent()] ?? null; if (isset($parentClass)) { - $parentClass->markAsHasChild(); - $class->setParentHasConstructor($parentClass->hasConstructor()); + $parentClass->hasChild = true; + $class->parentHasConstructor = $parentClass->hasConstructor; } else { $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class->parent(), $class->resourceUri())); } @@ -189,7 +190,7 @@ public function generate(array $config): void // Third pass foreach ($classes as &$class) { /* @var $class Class_ */ - $class->setIsAbstract($config['types'][$class->name()]['abstract'] ?? $class->hasChild()); + $class->isAbstract = $config['types'][$class->name()]['abstract'] ?? $class->hasChild; // When including all properties, ignore properties already set on parent if (($config['types'][$class->name()]['allProperties'] ?? true) && isset($classes[$class->parent()])) { @@ -247,7 +248,7 @@ public function generate(array $config): void $class = (new AnnotationsAppender($classes, $annotationGenerators, $typesToGenerate))($class); $class = (new AttributeAppender($classes, $attributeGenerators))($class); - $classDir = $this->namespaceToDir($config, $class->namespace()); + $classDir = $this->namespaceToDir($config, $class->namespace); $this->filesystem->mkdir($classDir); $path = sprintf('%s%s.php', $classDir, $className); @@ -263,8 +264,8 @@ public function generate(array $config): void $generatedFiles[] = $path; file_put_contents($path, $this->printer->printFile($class->interfaceToNetteFile($config['header'] ?? null))); - if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class->isAbstract()) { - $interfaceMappings[$class->interfaceNamespace().'\\'.$class->interfaceName()] = $class->namespace().'\\'.$className; + if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class->isAbstract) { + $interfaceMappings[$class->interfaceNamespace().'\\'.$class->interfaceName()] = $class->namespace.'\\'.$className; } } } @@ -288,6 +289,8 @@ public function generate(array $config): void /** * Gets the parent classes of the current one and add them to $parentClasses array. * + * @param RdfResource[] $parentClasses + * * @return RdfResource[] */ private function getParentClasses(RdfResource $resource, array $parentClasses = []): array @@ -319,6 +322,11 @@ private function getParentClasses(RdfResource $resource, array $parentClasses = /** * Creates a map between classes and properties. + * + * @param RdfResource[] $types + * @param Configuration $config + * + * @return array */ private function createPropertiesMap(array $types, array $config): array { @@ -337,6 +345,7 @@ private function createPropertiesMap(array $types, array $config): array foreach ($this->graphs as $graph) { foreach (self::$propertyTypes as $propertyType) { + /** @var RdfResource $property */ foreach ($graph->allOfType($propertyType) as $property) { if ($property->isBNode()) { continue; @@ -354,6 +363,11 @@ private function createPropertiesMap(array $types, array $config): array return $map; } + /** + * @param array{resources: RdfResource[], uris: string[], names: string[]}[] $typesResources + * @param Configuration $config + * @param array $map + */ private function addPropertyToMap(RdfResource $property, RdfResource $domain, array $typesResources, array $config, array &$map): void { $propertyName = $property->localName(); @@ -401,6 +415,11 @@ private function addPropertyToMap(RdfResource $property, RdfResource $domain, ar } } + /** + * @param Configuration $config + * + * @return RdfResource[] + */ private function defineTypesToGenerate(array $config): array { $typesToGenerate = []; @@ -446,6 +465,8 @@ private function defineTypesToGenerate(array $config): array /** * Converts a namespace to a directory path according to PSR-4. + * + * @param Configuration $config */ private function namespaceToDir(array $config, string $namespace): string { @@ -458,6 +479,8 @@ private function namespaceToDir(array $config, string $namespace): string /** * Uses PHP CS Fixer to make generated files following PSR and Symfony Coding Standards. + * + * @param string[] $files */ private function fixCs(array $files): void { diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index bdcf91de..78a71dca 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -92,7 +92,7 @@ static function ($rdf) { ->end() ->booleanNode('useInterface')->defaultFalse()->info('Generate interfaces and use Doctrine\'s Resolve Target Entity feature')->end() ->booleanNode('checkIsGoodRelations')->defaultFalse()->info('Emit a warning if a property is not derived from GoodRelations')->end() - ->scalarNode('header')->defaultFalse()->info('A license or any text to use as header of generated files')->example('// (c) Kévin Dunglas ')->end() + ->scalarNode('header')->defaultNull()->info('A license or any text to use as header of generated files')->example('// (c) Kévin Dunglas ')->end() ->arrayNode('namespaces') ->addDefaultsIfNotSet() ->info('PHP namespaces') @@ -108,7 +108,7 @@ static function ($rdf) { ->info('Doctrine') ->children() ->booleanNode('useCollection')->defaultTrue()->info('Use Doctrine\'s ArrayCollection instead of standard arrays')->end() - ->scalarNode('resolveTargetEntityConfigPath')->defaultNull()->info('The Resolve Target Entity Listener config file pass')->end() + ->scalarNode('resolveTargetEntityConfigPath')->defaultNull()->info('The Resolve Target Entity Listener config file path')->end() ->arrayNode('inheritanceAttributes') ->info('Doctrine inheritance attributes (if set, no other attributes are generated)') ->prototype('variable')->end() diff --git a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php index cefc5ad4..b796000f 100644 --- a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php @@ -18,8 +18,8 @@ use ApiPlatform\SchemaGenerator\Model\Interface_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; @@ -50,9 +50,11 @@ public function testGenerateClassAnnotations(Class_ $class, array $annotations): public function provideGenerateClassAnnotationsCases(): \Generator { - yield 'with interface' => [(new Class_('Res', new Resource('https://schema.org/Res')))->withInterface(new Interface_('Interface', '/foo')), ['{@inheritdoc}', '', '@author Bill']]; + $class = new Class_('Res', new RdfResource('https://schema.org/Res')); + $class->interface = new Interface_('Interface', '/foo'); + yield 'with interface' => [$class, ['{@inheritdoc}', '', '@author Bill']]; - $graph = new Graph(); - yield 'with resource' => [new Class_('Res', new Resource('https://schema.org/Res', $graph)), ['', '', '@see https://schema.org/Res', '@author Bill']]; + $graph = new RdfGraph(); + yield 'with resource' => [new Class_('Res', new RdfResource('https://schema.org/Res', $graph)), ['', '', '@see https://schema.org/Res', '@author Bill']]; } } diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 550c95f1..ca369ca0 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -16,13 +16,15 @@ use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\TypesGenerator; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; @@ -51,27 +53,29 @@ protected function setUp(): void */ public function testGenerateClassAttributes(Class_ $class, array $attributes): void { - $this->assertSame($attributes, $this->generator->generateClassAttributes($class)); + $this->assertEquals($attributes, $this->generator->generateClassAttributes($class)); } public function provideGenerateClassAttributesCases(): \Generator { - yield 'classical' => [new Class_('Res', new Resource('https://schema.org/Res')), [['ApiResource' => ['iri' => 'https://schema.org/Res']]]]; + yield 'classical' => [new Class_('Res', new RdfResource('https://schema.org/Res')), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])]]; - $class = new Class_('WithOperations', new Resource('https://schema.org/WithOperations')); + $class = new Class_('WithOperations', new RdfResource('https://schema.org/WithOperations')); $class->operations = [ 'item' => ['get' => ['route_name' => 'api_about_get']], 'collection' => [], ]; - yield 'with operations' => [$class, [['ApiResource' => ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []]]]]; + yield 'with operations' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []])]]; - yield 'abstract' => [(new Class_('Abstract', new Resource('https://schema.org/Abstract')))->setIsAbstract(true), []]; + $class = new Class_('Abstract', new RdfResource('https://schema.org/Abstract')); + $class->isAbstract = true; + yield 'abstract' => [$class, []]; - yield 'with short name' => [(new Class_('WithShortName', new Resource('https://schema.org/DifferentLocalName'))), [['ApiResource' => ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName']]]]; + yield 'with short name' => [(new Class_('WithShortName', new RdfResource('https://schema.org/DifferentLocalName'))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; - $class = new Class_('WithSecurity', new Resource('https://schema.org/WithSecurity')); + $class = new Class_('WithSecurity', new RdfResource('https://schema.org/WithSecurity')); $class->security = "is_granted('ROLE_USER')"; - yield 'with security' => [$class, [['ApiResource' => ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"]]]]; + yield 'with security' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"])]]; } /** @@ -79,19 +83,19 @@ public function provideGenerateClassAttributesCases(): \Generator */ public function testGeneratePropertyAttributes(Property $property, array $attributes): void { - $this->assertSame($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); + $this->assertEquals($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); } public function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); - $property->resource = new Resource('https://schema.org/prop'); - yield 'classical' => [$property, [['ApiProperty' => ['iri' => 'https://schema.org/prop']]]]; + $property->resource = new RdfResource('https://schema.org/prop'); + yield 'classical' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/prop'])]]; $property = new Property('WithSecurity'); - $property->resource = new Resource('https://schema.org/WithSecurity'); + $property->resource = new RdfResource('https://schema.org/WithSecurity'); $property->security = "is_granted('ROLE_ADMIN')"; - yield 'with security' => [$property, [['ApiProperty' => ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_ADMIN')"]]]]; + yield 'with security' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_ADMIN')"])]]; } public function testGenerateCustomPropertyAttributes(): void @@ -101,13 +105,13 @@ public function testGenerateCustomPropertyAttributes(): void public function testGenerateUses(): void { - $this->assertSame([ApiResource::class, ApiProperty::class], $this->generator->generateUses(new Class_('Res', new Resource('https://schema.org/Res', new Graph())))); + $this->assertEquals([new Use_(ApiResource::class), new Use_(ApiProperty::class)], $this->generator->generateUses(new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); } public function testGenerateNoUsesForEnum(): void { - $graph = new Graph(); - $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $graph = new RdfGraph(); + $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); $this->assertSame([], $this->generator->generateUses(new Class_('MyEnum', $myEnum))); } diff --git a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php index a664861e..b9f83ff0 100644 --- a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php @@ -14,13 +14,15 @@ namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\TypesGenerator; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -47,27 +49,27 @@ protected function setUp(): void */ public function testGenerateClassAttributes(Class_ $class, array $attributes): void { - $this->assertSame($attributes, $this->generator->generateClassAttributes($class)); + $this->assertEquals($attributes, $this->generator->generateClassAttributes($class)); } public function provideGenerateClassAttributesCases(): \Generator { - $graph = new Graph(); - $resource = new Resource('https://schema.org/Enum', $graph); + $graph = new RdfGraph(); + $resource = new RdfResource('https://schema.org/Enum', $graph); $resource->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); yield 'enum' => [new Class_('Enum', $resource), []]; - $graph = new Graph(); - $class = new Class_('Foo', new Resource('https://schema.org/Foo', $graph)); + $graph = new RdfGraph(); + $class = new Class_('Foo', new RdfResource('https://schema.org/Foo', $graph)); $uniqueProperty = new Property('bar'); $uniqueProperty->isUnique = true; $class->addProperty($uniqueProperty); - yield 'one unique property' => [$class, [['UniqueEntity' => ['bar']]]]; + yield 'one unique property' => [$class, [new Attribute('UniqueEntity', ['bar'])]]; - $graph = new Graph(); - $class = new Class_('Foo', new Resource('https://schema.org/Foo', $graph)); + $graph = new RdfGraph(); + $class = new Class_('Foo', new RdfResource('https://schema.org/Foo', $graph)); $uniqueProperty = new Property('bar'); $uniqueProperty->isUnique = true; $class->addProperty($uniqueProperty); @@ -75,7 +77,7 @@ public function provideGenerateClassAttributesCases(): \Generator $uniqueProperty->isUnique = true; $class->addProperty($uniqueProperty); - yield 'multiple unique properties' => [$class, [['UniqueEntity' => ['fields' => ['bar', 'baz']]]]]; + yield 'multiple unique properties' => [$class, [new Attribute('UniqueEntity', ['fields' => ['bar', 'baz']])]]; } /** @@ -83,38 +85,38 @@ public function provideGenerateClassAttributesCases(): \Generator */ public function testGeneratePropertyAttributes(Property $property, array $attributes): void { - $this->assertSame($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); + $this->assertEquals($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); } public function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); $property->isId = true; - yield 'uuid' => [$property, [['Assert\Uuid' => []]]]; + yield 'uuid' => [$property, [new Attribute('Assert\Uuid')]]; $property = new Property('prop'); - $property->range = new Resource('https://schema.org/email'); - $property->resource = new Resource('https://schema.org/email'); + $property->range = new RdfResource('https://schema.org/email'); + $property->resource = new RdfResource('https://schema.org/email'); $property->isNullable = false; - yield 'email' => [$property, [['Assert\Email' => []], ['Assert\NotNull' => []]]]; + yield 'email' => [$property, [new Attribute('Assert\Email'), new Attribute('Assert\NotNull')]]; $property = new Property('prop'); - $property->range = new Resource('https://schema.org/Enum'); + $property->range = new RdfResource('https://schema.org/Enum'); $property->rangeName = 'Enum'; $property->isEnum = true; $property->isArray = true; - yield 'enum' => [$property, [['Assert\Choice' => ['callback' => ['Enum', 'toArray'], 'multiple' => true]]]]; + yield 'enum' => [$property, [new Attribute('Assert\Choice', ['callback' => ['Enum', 'toArray'], 'multiple' => true])]]; } public function testGenerateUses(): void { - $this->assertSame(['Symfony\Component\Validator\Constraints as Assert', UniqueEntity::class], $this->generator->generateUses(new Class_('Res', new Resource('https://schema.org/Res', new Graph())))); + $this->assertEquals([new Use_('Symfony\Component\Validator\Constraints', 'Assert'), new Use_(UniqueEntity::class)], $this->generator->generateUses(new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); } public function testGenerateNoUsesForEnum(): void { - $graph = new Graph(); - $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $graph = new RdfGraph(); + $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); $this->assertSame([], $this->generator->generateUses(new Class_('MyEnum', $myEnum))); } diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 2c81b7de..a546f41b 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -15,15 +15,18 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineMongoDBAttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\TypesGenerator; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; +use Symfony\Component\Config\Definition\Processor; class DoctrineMongoDBAttributeGeneratorTest extends TestCase { @@ -33,58 +36,62 @@ class DoctrineMongoDBAttributeGeneratorTest extends TestCase protected function setUp(): void { - $graph = new Graph(); + $graph = new RdfGraph(); - $product = new Class_('Product', new Resource('https://schema.org/Product', $graph)); - $product->setIsAbstract(true); + $product = new Class_('Product', new RdfResource('https://schema.org/Product', $graph)); + $product->isAbstract = true; $this->classMap[$product->name()] = $product; - $vehicle = new Class_('Vehicle', new Resource('htts://schema.org/Vehicle', $graph)); + $vehicle = new Class_('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; - $idProperty->range = new Resource('https://schema.org/identifier'); + $idProperty->range = new RdfResource('https://schema.org/identifier'); $idProperty->isId = true; $vehicle->addProperty($idProperty); $enumProperty = new Property('enum'); $enumProperty->rangeName = 'Thing'; - $enumProperty->range = new Resource('https://schema.org/Thing'); + $enumProperty->range = new RdfResource('https://schema.org/Thing'); $enumProperty->isEnum = true; $enumProperty->isArray = true; $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); $collectionProperty->rangeName = 'Thing'; - $collectionProperty->range = new Resource('https://schema.org/Thing'); + $collectionProperty->range = new RdfResource('https://schema.org/Thing'); $collectionProperty->isArray = true; $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); $weightProperty->rangeName = 'nonPositiveInteger'; - $weightProperty->range = new Resource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); + $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); $vehicle->addProperty($weightProperty); $relationProperty = new Property('relation'); $relationProperty->rangeName = 'Person'; - $relationProperty->range = new Resource('https://schema.org/Person'); + $relationProperty->range = new RdfResource('https://schema.org/Person'); $relationProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $vehicle->addProperty($relationProperty); $relationsProperty = new Property('relations'); $relationsProperty->rangeName = 'Person'; - $relationsProperty->range = new Resource('https://schema.org/Person'); + $relationsProperty->range = new RdfResource('https://schema.org/Person'); $relationsProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; $vehicle->addProperty($relationsProperty); $this->classMap[$vehicle->name()] = $vehicle; - $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); $myEnumClass = new Class_('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; + $configuration = new TypesGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [['id' => ['generationStrategy' => 'auto', 'writable' => true], 'types' => ['MyEnum' => null, 'Product' => null, 'Vehicle' => null]]]); + $this->generator = new DoctrineMongoDBAttributeGenerator( new PhpTypeConverter(), new NullLogger(), InflectorFactory::create()->build(), [], [], - ['id' => ['generationStrategy' => 'auto', 'writable' => true]], + $processedConfiguration, $this->classMap ); } @@ -92,34 +99,34 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); - $this->assertSame([['MongoDB\MappedSuperclass' => []]], $this->generator->generateClassAttributes($this->classMap['Product'])); - $this->assertSame([['MongoDB\Document' => []]], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); + $this->assertEquals([new Attribute('MongoDB\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); + $this->assertEquals([new Attribute('MongoDB\Document')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); } public function testGenerateFieldAttributes(): void { - $this->assertSame( - [['MongoDB\Id' => ['strategy' => 'INCREMENT']]], + $this->assertEquals( + [new Attribute('MongoDB\Id', ['strategy' => 'INCREMENT'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('id'), 'Vehicle') ); - $this->assertSame( - [['MongoDB\Field' => ['type' => 'simple_array']]], + $this->assertEquals( + [new Attribute('MongoDB\Field', ['type' => 'simple_array'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('enum'), 'Vehicle') ); - $this->assertSame( - [['MongoDB\Field' => ['type' => 'collection']]], + $this->assertEquals( + [new Attribute('MongoDB\Field', ['type' => 'collection'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('collection'), 'Vehicle') ); - $this->assertSame( - [['MongoDB\Field' => ['type' => 'integer']]], + $this->assertEquals( + [new Attribute('MongoDB\Field', ['type' => 'integer'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') ); - $this->assertSame( - [['MongoDB\ReferenceOne' => ['targetDocument' => 'Person', 'simple' => true]]], + $this->assertEquals( + [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => 'Person', 'simple' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation'), 'Vehicle') ); - $this->assertSame( - [['MongoDB\ReferenceMany' => ['targetDocument' => 'Person', 'simple' => true]]], + $this->assertEquals( + [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => 'Person', 'simple' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relations'), 'Vehicle') ); } diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index da7d2c8c..3495fef6 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -15,15 +15,18 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\TypesGenerator; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; +use Symfony\Component\Config\Definition\Processor; /** * @author Erik Saunier @@ -36,93 +39,97 @@ class DoctrineOrmAttributeGeneratorTest extends TestCase protected function setUp(): void { - $graph = new Graph(); + $graph = new RdfGraph(); - $product = new Class_('Product', new Resource('https://schema.org/Product', $graph)); - $product->setIsAbstract(true); + $product = new Class_('Product', new RdfResource('https://schema.org/Product', $graph)); + $product->isAbstract = true; $this->classMap[$product->name()] = $product; - $vehicle = new Class_('Vehicle', new Resource('htts://schema.org/Vehicle', $graph)); + $vehicle = new Class_('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; - $idProperty->range = new Resource('https://schema.org/identifier'); + $idProperty->range = new RdfResource('https://schema.org/identifier'); $idProperty->isId = true; $vehicle->addProperty($idProperty); $enumProperty = new Property('enum'); $enumProperty->rangeName = 'Thing'; - $enumProperty->range = new Resource('https://schema.org/Thing'); + $enumProperty->range = new RdfResource('https://schema.org/Thing'); $enumProperty->isEnum = true; $enumProperty->isArray = true; $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); $collectionProperty->rangeName = 'Thing'; - $collectionProperty->range = new Resource('https://schema.org/Thing'); + $collectionProperty->range = new RdfResource('https://schema.org/Thing'); $collectionProperty->isArray = true; $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); $weightProperty->rangeName = 'nonPositiveInteger'; - $weightProperty->range = new Resource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); + $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); $vehicle->addProperty($weightProperty); $prefixedWeightProperty = new Property('prefixedWeight'); $prefixedWeightProperty->columnPrefix = 'weight_'; $prefixedWeightProperty->isEmbedded = true; $prefixedWeightProperty->rangeName = 'QuantitativeValue'; - $prefixedWeightProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $prefixedWeightProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $vehicle->addProperty($prefixedWeightProperty); $relation01Property = new Property('relation0_1'); $relation01Property->rangeName = 'QuantitativeValue'; - $relation01Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relation01Property->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation01Property->cardinality = CardinalitiesExtractor::CARDINALITY_0_1; $vehicle->addProperty($relation01Property); $relation11Property = new Property('relation1_1'); $relation11Property->rangeName = 'QuantitativeValue'; - $relation11Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relation11Property->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation11Property->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $vehicle->addProperty($relation11Property); $relationN0Property = new Property('relationN_0'); $relationN0Property->rangeName = 'QuantitativeValue'; - $relationN0Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relationN0Property->range = new RdfResource('https://schema.org/QuantitativeValue'); $relationN0Property->cardinality = CardinalitiesExtractor::CARDINALITY_N_0; $vehicle->addProperty($relationN0Property); $relationN1Property = new Property('relationN_1'); $relationN1Property->rangeName = 'QuantitativeValue'; - $relationN1Property->range = new Resource('https://schema.org/QuantitativeValue'); + $relationN1Property->range = new RdfResource('https://schema.org/QuantitativeValue'); $relationN1Property->cardinality = CardinalitiesExtractor::CARDINALITY_N_1; $vehicle->addProperty($relationN1Property); $relation0NProperty = new Property('relation0_N'); $relation0NProperty->rangeName = 'QuantitativeValue'; - $relation0NProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $relation0NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation0NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_0_N; $vehicle->addProperty($relation0NProperty); $relation1NProperty = new Property('relation1_N'); $relation1NProperty->rangeName = 'QuantitativeValue'; - $relation1NProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $relation1NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation1NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; $vehicle->addProperty($relation1NProperty); $relationNNProperty = new Property('relationN_N'); $relationNNProperty->rangeName = 'QuantitativeValue'; - $relationNNProperty->range = new Resource('https://schema.org/QuantitativeValue'); + $relationNNProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relationNNProperty->cardinality = CardinalitiesExtractor::CARDINALITY_N_N; $vehicle->addProperty($relationNNProperty); $this->classMap[$vehicle->name()] = $vehicle; - $quantitativeValue = new Class_('QuantitativeValue', new Resource('https://schema.org/QuantitativeValue', $graph)); - $quantitativeValue->setEmbeddable(true); + $quantitativeValue = new Class_('QuantitativeValue', new RdfResource('https://schema.org/QuantitativeValue', $graph)); + $quantitativeValue->isEmbeddable = true; $this->classMap[$quantitativeValue->name()] = $quantitativeValue; - $myEnum = new Resource('https://schema.org/MyEnum', $graph); + $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); $myEnumClass = new Class_('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; + $configuration = new TypesGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [['id' => ['generationStrategy' => 'auto', 'writable' => true], 'types' => ['MyEnum' => null, 'Product' => null, 'Vehicle' => null, 'QuantitativeValue' => null]]]); + $this->generator = new DoctrineOrmAttributeGenerator( new PhpTypeConverter(), new NullLogger(), InflectorFactory::create()->build(), [], [], - ['id' => ['generationStrategy' => 'auto', 'writable' => true]], + $processedConfiguration, $this->classMap ); } @@ -130,59 +137,59 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); - $this->assertSame([['ORM\MappedSuperclass' => []]], $this->generator->generateClassAttributes($this->classMap['Product'])); - $this->assertSame([['ORM\Entity' => []]], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); - $this->assertSame([['ORM\Embeddable' => []]], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); + $this->assertEquals([new Attribute('ORM\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); + $this->assertEquals([new Attribute('ORM\Entity')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); + $this->assertEquals([new Attribute('ORM\Embeddable')], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); } public function testGenerateFieldAttributes(): void { - $this->assertSame( - [['ORM\Id' => []], ['ORM\Column' => ['type' => 'integer']]], + $this->assertEquals( + [new Attribute('ORM\Id'), new Attribute('ORM\Column', ['type' => 'integer'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('id'), 'Vehicle') ); - $this->assertSame( - [['ORM\Column' => ['type' => 'simple_array', 'nullable' => true]]], + $this->assertEquals( + [new Attribute('ORM\Column', ['type' => 'simple_array', 'nullable' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('enum'), 'Vehicle') ); - $this->assertSame( - [['ORM\Column' => ['type' => 'json', 'nullable' => true]]], + $this->assertEquals( + [new Attribute('ORM\Column', ['type' => 'json', 'nullable' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('collection'), 'Vehicle') ); - $this->assertSame( - [['ORM\Column' => ['type' => 'integer', 'nullable' => true]]], + $this->assertEquals( + [new Attribute('ORM\Column', ['type' => 'integer', 'nullable' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') ); - $this->assertSame( - [['ORM\Embedded' => ['class' => 'QuantitativeValue', 'columnPrefix' => 'weight_']]], + $this->assertEquals( + [new Attribute('ORM\Embedded', ['class' => 'App\Entity\QuantitativeValue', 'columnPrefix' => 'weight_'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('prefixedWeight'), 'Vehicle') ); - $this->assertSame( - [['ORM\OneToOne' => ['targetEntity' => 'QuantitativeValue']]], + $this->assertEquals( + [new Attribute('ORM\OneToOne', ['targetEntity' => 'App\Entity\QuantitativeValue'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation0_1'), 'Vehicle') ); - $this->assertSame( - [['ORM\OneToOne' => ['targetEntity' => 'QuantitativeValue']], ['ORM\JoinColumn' => ['nullable' => false]]], + $this->assertEquals( + [new Attribute('ORM\OneToOne', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinColumn', ['nullable' => false])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_1'), 'Vehicle') ); - $this->assertSame( - [['ORM\ManyToOne' => ['targetEntity' => 'QuantitativeValue']]], + $this->assertEquals( + [new Attribute('ORM\ManyToOne', ['targetEntity' => 'App\Entity\QuantitativeValue'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_0'), 'Vehicle') ); - $this->assertSame( - [['ORM\ManyToOne' => ['targetEntity' => 'QuantitativeValue']], ['ORM\JoinColumn' => ['nullable' => false]]], + $this->assertEquals( + [new Attribute('ORM\ManyToOne', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinColumn', ['nullable' => false])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_1'), 'Vehicle') ); - $this->assertSame( - [['ORM\ManyToMany' => ['targetEntity' => 'QuantitativeValue']], ['ORM\InverseJoinColumn' => ['unique' => true]]], + $this->assertEquals( + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\InverseJoinColumn', ['unique' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation0_N'), 'Vehicle') ); - $this->assertSame( - [['ORM\ManyToMany' => ['targetEntity' => 'QuantitativeValue']], ['ORM\InverseJoinColumn' => ['nullable' => false, 'unique' => true]]], + $this->assertEquals( + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N'), 'Vehicle') ); - $this->assertSame( - [['ORM\ManyToMany' => ['targetEntity' => 'QuantitativeValue']]], + $this->assertEquals( + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle') ); } diff --git a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php index ea5a5984..762591d2 100644 --- a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php @@ -14,6 +14,7 @@ namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use Doctrine\Inflector\InflectorFactory; @@ -43,6 +44,6 @@ public function testGeneratePropertyAttributes(): void $property->isId = false; $property->groups = ['group']; - $this->assertSame([['Groups' => [['group']]]], $this->generator->generatePropertyAttributes($property, 'Res')); + $this->assertEquals([new Attribute('Groups', [['group']])], $this->generator->generatePropertyAttributes($property, 'Res')); } } diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 965e6924..62aa3cec 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -75,7 +75,7 @@ public function testDumpConfiguration(): void 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: @@ -98,7 +98,7 @@ interface: App\Model # Example: App\Model # 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 attributes (if set, no other attributes are generated) diff --git a/tests/Model/ClassTest.php b/tests/Model/ClassTest.php index f595a3b5..b438479a 100644 --- a/tests/Model/ClassTest.php +++ b/tests/Model/ClassTest.php @@ -16,31 +16,37 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Interface_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; -use EasyRdf\Resource; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Processor; class ClassTest extends TestCase { - public function testClass() + public function testClass(): void { $inflector = InflectorFactory::create()->build(); $property = new Property('author'); $property->typeHint = "App\Entity\Author"; $property->addAnnotation('@see https://schema.org/Author'); - $class = new Class_('Book', new Resource('http//schema.org/Book', new Graph())); - $class->withNamespace("App\Entity"); - $class->withInterface(new Interface_('Printable', 'OtherApp\Interfaces')); - $class->addUse('OtherApp\Interfaces\Printable'); + $class = new Class_('Book', new RdfResource('http//schema.org/Book', new RdfGraph())); + $class->namespace = 'App\Entity'; + $class->interface = new Interface_('Printable', 'OtherApp\Interfaces'); + $class->addUse(new Use_('OtherApp\Interfaces\Printable')); $class->addProperty($property); - $generated = (string) $class->toNetteFile([ + $configuration = new TypesGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'doctrine' => ['useCollection' => false], - 'accessorMethods' => true, 'fluentMutatorMethods' => true, - ], $inflector); + ]]); + + $generated = (string) $class->toNetteFile($processedConfiguration, $inflector); $this->assertStringContainsString('class Book', $generated); $this->assertStringContainsString('namespace App\Entity;', $generated); @@ -51,12 +57,12 @@ public function testClass() $this->assertStringContainsString('private ?Author $author = null;', $generated); $this->assertStringContainsString('public function setAuthor(?Author $author): self', $generated); $this->assertStringContainsString('public function getAuthor(): ?Author', $generated); - $this->assertFalse($class->isEmbeddable()); - $this->assertFalse($class->hasChild()); + $this->assertFalse($class->isEmbeddable); + $this->assertFalse($class->hasChild); $this->assertFalse($class->hasParent()); - $this->assertFalse($class->hasConstructor()); + $this->assertFalse($class->hasConstructor); $this->assertFalse($class->isEnum()); - $this->assertFalse($class->isAbstract()); + $this->assertFalse($class->isAbstract); $this->assertTrue($class->isInNamespace('App\Entity')); $this->assertEquals('Book', $class->resourceLocalName()); $this->assertEquals('http//schema.org/Book', $class->resourceUri()); diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index fb4c783e..94f6d2f6 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -20,10 +20,12 @@ use ApiPlatform\SchemaGenerator\TypesGenerator; use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\RdfNamespace; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Psr\Log\NullLogger; +use Symfony\Component\Config\Definition\Processor; use Twig\Environment; /** @@ -33,6 +35,11 @@ class TypesGeneratorTest extends TestCase { use ProphecyTrait; + protected function setUp(): void + { + RdfNamespace::set('schema', 'https://schema.org/'); + } + public function testGenerate(): void { $twigProphecy = $this->prophesize(Environment::class); @@ -58,7 +65,11 @@ public function testGenerate(): void ); $outputDir = 'build/type-generator-test'; - $typesGenerator->generate($this->getConfig($outputDir)); + $configuration = new TypesGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [$this->getConfig()]); + $processedConfiguration['output'] = $outputDir; + $typesGenerator->generate($processedConfiguration); $article = file_get_contents("$outputDir/App/Entity/Article.php"); $this->assertStringContainsString('abstract class Article extends CreativeWork', $article); @@ -122,9 +133,12 @@ public function getName(): ?string PHP, $thing); } + /** + * @return RdfGraph[] + */ private function getGraphs(): array { - $graph = new Graph(); + $graph = new RdfGraph(); $graph->addResource('https://schema.org/Article', 'rdf:type', 'rdfs:Class'); $graph->addResource('https://schema.org/Article', 'rdfs:subClassOf', 'https://schema.org/CreativeWork'); @@ -178,6 +192,9 @@ private function getGraphs(): array return [$graph]; } + /** + * @return array + */ private function getCardinalities(): array { return [ @@ -192,30 +209,36 @@ private function getCardinalities(): array ]; } - private function getConfig(string $outputDir): array + /** + * @return array{ + * annotationGenerators: string[], + * attributeGenerators: string[], + * types: array + * }> + * } + */ + private function getConfig(): array { return [ 'annotationGenerators' => [ ], 'attributeGenerators' => [ ], - 'checkIsGoodRelations' => false, - 'namespaces' => [ - 'entity' => 'App\Entity', - ], - 'output' => $outputDir, - 'allTypes' => false, 'types' => [ 'Article' => [ - 'allProperties' => false, + 'parent' => null, 'properties' => [ 'articleBody' => null, 'articleSection' => null, ], - 'vocabularyNamespace' => TypesGeneratorConfiguration::SCHEMA_ORG_NAMESPACE, ], 'CreativeWork' => [ - 'allProperties' => false, + 'parent' => null, 'properties' => [ 'author' => [ 'cardinality' => CardinalitiesExtractor::CARDINALITY_N_0, @@ -225,38 +248,25 @@ private function getConfig(string $outputDir): array 'headline' => null, 'isFamilyFriendly' => null, ], - 'vocabularyNamespace' => TypesGeneratorConfiguration::SCHEMA_ORG_NAMESPACE, ], 'BlogPosting' => [ + 'parent' => null, 'allProperties' => true, 'properties' => null, - 'vocabularyNamespace' => TypesGeneratorConfiguration::SCHEMA_ORG_NAMESPACE, ], 'Person' => [ - 'allProperties' => false, + 'parent' => null, 'properties' => [], - 'vocabularyNamespace' => TypesGeneratorConfiguration::SCHEMA_ORG_NAMESPACE, ], 'SocialMediaPosting' => [ + 'parent' => null, 'allProperties' => true, - 'vocabularyNamespace' => TypesGeneratorConfiguration::SCHEMA_ORG_NAMESPACE, ], 'Thing' => [ + 'parent' => null, 'allProperties' => true, - 'vocabularyNamespace' => TypesGeneratorConfiguration::SCHEMA_ORG_NAMESPACE, ], ], - 'id' => [ - 'generate' => true, - 'generationStrategy' => 'auto', - 'writable' => false, - 'onClass' => 'child', - ], - 'useInterface' => false, - 'doctrine' => [ - 'useCollection' => true, - 'resolveTargetEntityConfigPath' => null, - ], ]; } } diff --git a/tests/config/address-book.yaml b/tests/config/address-book.yaml index fc561527..86d2d773 100644 --- a/tests/config/address-book.yaml +++ b/tests/config/address-book.yaml @@ -4,7 +4,6 @@ namespaces: # The list of types and properties we want to use types: Person: - parent: false properties: name: ~ familyName: ~ @@ -26,8 +25,6 @@ types: url: ~ friends: { range: "Person", cardinality: (0..*) } 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: "https://schema.org/Text" } @@ -37,7 +34,6 @@ types: postalCode: ~ streetAddress: ~ Organization: - parent: false properties: name: ~ # Custom property with custom ORM\Column content diff --git a/tests/config/ecommerce.yaml b/tests/config/ecommerce.yaml index 9a7f8cc7..a548ede6 100644 --- a/tests/config/ecommerce.yaml +++ b/tests/config/ecommerce.yaml @@ -47,7 +47,6 @@ types: properties: logo: { range: 'ImageObject' } Seller: - parent: false guessFrom: Person properties: name: ~ @@ -75,10 +74,10 @@ types: priceCurrency: ~ validFrom: ~ validThrough: ~ - DeliveryChargeSpecification: { parent: false } - PaymentChargeSpecification: { parent: false } + DeliveryChargeSpecification: ~ + PaymentChargeSpecification: ~ OfferItemCondition: ~ PaymentMethod: ~ ItemAvailability: ~ DeliveryMethod: ~ - QuantitativeValue: { parent: false } + QuantitativeValue: ~ diff --git a/tests/config/enum.yaml b/tests/config/enum.yaml index 7ecf73b4..c29247bb 100644 --- a/tests/config/enum.yaml +++ b/tests/config/enum.yaml @@ -5,5 +5,4 @@ types: properties: gender: { range: GenderType } GenderType: - parent: false guessFrom: GenderType diff --git a/tests/config/fluent-mutators.yaml b/tests/config/fluent-mutators.yaml index b677ea57..5a162430 100644 --- a/tests/config/fluent-mutators.yaml +++ b/tests/config/fluent-mutators.yaml @@ -22,7 +22,6 @@ types: url: ~ friends: { range: "Person", cardinality: (0..*) } PostalAddress: - # Disable the generation of the class hierarchy for this type properties: # Force the type of the addressCountry property to text addressCountry: { range: "Text" } diff --git a/tests/config/mongodb/address-book.yaml b/tests/config/mongodb/address-book.yaml index 11d6513d..fabde6fc 100644 --- a/tests/config/mongodb/address-book.yaml +++ b/tests/config/mongodb/address-book.yaml @@ -11,7 +11,6 @@ id: # The list of types and properties we want to use types: Person: - parent: false properties: name: ~ familyName: ~ @@ -32,8 +31,6 @@ types: url: ~ friends: { range: "https://schema.org/Person", cardinality: (0..*) } 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: "https://schema.org/Text" } @@ -43,6 +40,5 @@ types: postalCode: ~ streetAddress: ~ Organization: - parent: false properties: name: ~ diff --git a/tests/config/mongodb/ecommerce.yaml b/tests/config/mongodb/ecommerce.yaml index a42d8a67..6204dec9 100644 --- a/tests/config/mongodb/ecommerce.yaml +++ b/tests/config/mongodb/ecommerce.yaml @@ -54,7 +54,6 @@ types: properties: logo: { range: 'https://schema.org/ImageObject' } Seller: - parent: false guessFrom: Person properties: name: ~ @@ -82,10 +81,10 @@ types: priceCurrency: ~ validFrom: ~ validThrough: ~ - DeliveryChargeSpecification: { parent: false } - PaymentChargeSpecification: { parent: false } + DeliveryChargeSpecification: ~ + PaymentChargeSpecification: ~ OfferItemCondition: ~ PaymentMethod: ~ ItemAvailability: ~ DeliveryMethod: ~ - QuantitativeValue: { parent: false } + QuantitativeValue: ~ diff --git a/tests/config/public-properties.yaml b/tests/config/public-properties.yaml index 20a34e9f..00022979 100644 --- a/tests/config/public-properties.yaml +++ b/tests/config/public-properties.yaml @@ -23,7 +23,6 @@ types: url: ~ friends: { range: "Person", cardinality: (0..*) } PostalAddress: - # Disable the generation of the class hierarchy for this type properties: # Force the type of the addressCountry property to text addressCountry: { range: "Text" } diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 168ab15d..7f8b8873 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -29,8 +29,6 @@ types: url: ~ customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } PostalAddress: - # Disable the generation of the class hierarchy for this type - parent: false properties: addressCountry: { range: https://schema.org/Text } addressLocality: ~ From 669b9753c070349552677e96a6be751ba09da19e Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Mon, 22 Nov 2021 15:43:15 +0100 Subject: [PATCH 195/258] fix: manage correctly non defined type in configuration (#355) --- .../DoctrineMongoDBAttributeGenerator.php | 4 +- .../DoctrineOrmAttributeGenerator.php | 6 +- src/ClassMutator/ClassParentMutator.php | 6 +- src/ClassMutator/ClassPropertiesAppender.php | 23 ++-- src/PropertyGenerator/PropertyGenerator.php | 6 +- src/TypesGenerator.php | 12 +- .../DoctrineMongoDBAttributeGeneratorTest.php | 14 +- .../DoctrineOrmAttributeGeneratorTest.php | 14 +- tests/ClassMutator/ClassParentMutatorTest.php | 88 ++++++++++++ .../ClassPropertiesAppenderTest.php | 126 ++++++++++++++++++ 10 files changed, 273 insertions(+), 26 deletions(-) create mode 100644 tests/ClassMutator/ClassParentMutatorTest.php create mode 100644 tests/ClassMutator/ClassPropertiesAppenderTest.php diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index c2c74ed8..c7324027 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -31,7 +31,7 @@ final class DoctrineMongoDBAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($doctrineAttributes = $this->config['types'][$class->name()]['doctrine']['attributes']) { + if ($doctrineAttributes = isset($this->config['types'][$class->name()]) ? $this->config['types'][$class->name()]['doctrine']['attributes'] : false) { $attributes = []; foreach ($doctrineAttributes as $attributeName => $attributeArgs) { $attributes[] = new Attribute($attributeName, $attributeArgs); @@ -46,7 +46,7 @@ public function generateClassAttributes(Class_ $class): array $attributes = []; if ($class->isAbstract) { - if ($inheritanceAttributes = ($this->config['doctrine']['inheritanceAttributes'])) { + if ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes']) { $attributes = []; foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { $attributes[] = new Attribute($attributeName, $attributeArgs); diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index b58406a3..b35660bd 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -42,7 +42,7 @@ final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($doctrineAttributes = $this->config['types'][$class->name()]['doctrine']['attributes']) { + if ($doctrineAttributes = (isset($this->config['types'][$class->name()]) ? $this->config['types'][$class->name()]['doctrine']['attributes'] : false)) { $attributes = []; foreach ($doctrineAttributes as $attributeName => $attributeArgs) { $attributes[] = new Attribute($attributeName, $attributeArgs); @@ -288,14 +288,14 @@ private function getRelationName(string $rangeName): ?string if (null !== $class->interfaceName()) { if (isset($this->config['types'][$rangeName]['namespaces']['interface'])) { - return sprintf('%s\\%s', $this->config['types'][$class->name()]['namespaces']['interface'], $class->interfaceName()); + return sprintf('%s\\%s', $this->config['types'][$rangeName]['namespaces']['interface'], $class->interfaceName()); } return sprintf('%s\\%s', $this->config['namespaces']['interface'], $class->interfaceName()); } if (isset($this->config['types'][$rangeName]['namespaces']['class'])) { - return sprintf('%s\\%s', $this->config['types'][$class->name()]['namespaces']['class'], $class->name()); + return sprintf('%s\\%s', $this->config['types'][$rangeName]['namespaces']['class'], $class->name()); } return sprintf('%s\\%s', $this->config['namespaces']['entity'], $rangeName); diff --git a/src/ClassMutator/ClassParentMutator.php b/src/ClassMutator/ClassParentMutator.php index f56911f4..852fe720 100644 --- a/src/ClassMutator/ClassParentMutator.php +++ b/src/ClassMutator/ClassParentMutator.php @@ -37,8 +37,8 @@ public function __construct(array $config, PhpTypeConverterInterface $phpTypeCon public function __invoke(Class_ $class): Class_ { - $typeConfig = $this->config['types'][$class->name()]; - $class->withParent($typeConfig['parent']); + $typeConfig = $this->config['types'][$class->name()] ?? null; + $class->withParent($typeConfig['parent'] ?? null); if (null === $class->parent() && $subclassOf = $class->getSubClassOf()) { if (\count($subclassOf) > 1) { @@ -51,7 +51,7 @@ public function __invoke(Class_ $class): Class_ if ($class->hasParent() && isset($this->config['types'][$class->parent()]['namespaces']['class'])) { $parentNamespace = $this->config['types'][$class->parent()]['namespaces']['class']; - if ($class->isInNamespace($parentNamespace)) { + if (!$class->isInNamespace($parentNamespace)) { $class->addUse(new Use_($parentNamespace.'\\'.$class->parent())); } } diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 3344aff3..4da0eed0 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -53,9 +53,9 @@ public function __construct(PropertyGenerator $propertyGenerator, LoggerInterfac public function __invoke(Class_ $class): Class_ { - $typeConfig = $this->config['types'][$class->name()]; + $typeConfig = $this->config['types'][$class->name()] ?? null; - if (!$typeConfig['allProperties']) { + if (null !== $typeConfig && !$typeConfig['allProperties']) { foreach ($typeConfig['properties'] as $key => $value) { if ($value['exclude']) { continue; @@ -75,9 +75,12 @@ public function __invoke(Class_ $class): Class_ $class = $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); } } else { - $remainingProperties = $typeConfig['properties']; + $remainingProperties = $typeConfig['properties'] ?? []; + if (!isset($this->propertiesMap[$class->resourceUri()])) { + $this->logger->warning(sprintf('Properties for "%s" not found in the map.', $class->resourceUri())); + } // All properties - foreach ($this->propertiesMap[$class->resourceUri()] as $property) { + foreach ($this->propertiesMap[$class->resourceUri()] ?? [] as $property) { unset($remainingProperties[$property->localName()]); if ($property->hasProperty(self::SCHEMA_ORG_SUPERSEDED_BY)) { $supersededBy = $property->get(self::SCHEMA_ORG_SUPERSEDED_BY); @@ -101,10 +104,10 @@ public function __invoke(Class_ $class): Class_ /** * Add custom fields (not defined in the vocabulary). * - * @param TypeConfiguration $typeConfig - * @param Configuration $config + * @param ?TypeConfiguration $typeConfig + * @param Configuration $config */ - private function generateCustomField(string $propertyName, RdfResource $type, array $typeConfig, Class_ $class, array $config): Class_ + private function generateCustomField(string $propertyName, RdfResource $type, ?array $typeConfig, Class_ $class, array $config): Class_ { $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())); $customResource = new RdfResource('_:'.$propertyName, new RdfGraph()); @@ -116,10 +119,10 @@ private function generateCustomField(string $propertyName, RdfResource $type, ar /** * Updates generated $class with given field config. * - * @param Configuration $config - * @param TypeConfiguration $typeConfig + * @param Configuration $config + * @param ?TypeConfiguration $typeConfig */ - private function generateField(array $config, Class_ $class, RdfResource $type, array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ + private function generateField(array $config, Class_ $class, RdfResource $type, ?array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ { return ($this->propertyGenerator)($config, $class, $type, $typeConfig, $property, $isCustom); } diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index 30da2509..e810f3de 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -50,10 +50,10 @@ public function __construct(GoodRelationsBridge $goodRelationsBridge, PhpTypeCon } /** - * @param Configuration $config - * @param TypeConfiguration $typeConfig + * @param Configuration $config + * @param ?TypeConfiguration $typeConfig */ - public function __invoke(array $config, Class_ $class, RdfResource $type, array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ + public function __invoke(array $config, Class_ $class, RdfResource $type, ?array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ { $typeUri = $type->getUri(); $propertyName = $property->localName(); diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index d1d3c80f..7dbfda23 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -27,6 +27,7 @@ use EasyRdf\Graph as RdfGraph; use EasyRdf\RdfNamespace; use EasyRdf\Resource as RdfResource; +use Nette\InvalidArgumentException as NetteInvalidArgumentException; use PhpCsFixer\Cache\NullCacheManager; use PhpCsFixer\Differ\NullDiffer; use PhpCsFixer\Error\ErrorsManager; @@ -212,7 +213,7 @@ public function generate(array $config): void } $parentConfig = $parentClass->parent() ? ($config['types'][$parentClass->parent()] ?? null) : null; - $parentClass = $parentClass->parent() ? $classes[$parentClass->parent()] : null; + $parentClass = $parentClass->parent() && isset($classes[$parentClass->parent()]) ? $classes[$parentClass->parent()] : null; } } } @@ -252,9 +253,14 @@ public function generate(array $config): void $this->filesystem->mkdir($classDir); $path = sprintf('%s%s.php', $classDir, $className); - $generatedFiles[] = $path; - file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector))); + try { + file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector))); + } catch (NetteInvalidArgumentException $exception) { + $this->logger->warning($exception->getMessage()); + } + + $generatedFiles[] = $path; if (null !== $class->interfaceNamespace()) { $interfaceDir = $this->namespaceToDir($config, $class->interfaceNamespace()); diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index a546f41b..1c178769 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -81,9 +81,20 @@ protected function setUp(): void $myEnumClass = new Class_('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; + $customAttributes = new RdfResource('https://schema.org/CustomAttributes', $graph); + $customAttributesClass = new Class_('CustomAttributes', $customAttributes); + $this->classMap[$customAttributesClass->name()] = $customAttributesClass; + $configuration = new TypesGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ - $processedConfiguration = (new Processor())->processConfiguration($configuration, [['id' => ['generationStrategy' => 'auto', 'writable' => true], 'types' => ['MyEnum' => null, 'Product' => null, 'Vehicle' => null]]]); + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ + 'id' => ['generationStrategy' => 'auto', 'writable' => true], + 'types' => [ + 'CustomAttributes' => ['doctrine' => ['attributes' => ['MongoDB\Document' => ['db' => 'my_db']]]], + 'Product' => null, + // Vehicle is not added deliberately + ], + ]]); $this->generator = new DoctrineMongoDBAttributeGenerator( new PhpTypeConverter(), @@ -99,6 +110,7 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); + $this->assertEquals([new Attribute('MongoDB\Document', ['db' => 'my_db'])], $this->generator->generateClassAttributes($this->classMap['CustomAttributes'])); $this->assertEquals([new Attribute('MongoDB\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); $this->assertEquals([new Attribute('MongoDB\Document')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); } diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index 3495fef6..190afd40 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -119,9 +119,20 @@ protected function setUp(): void $myEnumClass = new Class_('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; + $customAttributes = new RdfResource('https://schema.org/CustomAttributes', $graph); + $customAttributesClass = new Class_('CustomAttributes', $customAttributes); + $this->classMap[$customAttributesClass->name()] = $customAttributesClass; + $configuration = new TypesGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ - $processedConfiguration = (new Processor())->processConfiguration($configuration, [['id' => ['generationStrategy' => 'auto', 'writable' => true], 'types' => ['MyEnum' => null, 'Product' => null, 'Vehicle' => null, 'QuantitativeValue' => null]]]); + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ + 'id' => ['generationStrategy' => 'auto', 'writable' => true], + 'types' => [ + 'CustomAttributes' => ['doctrine' => ['attributes' => ['ORM\Entity' => ['readOnly' => true]]]], + 'Product' => null, + // Vehicle is not added deliberately + ], + ]]); $this->generator = new DoctrineOrmAttributeGenerator( new PhpTypeConverter(), @@ -137,6 +148,7 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); + $this->assertEquals([new Attribute('ORM\Entity', ['readOnly' => true])], $this->generator->generateClassAttributes($this->classMap['CustomAttributes'])); $this->assertEquals([new Attribute('ORM\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); $this->assertEquals([new Attribute('ORM\Entity')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); $this->assertEquals([new Attribute('ORM\Embeddable')], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); diff --git a/tests/ClassMutator/ClassParentMutatorTest.php b/tests/ClassMutator/ClassParentMutatorTest.php new file mode 100644 index 00000000..76f18774 --- /dev/null +++ b/tests/ClassMutator/ClassParentMutatorTest.php @@ -0,0 +1,88 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\ClassMutator; + +use ApiPlatform\SchemaGenerator\ClassMutator\ClassParentMutator; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Use_; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; +use Prophecy\Prophecy\ObjectProphecy; +use Psr\Log\LoggerInterface; +use Symfony\Component\Config\Definition\Processor; + +class ClassParentMutatorTest extends TestCase +{ + use ProphecyTrait; + + private ObjectProphecy $loggerProphecy; + private ClassParentMutator $classParentMutator; + + protected function setUp(): void + { + $this->loggerProphecy = $this->prophesize(LoggerInterface::class); + + $configuration = new TypesGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ + 'types' => [ + 'BlogPosting' => ['parent' => 'SocialMediaPosting'], + 'SocialMediaPosting' => ['namespaces' => ['class' => 'socialMediaNamespace']], + ], + ]]); + + $this->classParentMutator = new ClassParentMutator($processedConfiguration, new PhpTypeConverter(), $this->loggerProphecy->reveal()); + } + + /** + * @dataProvider provideInvokeTestCases + */ + public function testInvoke(Class_ $class, Class_ $expectedClass, ?string $loggerMessage = null): void + { + if ($loggerMessage) { + $this->loggerProphecy->warning($loggerMessage)->shouldBeCalled(); + } + + $this->assertEquals($expectedClass, ($this->classParentMutator)($class)); + } + + /** + * @return \Generator + */ + public function provideInvokeTestCases(): \Generator + { + $graph = new RdfGraph(); + $product = new Class_('Product', new RdfResource('https://schema.org/Product', $graph)); + yield 'no parent' => [clone $product, clone $product]; + + $graph = new RdfGraph(); + $graph->addResource('https://schema.org/CreativeWork', 'rdfs:subClassOf', 'https://schema.org/Thing'); + $creativeWork = new Class_('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph)); + yield 'with subclass' => [clone $creativeWork, (clone $creativeWork)->withParent('Thing')]; + + $graph = new RdfGraph(); + $graph->addResource('https://schema.org/CreativeWork', 'rdfs:subClassOf', 'https://schema.org/Work'); + $graph->addResource('https://schema.org/CreativeWork', 'rdfs:subClassOf', 'https://schema.org/Thing'); + $creativeWork = new Class_('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph)); + yield 'with multiple subclasses' => [clone $creativeWork, (clone $creativeWork)->withParent('Work'), 'The type "https://schema.org/CreativeWork" has several supertypes. Using the first one.']; + + $graph = new RdfGraph(); + $blogPosting = new Class_('BlogPosting', new RdfResource('https://schema.org/BlogPosting', $graph)); + yield 'with parent' => [clone $blogPosting, (clone $blogPosting)->withParent('SocialMediaPosting')->addUse(new Use_('socialMediaNamespace\SocialMediaPosting'))]; + } +} diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php new file mode 100644 index 00000000..2b4b5d6e --- /dev/null +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -0,0 +1,126 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\ClassMutator; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesAppender; +use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator; +use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\TestCase; +use Prophecy\PhpUnit\ProphecyTrait; +use Prophecy\Prophecy\ObjectProphecy; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; +use Symfony\Component\Config\Definition\Processor; + +class ClassPropertiesAppenderTest extends TestCase +{ + use ProphecyTrait; + + private RdfGraph $graph; + private ObjectProphecy $loggerProphecy; + private ClassPropertiesAppender $classPropertiesAppender; + + protected function setUp(): void + { + $this->loggerProphecy = $this->prophesize(LoggerInterface::class); + + $propertyGenerator = new PropertyGenerator(new GoodRelationsBridge([]), new PhpTypeConverter(), [], new NullLogger()); + + $configuration = new TypesGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ + 'types' => [ + 'Person' => ['properties' => ['givenName' => []]], + ], + ]]); + + $this->graph ??= new RdfGraph(); + + $this->graph->addResource('https://schema.org/articleBody', 'rdf:type', 'rdf:Property'); + $this->graph->addResource('https://schema.org/articleBody', 'schema:rangeIncludes', 'https://schema.org/Text'); + + $this->graph->addResource('https://schema.org/articleSection', 'rdf:type', 'rdf:Property'); + $this->graph->addResource('https://schema.org/articleSection', 'schema:rangeIncludes', 'https://schema.org/Text'); + + $this->graph->addResource('https://schema.org/givenName', 'rdf:type', 'rdfs:Property'); + $this->graph->addResource('https://schema.org/givenName', 'schema:rangeIncludes', 'https://schema.org/Text'); + + $propertiesMap = [ + 'https://schema.org/Article' => [new RdfResource('https://schema.org/articleBody', $this->graph), new RdfResource('https://schema.org/articleSection', $this->graph)], + 'https://schema.org/Person' => [new RdfResource('https://schema.org/givenName', $this->graph)], + ]; + + $this->classPropertiesAppender = new ClassPropertiesAppender($propertyGenerator, $this->loggerProphecy->reveal(), $processedConfiguration, $propertiesMap, []); + } + + /** + * @dataProvider provideInvokeTestCases + */ + public function testInvoke(Class_ $class, Class_ $expectedClass, RdfGraph &$graph = null, ?string $loggerMessage = null): void + { + if ($graph) { + $this->graph = $graph; + $this->setUp(); + } + + if ($loggerMessage) { + $this->loggerProphecy->warning($loggerMessage)->shouldBeCalled(); + } + + $this->assertEquals($expectedClass, ($this->classPropertiesAppender)($class)); + } + + /** + * @return \Generator + */ + public function provideInvokeTestCases(): \Generator + { + $product = new Class_('Product', new RdfResource('https://schema.org/Product')); + yield 'no configuration no properties in map' => [clone $product, clone $product, null, 'Properties for "https://schema.org/Product" not found in the map.']; + + $article = new Class_('Article', new RdfResource('https://schema.org/Article')); + $graph = new RdfGraph(); + $expectedArticleBodyProperty = new Property('articleBody'); + $expectedArticleBodyProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $expectedArticleBodyProperty->resource = new RdfResource('https://schema.org/articleBody', $graph); + $expectedArticleBodyProperty->range = new RdfResource('https://schema.org/Text', $graph); + $expectedArticleBodyProperty->rangeName = 'Text'; + $expectedArticleBodyProperty->isNullable = false; + $expectedArticleSectionProperty = new Property('articleSection'); + $expectedArticleSectionProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $expectedArticleSectionProperty->resource = new RdfResource('https://schema.org/articleSection', $graph); + $expectedArticleSectionProperty->range = new RdfResource('https://schema.org/Text', $graph); + $expectedArticleSectionProperty->rangeName = 'Text'; + $expectedArticleSectionProperty->isNullable = false; + yield 'no configuration' => [clone $article, (clone $article)->addProperty($expectedArticleBodyProperty)->addProperty($expectedArticleSectionProperty), $graph]; + + $graph = new RdfGraph(); + $person = new Class_('Person', new RdfResource('https://schema.org/Person', $graph)); + $expectedGivenNameProperty = new Property('givenName'); + $expectedGivenNameProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $expectedGivenNameProperty->resource = new RdfResource('https://schema.org/givenName', $graph); + $expectedGivenNameProperty->range = new RdfResource('https://schema.org/Text', $graph); + $expectedGivenNameProperty->rangeName = 'Text'; + $expectedGivenNameProperty->isNullable = true; + $expectedGivenNameProperty->ormColumn = []; + yield 'with configuration' => [clone $person, (clone $person)->addProperty($expectedGivenNameProperty), $graph]; + } +} From 5780e4cdc9896e5bab3290556801faa142b5842f Mon Sep 17 00:00:00 2001 From: TheArrowRichard <87716741+TheArrowRichard@users.noreply.github.com> Date: Mon, 22 Nov 2021 10:03:31 -0500 Subject: [PATCH 196/258] feat: add yaml support for doctrine resolve entity (#350) --- phpstan.neon | 2 +- src/TypesGenerator.php | 9 ++++++++- src/TypesGeneratorConfiguration.php | 1 + templates/doctrine.yaml.twig | 6 ++++++ tests/Command/DumpConfigurationTest.php | 3 +++ 5 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 templates/doctrine.yaml.twig diff --git a/phpstan.neon b/phpstan.neon index f023f010..69f8f4c0 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -49,7 +49,7 @@ parameters: checkIsGoodRelations: boolean, header: ?string, namespaces: array{prefix: ?string, entity: string, enum: string, interface: string}, - doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, inheritanceAttributes: array}, + doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, resolveTargetEntityConfigType: 'XML'|'yaml', inheritanceAttributes: array}, validator: array{assertType: boolean}, author: false|string, fieldVisibility: string, diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 7dbfda23..e86df991 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -281,9 +281,16 @@ public function generate(array $config): void $dir = \dirname($file); $this->filesystem->mkdir($dir); + $fileType = $config['doctrine']['resolveTargetEntityConfigType']; + + $mappingTemplateFile = 'doctrine.xml.twig'; + if ('yaml' === $fileType) { + $mappingTemplateFile = 'doctrine.yaml.twig'; + } + file_put_contents( $file, - $this->twig->render('doctrine.xml.twig', ['mappings' => $interfaceMappings]) + $this->twig->render($mappingTemplateFile, ['mappings' => $interfaceMappings]) ); $generatedFiles[] = $file; diff --git a/src/TypesGeneratorConfiguration.php b/src/TypesGeneratorConfiguration.php index 78a71dca..992c9451 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/TypesGeneratorConfiguration.php @@ -109,6 +109,7 @@ static function ($rdf) { ->children() ->booleanNode('useCollection')->defaultTrue()->info('Use Doctrine\'s ArrayCollection instead of standard arrays')->end() ->scalarNode('resolveTargetEntityConfigPath')->defaultNull()->info('The Resolve Target Entity Listener config file path')->end() + ->enumNode('resolveTargetEntityConfigType')->defaultValue('XML')->values(['XML', 'yaml'])->info('The Resolve Target Entity Listener config file type')->end() ->arrayNode('inheritanceAttributes') ->info('Doctrine inheritance attributes (if set, no other attributes are generated)') ->prototype('variable')->end() diff --git a/templates/doctrine.yaml.twig b/templates/doctrine.yaml.twig new file mode 100644 index 00000000..88ecf1de --- /dev/null +++ b/templates/doctrine.yaml.twig @@ -0,0 +1,6 @@ +doctrine: + orm: + resolve_target_entities: +{% for interface, class in mappings %} + {{ interface }}: {{ class }} +{% endfor %} diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 62aa3cec..8f60a6f4 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -101,6 +101,9 @@ interface: App\Model # Example: App\Model # The Resolve Target Entity Listener config file path resolveTargetEntityConfigPath: null + # 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: [] From 037f5c0fbb842fdecada8dce71048f433802626e Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Wed, 24 Nov 2021 12:09:06 +0100 Subject: [PATCH 197/258] feat: load file (#356) --- .github/workflows/ci.yml | 64 ++- .github/workflows/release.yml | 19 +- .php-cs-fixer.dist.php | 1 + bin/compile | 20 +- composer.json | 4 +- composer.lock | 448 +++++++++--------- src/Command/GenerateCommand.php | 15 +- src/Model/Attribute.php | 10 + src/Model/Class_.php | 130 ++++- src/Model/Constant.php | 6 +- src/Model/Property.php | 53 ++- src/Model/ResolveNameTrait.php | 31 ++ src/Printer.php | 11 +- src/TypesGenerator.php | 18 +- tests/Model/ClassTest.php | 9 +- tests/TypesGeneratorTest.php | 6 +- tests/e2e/customized/App/Entity/Person.php | 222 +++++++++ .../App/Entity/PostalAddress.php | 0 .../{src => customized}/App/Entity/Thing.php | 0 .../{src => original}/App/Entity/Person.php | 2 +- .../e2e/original/App/Entity/PostalAddress.php | 143 ++++++ tests/e2e/original/App/Entity/Thing.php | 48 ++ 22 files changed, 943 insertions(+), 317 deletions(-) create mode 100644 src/Model/ResolveNameTrait.php create mode 100644 tests/e2e/customized/App/Entity/Person.php rename tests/e2e/{src => customized}/App/Entity/PostalAddress.php (100%) rename tests/e2e/{src => customized}/App/Entity/Thing.php (100%) rename tests/e2e/{src => original}/App/Entity/Person.php (99%) create mode 100644 tests/e2e/original/App/Entity/PostalAddress.php create mode 100644 tests/e2e/original/App/Entity/Thing.php diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a790ce11..ca0e7347 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,64 +4,86 @@ on: push: pull_request: +env: + COVERAGE: '0' + jobs: build: name: Build and Test runs-on: ubuntu-latest - env: - extensions: json - composer_version: 2 strategy: matrix: - php_version: + php: - '7.4' - '8.0' + include: + - php: '8.0' + coverage: true steps: - uses: actions/checkout@v2 - name: Get Composer Cache Directory id: composer-cache - run: | - echo "::set-output name=dir::$(composer config cache-files-dir)" + run: echo "::set-output name=dir::$(composer config cache-files-dir)" - uses: actions/cache@v2 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- + restore-keys: ${{ runner.os }}-composer- - name: Setup PHP with extensions uses: shivammathur/setup-php@v2 with: - php-version: ${{ matrix.php_version }} - extensions: ${{ env.extensions }} + php-version: ${{ matrix.php }} + extensions: json ini-values: memory_limit=-1 coverage: pcov - tools: composer:v2, cs2pr, php-cs-fixer + tools: composer, cs2pr, php-cs-fixer - name: Install prerequisites run: | - export PATH="$PATH:$HOME/.composer/vendor/bin" - mkdir -p build/logs - wget https://github.com/satooshi/php-coveralls/releases/download/v2.4.3/php-coveralls.phar wget -O box.phar https://github.com/humbug/box/releases/download/3.13.0/box.phar - export BOX_BIN=$(pwd)/box.phar + echo "BOX_BIN=$(pwd)/box.phar" >> $GITHUB_ENV sudo chown -R $(whoami):$(whoami) . - name: Install dependencies - run: composer install --prefer-dist --no-interaction --no-progress + if: startsWith(matrix.php, '8.0') + run: composer install --prefer-dist --no-interaction --no-progress --ansi + + - name: Update dependencies + if: "!startsWith(matrix.php, '8.0')" + run: composer update --no-interaction --no-progress --ansi + + - name: Enable code coverage + if: matrix.coverage + run: echo "COVERAGE=1" >> $GITHUB_ENV - name: Run phpunit - run: vendor/bin/simple-phpunit + run: | + mkdir -p build/logs/phpunit + if [ "$COVERAGE" = '1' ]; then + vendor/bin/simple-phpunit --coverage-clover build/logs/phpunit/clover.xml + else + vendor/bin/simple-phpunit + fi - name: Run php-cs-fixer - run: php-cs-fixer fix --dry-run --format=checkstyle | cs2pr + run: php-cs-fixer fix --dry-run --format=checkstyle --ansi | cs2pr - name: Run phpstan - run: | - vendor/bin/phpstan analyse + run: vendor/bin/phpstan analyse --ansi - name: Run e2e tests + if: startsWith(matrix.php, '8.0') + run: bin/compile + + - name: Upload coverage results to Coveralls + if: matrix.coverage + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | - php bin/compile + composer global require --prefer-dist --no-interaction --no-progress --ansi php-coveralls/php-coveralls + export PATH="$PATH:$HOME/.composer/vendor/bin" + php-coveralls --coverage_clover=build/logs/phpunit/clover.xml -v + continue-on-error: true diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index ce479ef8..5065ace0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,9 +9,6 @@ jobs: build: name: Create Release and Upload Release Asset runs-on: ubuntu-latest - env: - extensions: json - php_version: '8.0' outputs: upload_url: ${{ steps.step_upload_url.outputs.upload_url }} steps: @@ -21,27 +18,25 @@ jobs: - name: Setup PHP with extensions uses: shivammathur/setup-php@v2 with: - php-version: ${{ env.php_version }} - extensions: ${{ env.extensions }} + php-version: '8.0' + extensions: json ini-values: memory_limit=-1 - tools: composer:v2 + tools: composer - name: Install dependencies - run: composer install --prefer-dist --no-interaction --no-progress + run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Download box.phar - run: | - wget -O box.phar https://github.com/humbug/box/releases/download/3.11.1/box.phar - export BOX_BIN=$(pwd)/box.phar + run: wget -O box.phar https://github.com/humbug/box/releases/download/3.13.0/box.phar - name: Compile project - run: php ./box.phar compile; + run: php ./box.phar compile - name: Create Release id: create_release uses: actions/create-release@v1 env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # This token is provided by Actions, you do not need to create your own token + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} with: tag_name: ${{ github.ref }} release_name: Release ${{ github.ref }} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 4484f39c..06c22e6f 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -24,6 +24,7 @@ ->in(__DIR__) ->exclude('tests/Fixtures/app/cache') ->exclude('build') + ->exclude('tmp') ->exclude('tests/e2e'); $config = new PhpCsFixer\Config(); diff --git a/bin/compile b/bin/compile index d958c118..49d9818e 100755 --- a/bin/compile +++ b/bin/compile @@ -4,8 +4,20 @@ set -eox pipefail php "$BOX_BIN" compile; -php schema.phar generate tmp/ tests/e2e/schema.yml; +rm -rf tmp/original -diff tests/e2e/src/App/Entity/Person.php tmp/App/Entity/Person.php; -diff tests/e2e/src/App/Entity/PostalAddress.php tmp/App/Entity/PostalAddress.php; -diff tests/e2e/src/App/Entity/Thing.php tmp/App/Entity/Thing.php; +php schema.phar generate tmp/original tests/e2e/schema.yml -n -vv --ansi; + +diff tests/e2e/original/App/Entity/Person.php tmp/original/App/Entity/Person.php; +diff tests/e2e/original/App/Entity/PostalAddress.php tmp/original/App/Entity/PostalAddress.php; +diff tests/e2e/original/App/Entity/Thing.php tmp/original/App/Entity/Thing.php; + +# Already generated files + +cp -r tests/e2e/customized tmp/ + +php schema.phar generate tmp/customized tests/e2e/schema.yml -n -vv --ansi; + +diff tests/e2e/customized/App/Entity/Person.php tmp/customized/App/Entity/Person.php; +diff tests/e2e/customized/App/Entity/PostalAddress.php tmp/customized/App/Entity/PostalAddress.php; +diff tests/e2e/customized/App/Entity/Thing.php tmp/customized/App/Entity/Thing.php; diff --git a/composer.json b/composer.json index 12a376ff..dd32e162 100644 --- a/composer.json +++ b/composer.json @@ -42,7 +42,9 @@ "symfony/yaml": "^5.2", "symfony/filesystem": "^5.2", "twig/twig": "^3.0", - "nette/php-generator": "^3.6" + "nette/php-generator": "^3.6 || ^4.0-dev", + "nette/utils": "^3.1 || ^4.0-dev", + "nikic/php-parser": "^4.13" }, "require-dev": { "api-platform/core": "^2.5", diff --git a/composer.lock b/composer.lock index 3c39903b..72383d94 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2a748e8ceaccc7ceb34d59ecfc529707", + "content-hash": "da97bd866ab6d3cfc52b8ce1087cd5eb", "packages": [ { "name": "composer/semver", @@ -650,35 +650,36 @@ }, { "name": "nette/php-generator", - "version": "v3.6.4", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "b8375ac20760c62b6816f8c2eaeabbbca305eed7" + "reference": "d4efca79da759eb9ae22fac765666b554898bba3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/b8375ac20760c62b6816f8c2eaeabbbca305eed7", - "reference": "b8375ac20760c62b6816f8c2eaeabbbca305eed7", + "url": "https://api.github.com/repos/nette/php-generator/zipball/d4efca79da759eb9ae22fac765666b554898bba3", + "reference": "d4efca79da759eb9ae22fac765666b554898bba3", "shasum": "" }, "require": { - "nette/utils": "^3.1.2", - "php": ">=7.2 <8.2" + "nette/utils": "^4.0", + "php": ">=8.0 <8.2" }, "require-dev": { "nette/tester": "^2.4", "nikic/php-parser": "^4.13", - "phpstan/phpstan": "^0.12", + "phpstan/phpstan": "^1.0", "tracy/tracy": "^2.8" }, "suggest": { - "nikic/php-parser": "to use ClassType::withBodiesFrom() & GlobalFunction::withBodyFrom()" + "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.6-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -712,34 +713,34 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v3.6.4" + "source": "https://github.com/nette/php-generator/tree/master" }, - "time": "2021-10-15T10:28:31+00:00" + "time": "2021-11-23T15:34:51+00:00" }, { "name": "nette/utils", - "version": "v3.2.5", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "9cd80396ca58d7969ab44fc7afcf03624dfa526e" + "reference": "32809e8000f727a3e5f30ff1e4faf66793b05f39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/9cd80396ca58d7969ab44fc7afcf03624dfa526e", - "reference": "9cd80396ca58d7969ab44fc7afcf03624dfa526e", + "url": "https://api.github.com/repos/nette/utils/zipball/32809e8000f727a3e5f30ff1e4faf66793b05f39", + "reference": "32809e8000f727a3e5f30ff1e4faf66793b05f39", "shasum": "" }, "require": { - "php": ">=7.2 <8.2" + "php": ">=8.0 <8.2" }, "conflict": { "nette/di": "<3.0.6" }, "require-dev": { - "nette/tester": "~2.0", - "phpstan/phpstan": "^0.12", - "tracy/tracy": "^2.3" + "nette/tester": "^2.4", + "phpstan/phpstan": "^1.0", + "tracy/tracy": "^2.8" }, "suggest": { "ext-gd": "to use Image", @@ -750,10 +751,11 @@ "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", "ext-xml": "to use Strings::length() etc. when mbstring is not available" }, + "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -797,9 +799,65 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.5" + "source": "https://github.com/nette/utils/tree/master" }, - "time": "2021-09-20T10:50:11+00:00" + "time": "2021-11-22T23:58:34+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.13.1", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.9-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + }, + "time": "2021-11-03T20:52:16+00:00" }, { "name": "php-cs-fixer/diff", @@ -855,20 +913,20 @@ }, { "name": "psr/cache", - "version": "1.0.1", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/cache.git", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", - "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { @@ -888,7 +946,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for caching libraries", @@ -898,9 +956,9 @@ "psr-6" ], "support": { - "source": "https://github.com/php-fig/cache/tree/master" + "source": "https://github.com/php-fig/cache/tree/3.0.0" }, - "time": "2016-08-06T20:24:11+00:00" + "time": "2021-02-03T23:26:27+00:00" }, { "name": "psr/container", @@ -1052,16 +1110,16 @@ }, { "name": "symfony/config", - "version": "v5.3.10", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "ac23c2f24d5634966d665d836c3933d54347e5d4" + "reference": "f080af00c441f1df40cf5c269707fdebe5740557" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/ac23c2f24d5634966d665d836c3933d54347e5d4", - "reference": "ac23c2f24d5634966d665d836c3933d54347e5d4", + "url": "https://api.github.com/repos/symfony/config/zipball/f080af00c441f1df40cf5c269707fdebe5740557", + "reference": "f080af00c441f1df40cf5c269707fdebe5740557", "shasum": "" }, "require": { @@ -1111,7 +1169,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v5.3.10" + "source": "https://github.com/symfony/config/tree/v5.3.11" }, "funding": [ { @@ -1127,20 +1185,20 @@ "type": "tidelift" } ], - "time": "2021-10-22T09:06:52+00:00" + "time": "2021-10-29T16:05:40+00:00" }, { "name": "symfony/console", - "version": "v5.3.10", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3" + "reference": "3e7ab8f5905058984899b05a4648096f558bfeba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", - "reference": "d4e409d9fbcfbf71af0e5a940abb7b0b4bad0bd3", + "url": "https://api.github.com/repos/symfony/console/zipball/3e7ab8f5905058984899b05a4648096f558bfeba", + "reference": "3e7ab8f5905058984899b05a4648096f558bfeba", "shasum": "" }, "require": { @@ -1153,7 +1211,6 @@ "symfony/string": "^5.1" }, "conflict": { - "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -1210,7 +1267,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.10" + "source": "https://github.com/symfony/console/tree/v5.3.11" }, "funding": [ { @@ -1226,20 +1283,20 @@ "type": "tidelift" } ], - "time": "2021-10-26T09:30:15+00:00" + "time": "2021-11-21T19:41:05+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627" + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5f38c8804a9e97d23e0c8d63341088cd8a22d627", - "reference": "5f38c8804a9e97d23e0c8d63341088cd8a22d627", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", "shasum": "" }, "require": { @@ -1248,7 +1305,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1277,7 +1334,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" }, "funding": [ { @@ -1293,20 +1350,20 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.3.7", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "ce7b20d69c66a20939d8952b617506a44d102130" + "reference": "661a7a6e085394f8513945669e31f7c1338a7e69" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/ce7b20d69c66a20939d8952b617506a44d102130", - "reference": "ce7b20d69c66a20939d8952b617506a44d102130", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/661a7a6e085394f8513945669e31f7c1338a7e69", + "reference": "661a7a6e085394f8513945669e31f7c1338a7e69", "shasum": "" }, "require": { @@ -1362,7 +1419,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.7" + "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.11" }, "funding": [ { @@ -1378,20 +1435,20 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-17T12:16:12+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11" + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/69fee1ad2332a7cbab3aca13591953da9cdb7a11", - "reference": "69fee1ad2332a7cbab3aca13591953da9cdb7a11", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", "shasum": "" }, "require": { @@ -1404,7 +1461,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1441,7 +1498,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" }, "funding": [ { @@ -1457,7 +1514,7 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-07-12T14:48:14+00:00" }, { "name": "symfony/filesystem", @@ -2296,16 +2353,16 @@ }, { "name": "symfony/process", - "version": "v5.3.7", + "version": "v5.3.12", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967" + "reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/38f26c7d6ed535217ea393e05634cb0b244a1967", - "reference": "38f26c7d6ed535217ea393e05634cb0b244a1967", + "url": "https://api.github.com/repos/symfony/process/zipball/e498803a6e95ede78e9d5646ad32a2255c033a6a", + "reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a", "shasum": "" }, "require": { @@ -2338,7 +2395,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v5.3.7" + "source": "https://github.com/symfony/process/tree/v5.3.12" }, "funding": [ { @@ -2354,25 +2411,29 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-22T22:39:13+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb" + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", - "reference": "f040a30e04b57fbcc9c6cbcf4dbaa96bd318b9bb", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", "shasum": "" }, "require": { "php": ">=7.2.5", - "psr/container": "^1.1" + "psr/container": "^1.1", + "symfony/deprecation-contracts": "^2.1" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -2380,7 +2441,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2417,7 +2478,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" }, "funding": [ { @@ -2433,7 +2494,7 @@ "type": "tidelift" } ], - "time": "2021-04-01T10:43:52+00:00" + "time": "2021-11-04T16:48:04+00:00" }, { "name": "symfony/stopwatch", @@ -2582,16 +2643,16 @@ }, { "name": "symfony/yaml", - "version": "v5.3.6", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7" + "reference": "226638aa877bc4104e619a15f27d8141cd6b4e4a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", - "reference": "4500fe63dc9c6ffc32d3b1cb0448c329f9c814b7", + "url": "https://api.github.com/repos/symfony/yaml/zipball/226638aa877bc4104e619a15f27d8141cd6b4e4a", + "reference": "226638aa877bc4104e619a15f27d8141cd6b4e4a", "shasum": "" }, "require": { @@ -2637,7 +2698,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.3.6" + "source": "https://github.com/symfony/yaml/tree/v5.3.11" }, "funding": [ { @@ -2653,7 +2714,7 @@ "type": "tidelift" } ], - "time": "2021-07-29T06:20:01+00:00" + "time": "2021-11-20T16:42:42+00:00" }, { "name": "twig/twig", @@ -3727,27 +3788,27 @@ }, { "name": "fig/link-util", - "version": "1.1.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/php-fig/link-util.git", - "reference": "5d7b8d04ed3393b4b59968ca1e906fb7186d81e8" + "reference": "10e52348a2e9ad4581f2bf3e16458f0861a88c6a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/link-util/zipball/5d7b8d04ed3393b4b59968ca1e906fb7186d81e8", - "reference": "5d7b8d04ed3393b4b59968ca1e906fb7186d81e8", + "url": "https://api.github.com/repos/php-fig/link-util/zipball/10e52348a2e9ad4581f2bf3e16458f0861a88c6a", + "reference": "10e52348a2e9ad4581f2bf3e16458f0861a88c6a", "shasum": "" }, "require": { - "php": ">=5.5.0", - "psr/link": "~1.0@dev" + "php": ">=8.0.0", + "psr/link": "^1.1.0 | ^2.0.0" }, "provide": { "psr/link-implementation": "1.0" }, "require-dev": { - "phpunit/phpunit": "^5.1", + "phpunit/phpunit": "^9", "squizlabs/php_codesniffer": "^2.3.1" }, "type": "library", @@ -3782,9 +3843,9 @@ ], "support": { "issues": "https://github.com/php-fig/link-util/issues", - "source": "https://github.com/php-fig/link-util/tree/1.1.2" + "source": "https://github.com/php-fig/link-util/tree/1.2.0" }, - "time": "2021-02-03T23:36:04+00:00" + "time": "2021-03-11T23:09:19+00:00" }, { "name": "myclabs/deep-copy", @@ -3904,62 +3965,6 @@ ], "time": "2021-07-05T08:18:36+00:00" }, - { - "name": "nikic/php-parser", - "version": "v4.13.1", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.9-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" - }, - "time": "2021-11-03T20:52:16+00:00" - }, { "name": "phar-io/manifest", "version": "2.0.3", @@ -4837,20 +4842,20 @@ }, { "name": "psr/link", - "version": "1.0.0", + "version": "1.1.1", "source": { "type": "git", "url": "https://github.com/php-fig/link.git", - "reference": "eea8e8662d5cd3ae4517c9b864493f59fca95562" + "reference": "846c25f58a1f02b93a00f2404e3626b6bf9b7807" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/link/zipball/eea8e8662d5cd3ae4517c9b864493f59fca95562", - "reference": "eea8e8662d5cd3ae4517c9b864493f59fca95562", + "url": "https://api.github.com/repos/php-fig/link/zipball/846c25f58a1f02b93a00f2404e3626b6bf9b7807", + "reference": "846c25f58a1f02b93a00f2404e3626b6bf9b7807", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { @@ -4874,6 +4879,7 @@ } ], "description": "Common interfaces for HTTP links", + "homepage": "https://github.com/php-fig/link", "keywords": [ "http", "http-link", @@ -4883,9 +4889,9 @@ "rest" ], "support": { - "source": "https://github.com/php-fig/link/tree/master" + "source": "https://github.com/php-fig/link/tree/1.1.1" }, - "time": "2016-10-28T16:06:13+00:00" + "time": "2021-03-11T22:59:13+00:00" }, { "name": "sebastian/cli-parser", @@ -5740,6 +5746,7 @@ "type": "github" } ], + "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { @@ -5853,16 +5860,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v5.3.8", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "212521017d81686bdc84a132fb5de2b03867a7e7" + "reference": "9b220ebc6fb4d5f15a8b74887c059b4d57ba85f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/212521017d81686bdc84a132fb5de2b03867a7e7", - "reference": "212521017d81686bdc84a132fb5de2b03867a7e7", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/9b220ebc6fb4d5f15a8b74887c059b4d57ba85f8", + "reference": "9b220ebc6fb4d5f15a8b74887c059b4d57ba85f8", "shasum": "" }, "require": { @@ -5947,7 +5954,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v5.3.8" + "source": "https://github.com/symfony/doctrine-bridge/tree/v5.3.11" }, "funding": [ { @@ -5963,20 +5970,20 @@ "type": "tidelift" } ], - "time": "2021-09-11T18:11:56+00:00" + "time": "2021-11-12T11:38:27+00:00" }, { "name": "symfony/error-handler", - "version": "v5.3.7", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321" + "reference": "eec73dd7218713f48a7996583a741b3bae58c8d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321", - "reference": "3bc60d0fba00ae8d1eaa9eb5ab11a2bbdd1fc321", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/eec73dd7218713f48a7996583a741b3bae58c8d3", + "reference": "eec73dd7218713f48a7996583a741b3bae58c8d3", "shasum": "" }, "require": { @@ -6015,7 +6022,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.3.7" + "source": "https://github.com/symfony/error-handler/tree/v5.3.11" }, "funding": [ { @@ -6031,20 +6038,20 @@ "type": "tidelift" } ], - "time": "2021-08-28T15:07:08+00:00" + "time": "2021-11-13T13:42:37+00:00" }, { "name": "symfony/http-client-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4" + "reference": "ec82e57b5b714dbb69300d348bd840b345e24166" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/7e82f6084d7cae521a75ef2cb5c9457bbda785f4", - "reference": "7e82f6084d7cae521a75ef2cb5c9457bbda785f4", + "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ec82e57b5b714dbb69300d348bd840b345e24166", + "reference": "ec82e57b5b714dbb69300d348bd840b345e24166", "shasum": "" }, "require": { @@ -6056,7 +6063,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6093,7 +6100,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.0" }, "funding": [ { @@ -6109,20 +6116,20 @@ "type": "tidelift" } ], - "time": "2021-04-11T23:07:08+00:00" + "time": "2021-11-03T09:24:47+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.3.10", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "9f34f02e8a5fdc7a56bafe011cea1ce97300e54c" + "reference": "d1e7059ebeb0b8f9fe5eb5b26eacd2e3c1f371cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/9f34f02e8a5fdc7a56bafe011cea1ce97300e54c", - "reference": "9f34f02e8a5fdc7a56bafe011cea1ce97300e54c", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d1e7059ebeb0b8f9fe5eb5b26eacd2e3c1f371cc", + "reference": "d1e7059ebeb0b8f9fe5eb5b26eacd2e3c1f371cc", "shasum": "" }, "require": { @@ -6166,7 +6173,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.3.10" + "source": "https://github.com/symfony/http-foundation/tree/v5.3.11" }, "funding": [ { @@ -6182,20 +6189,20 @@ "type": "tidelift" } ], - "time": "2021-10-11T15:41:55+00:00" + "time": "2021-11-04T16:37:19+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.3.10", + "version": "v5.3.12", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "703e4079920468e9522b72cf47fd76ce8d795e86" + "reference": "f53025cd1d91b1af85d6d9e17eefa98e31ee953b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/703e4079920468e9522b72cf47fd76ce8d795e86", - "reference": "703e4079920468e9522b72cf47fd76ce8d795e86", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f53025cd1d91b1af85d6d9e17eefa98e31ee953b", + "reference": "f53025cd1d91b1af85d6d9e17eefa98e31ee953b", "shasum": "" }, "require": { @@ -6278,7 +6285,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.3.10" + "source": "https://github.com/symfony/http-kernel/tree/v5.3.12" }, "funding": [ { @@ -6294,20 +6301,20 @@ "type": "tidelift" } ], - "time": "2021-10-29T08:36:48+00:00" + "time": "2021-11-24T08:46:46+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v5.3.10", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "325aaf6302501ed3673cffbd3ba88db5949de8ae" + "reference": "7b3637f0ce55c510a0fbe6e4d49b223103b7bf7b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/325aaf6302501ed3673cffbd3ba88db5949de8ae", - "reference": "325aaf6302501ed3673cffbd3ba88db5949de8ae", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/7b3637f0ce55c510a0fbe6e4d49b223103b7bf7b", + "reference": "7b3637f0ce55c510a0fbe6e4d49b223103b7bf7b", "shasum": "" }, "require": { @@ -6361,7 +6368,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v5.3.10" + "source": "https://github.com/symfony/phpunit-bridge/tree/v5.3.11" }, "funding": [ { @@ -6377,7 +6384,7 @@ "type": "tidelift" } ], - "time": "2021-10-28T19:22:18+00:00" + "time": "2021-11-12T11:38:27+00:00" }, { "name": "symfony/property-access", @@ -6552,16 +6559,16 @@ }, { "name": "symfony/serializer", - "version": "v5.3.10", + "version": "v5.3.12", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "5d7f068253ac3e7c62964ebdda491b06d401059a" + "reference": "bf570839e289e0bdde69c9fa867d3a42f5e8fde1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/5d7f068253ac3e7c62964ebdda491b06d401059a", - "reference": "5d7f068253ac3e7c62964ebdda491b06d401059a", + "url": "https://api.github.com/repos/symfony/serializer/zipball/bf570839e289e0bdde69c9fa867d3a42f5e8fde1", + "reference": "bf570839e289e0bdde69c9fa867d3a42f5e8fde1", "shasum": "" }, "require": { @@ -6634,7 +6641,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.3.10" + "source": "https://github.com/symfony/serializer/tree/v5.3.12" }, "funding": [ { @@ -6650,20 +6657,20 @@ "type": "tidelift" } ], - "time": "2021-09-29T17:19:25+00:00" + "time": "2021-11-24T08:13:09+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.4.0", + "version": "v2.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95" + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/95c812666f3e91db75385749fe219c5e494c7f95", - "reference": "95c812666f3e91db75385749fe219c5e494c7f95", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/d28150f0f44ce854e942b671fc2620a98aae1b1e", + "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e", "shasum": "" }, "require": { @@ -6675,7 +6682,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.4-dev" + "dev-main": "2.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6712,7 +6719,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v2.5.0" }, "funding": [ { @@ -6728,20 +6735,20 @@ "type": "tidelift" } ], - "time": "2021-03-23T23:28:01+00:00" + "time": "2021-08-17T14:20:01+00:00" }, { "name": "symfony/validator", - "version": "v5.3.10", + "version": "v5.3.12", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "a85f3ba9e1c883253fc00a2e3d111e6e82a0baf5" + "reference": "379ca8939ebcab78d835e188673396a9f8d6eee8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/a85f3ba9e1c883253fc00a2e3d111e6e82a0baf5", - "reference": "a85f3ba9e1c883253fc00a2e3d111e6e82a0baf5", + "url": "https://api.github.com/repos/symfony/validator/zipball/379ca8939ebcab78d835e188673396a9f8d6eee8", + "reference": "379ca8939ebcab78d835e188673396a9f8d6eee8", "shasum": "" }, "require": { @@ -6822,7 +6829,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v5.3.10" + "source": "https://github.com/symfony/validator/tree/v5.3.12" }, "funding": [ { @@ -6838,20 +6845,20 @@ "type": "tidelift" } ], - "time": "2021-10-28T19:22:18+00:00" + "time": "2021-11-22T22:24:25+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.3.10", + "version": "v5.3.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "875432adb5f5570fff21036fd22aee244636b7d1" + "reference": "a029b3a11b757f9cc8693040339153b4745a913f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/875432adb5f5570fff21036fd22aee244636b7d1", - "reference": "875432adb5f5570fff21036fd22aee244636b7d1", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a029b3a11b757f9cc8693040339153b4745a913f", + "reference": "a029b3a11b757f9cc8693040339153b4745a913f", "shasum": "" }, "require": { @@ -6910,7 +6917,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.10" + "source": "https://github.com/symfony/var-dumper/tree/v5.3.11" }, "funding": [ { @@ -6926,7 +6933,7 @@ "type": "tidelift" } ], - "time": "2021-10-26T09:30:15+00:00" + "time": "2021-11-12T11:38:27+00:00" }, { "name": "symfony/web-link", @@ -7182,7 +7189,10 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": { + "nette/php-generator": 20, + "nette/utils": 20 + }, "prefer-stable": false, "prefer-lowest": false, "platform": { diff --git a/src/Command/GenerateCommand.php b/src/Command/GenerateCommand.php index fdd9dae3..fb14bdc9 100644 --- a/src/Command/GenerateCommand.php +++ b/src/Command/GenerateCommand.php @@ -28,6 +28,7 @@ use Symfony\Component\Console\Logger\ConsoleLogger; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Yaml\Parser; use Twig\Environment; @@ -85,6 +86,8 @@ private function readComposer(): void */ protected function execute(InputInterface $input, OutputInterface $output): int { + $io = new SymfonyStyle($input, $output); + $defaultOutput = $this->defaultOutput ? realpath($this->defaultOutput) : null; $outputDir = $input->getArgument('output'); $configArgument = $input->getArgument('config'); @@ -138,11 +141,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $config = $parser->parse($defaultConfigContent); unset($parser); } else { - $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion('Your project has no config file. The entire vocabulary will be imported.'.\PHP_EOL.'Continue? [yN]', false); - - if (!$helper->ask($input, $output, $question)) { - return 0; + if (!$io->askQuestion(new ConfirmationQuestion('Your project has no config file. The entire vocabulary will be imported.'.\PHP_EOL.'Continue?', false))) { + return Command::SUCCESS; } $config = []; @@ -199,11 +199,12 @@ protected function execute(InputInterface $input, OutputInterface $output): int new PhpTypeConverter(), $cardinalitiesExtractor, $goodRelationsBridge, - new Printer() + new Printer(), + $io ); $entitiesGenerator->generate($processedConfiguration); - return 0; + return Command::SUCCESS; } } diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php index fe152f03..9678f924 100644 --- a/src/Model/Attribute.php +++ b/src/Model/Attribute.php @@ -13,8 +13,13 @@ namespace ApiPlatform\SchemaGenerator\Model; +use Nette\PhpGenerator\Attribute as NetteAttribute; +use Nette\PhpGenerator\PhpNamespace; + final class Attribute { + use ResolveNameTrait; + private string $name; /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] */ @@ -41,4 +46,9 @@ public function args(): array { return $this->args; } + + public function toNetteAttribute(PhpNamespace $namespace): NetteAttribute + { + return new NetteAttribute($this->resolveName($namespace, $this->name), $this->args); + } } diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 6bd1db95..189cd420 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -15,12 +15,15 @@ use Doctrine\Inflector\Inflector; use EasyRdf\Resource as RdfResource; +use MyCLabs\Enum\Enum as MyCLabsEnum; use Nette\PhpGenerator\Helpers; use Nette\PhpGenerator\Method; use Nette\PhpGenerator\PhpFile; final class Class_ { + use ResolveNameTrait; + private string $name; private RdfResource $resource; public string $namespace = ''; @@ -249,7 +252,7 @@ public function isParentEnum(): bool /** * @param Configuration $config */ - public function toNetteFile(array $config, Inflector $inflector): PhpFile + public function toNetteFile(array $config, Inflector $inflector, ?PhpFile $file = null): PhpFile { $useDoctrineCollections = $config['doctrine']['useCollection']; $useAccessors = $config['accessorMethods']; @@ -257,48 +260,98 @@ public function toNetteFile(array $config, Inflector $inflector): PhpFile $fileHeader = $config['header'] ?? null; $fieldVisibility = $config['fieldVisibility']; - $file = new PhpFile(); - if (null !== $fileHeader && false !== $fileHeader) { + $file ??= new PhpFile(); + if (null !== $fileHeader && false !== $fileHeader && !$file->getComment()) { // avoid nested doc-block for configurations that already have * as delimiter $file->setComment(Helpers::unformatDocComment($fileHeader)); } - $namespace = $file->addNamespace($this->namespace); + $namespace = $file->getNamespaces()[$this->namespace] ?? null; + if (!$namespace) { + $namespace = $file->addNamespace($this->namespace); + } + foreach ($this->uses as $use) { $namespace->addUse($use->name(), $use->alias()); } - $class = $namespace->addClass($this->name); + $class = $namespace->getClasses()[$this->name] ?? null; + if (!$class) { + $class = $namespace->addClass($this->name); + } + $netteAttributes = $class->getAttributes(); foreach ($this->attributes as $attribute) { - $class->addAttribute($attribute->name(), $attribute->args()); + $hasAttribute = false; + foreach ($class->getAttributes() as $netteAttribute) { + if ($netteAttribute->getName() === $this->resolveName($namespace, $attribute->name())) { + $hasAttribute = true; + } + } + if (!$hasAttribute) { + $netteAttributes[] = $attribute->toNetteAttribute($namespace); + } } + $class->setAttributes($netteAttributes); - foreach ($this->annotations as $annotation) { - $class->addComment($annotation); + if (!$class->getComment()) { + foreach ($this->annotations as $annotation) { + $class->addComment($annotation); + } } $class->setAbstract($this->isAbstract); if (null !== $this->interfaceName()) { - $class->setImplements([$this->interfaceName()]); + $interfaceImplement = $this->resolveName($namespace, $this->interfaceName()); + $implements = $class->getImplements(); + if (!\in_array($interfaceImplement, $implements, true)) { + $implements[] = $interfaceImplement; + } + $class->setImplements($implements); } if ($this->parent()) { - $class->setExtends($this->parent()); + $parentExtend = $this->resolveName($namespace, $this->parent()); + if ($this->isParentEnum()) { + $parentExtend = MyCLabsEnum::class; + } + $extends = (array) $class->getExtends(); + if (!\in_array($parentExtend, $extends, true)) { + $extends[] = $parentExtend; + } + $class->setExtends($extends); + } + + $netteConstants = $class->getConstants(); + foreach ($this->constants as $constant) { + if (!isset($class->getConstants()[$constant->name()])) { + $netteConstants[] = $constant->toNetteConstant(); + } } + $class->setConstants($netteConstants); $sortedProperties = isset($this->properties['id']) ? ['id' => $this->properties['id']] + $this->properties : $this->properties; - $class->setConstants(array_map(static fn (Constant $constant) => $constant->toNetteConstant(), $this->constants)); - $class->setProperties(array_map( - static function (Property $property) use ($useDoctrineCollections, $fieldVisibility) { - return $property->toNetteProperty($fieldVisibility, $useDoctrineCollections); - }, - $sortedProperties - )); + $netteProperties = []; + foreach ($class->getProperties() as $netteProperty) { + $hasProperty = false; + foreach ($sortedProperties as $property) { + if ($property->name() === $netteProperty->getName()) { + $hasProperty = true; + } + } + if (!$hasProperty) { + $netteProperties[] = $netteProperty; + } + } + foreach ($sortedProperties as $property) { + $netteProperty = $class->hasProperty($property->name()) ? $class->getProperty($property->name()) : null; + $netteProperties[] = $property->toNetteProperty($namespace, $fieldVisibility, $useDoctrineCollections, $netteProperty); + } + $class->setProperties($netteProperties); - if ($useDoctrineCollections && $this->hasConstructor) { + if ($useDoctrineCollections && $this->hasConstructor && !$class->hasMethod('__construct')) { $constructor = new Method('__construct'); if ($this->parentHasConstructor) { $constructor->addBody('parent::__construct();'); @@ -316,13 +369,50 @@ static function (Property $property) use ($useDoctrineCollections, $fieldVisibil } if ($useAccessors) { + $methods = []; foreach ($sortedProperties as $property) { foreach ($property->generateNetteMethods(static function ($string) use ($inflector) { return $inflector->singularize($string); - }, $useDoctrineCollections, $useFluentMutators) as $method) { - $class->addMember($method); + }, $namespace, $useDoctrineCollections, $useFluentMutators) as $method) { + $methods[] = $method; + } + } + + $netteMethods = []; + foreach ($class->getMethods() as $netteMethod) { + $hasMethod = false; + foreach ($methods as $method) { + if ($method->getName() === $netteMethod->getName()) { + $hasMethod = true; + } + } + if (!$hasMethod) { + $netteMethods[] = $netteMethod; + } + } + + foreach ($methods as $method) { + if (!$class->hasMethod($method->getName())) { + $netteMethods[] = $method; + continue; + } + $netteMethod = $class->getMethod($method->getName()); + $netteAttributes = $netteMethod->getAttributes(); + foreach ($method->getAttributes() as $attribute) { + $hasAttribute = false; + foreach ($netteMethod->getAttributes() as $netteAttribute) { + if ($netteAttribute->getName() === $attribute->getName()) { + $hasAttribute = true; + } + } + if (!$hasAttribute) { + $netteAttributes[] = $attribute; + } } + $method->setAttributes($netteAttributes); + $netteMethods[] = $method; } + $class->setMethods($netteMethods); } return $file; diff --git a/src/Model/Constant.php b/src/Model/Constant.php index f5670b79..92521a45 100644 --- a/src/Model/Constant.php +++ b/src/Model/Constant.php @@ -51,14 +51,14 @@ public function addAnnotation(string $annotation): self public function toNetteConstant(): NetteConstant { - $netteConstant = (new NetteConstant($this->name)) + $constant = (new NetteConstant($this->name)) ->setValue($this->resource->getUri()) ->setVisibility(ClassType::VISIBILITY_PUBLIC); foreach ($this->annotations as $annotation) { - $netteConstant->addComment($annotation); + $constant->addComment($annotation); } - return $netteConstant; + return $constant; } } diff --git a/src/Model/Property.php b/src/Model/Property.php index bb440e35..d4769d68 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -16,10 +16,13 @@ use EasyRdf\Resource as RdfResource; use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Method; +use Nette\PhpGenerator\PhpNamespace; use Nette\PhpGenerator\Property as NetteProperty; final class Property { + use ResolveNameTrait; + private string $name; public ?RdfResource $resource = null; public string $cardinality; @@ -143,31 +146,45 @@ public function markAsCustom(): self return $this; } - public function toNetteProperty(string $visibility = null, bool $useDoctrineCollections = true): NetteProperty + public function toNetteProperty(PhpNamespace $namespace, string $visibility = null, bool $useDoctrineCollections = true, ?NetteProperty $property = null): NetteProperty { - $netteProperty = (new NetteProperty($this->name)) - ->setVisibility($visibility ?? ClassType::VISIBILITY_PRIVATE); + $property ??= new NetteProperty($this->name); + + $property->setVisibility($visibility ?? ClassType::VISIBILITY_PRIVATE); if ($this->typeHint) { - $netteProperty->setType($this->typeHint); + $property->setType($this->resolveName($namespace, $this->typeHint)); } if (!$this->isArray || $this->isTypeHintedAsCollection()) { - $netteProperty->setNullable($this->isNullable); + $property->setNullable($this->isNullable); } if (($default = $this->guessDefaultGeneratedValue($useDoctrineCollections)) !== -1) { - $netteProperty->setValue($default); + $property->setValue($default); } + $netteAttributes = $property->getAttributes(); foreach ($this->attributes as $attribute) { - $netteProperty->addAttribute($attribute->name(), $attribute->args()); + $hasAttribute = false; + foreach ($property->getAttributes() as $netteAttribute) { + if ($netteAttribute->getName() === $this->resolveName($namespace, $attribute->name())) { + $hasAttribute = true; + } + } + if (!$hasAttribute) { + $netteAttributes[] = $attribute->toNetteAttribute($namespace); + } } - foreach ($this->annotations as $annotation) { - $netteProperty->addComment($annotation); + $property->setAttributes($netteAttributes); + + if (!$property->getComment()) { + foreach ($this->annotations as $annotation) { + $property->addComment($annotation); + } } - return $netteProperty; + return $property; } /** @@ -175,16 +192,17 @@ public function toNetteProperty(string $visibility = null, bool $useDoctrineColl */ public function generateNetteMethods( \Closure $singularize, + PhpNamespace $namespace, bool $useDoctrineCollections = true, bool $useFluentMutators = false ): array { return array_merge( - $this->generateMutators($singularize, $useDoctrineCollections, $useFluentMutators), - $this->isReadable ? [$this->generateGetter()] : [] + $this->generateMutators($singularize, $namespace, $useDoctrineCollections, $useFluentMutators), + $this->isReadable ? [$this->generateGetter($namespace)] : [] ); } - private function generateGetter(): Method + private function generateGetter(PhpNamespace $namespace): Method { if (!$this->isReadable) { throw new \LogicException(sprintf("Property '%s' is not readable.", $this->name)); @@ -195,7 +213,7 @@ private function generateGetter(): Method $getter->addComment($annotation); } if ($this->typeHint) { - $getter->setReturnType($this->typeHint); + $getter->setReturnType($this->resolveName($namespace, $this->typeHint)); if ($this->isNullable && !$this->isArray) { $getter->setReturnNullable(); } @@ -210,6 +228,7 @@ private function generateGetter(): Method */ private function generateMutators( \Closure $singularize, + PhpNamespace $namespace, bool $useDoctrineCollections = true, bool $useFluentMutators = false ): array { @@ -228,7 +247,7 @@ private function generateMutators( } $parameter = $adder->addParameter($singularProperty); if ($this->typeHint && !$this->isEnum) { - $parameter->setType($this->adderRemoverTypeHint); + $parameter->setType($this->adderRemoverTypeHint ? $this->resolveName($namespace, $this->adderRemoverTypeHint) : $this->adderRemoverTypeHint); } $adder->addBody( sprintf('$this->%s[] = %s;', $this->name(), ($this->isEnum ? '(string) ' : '')."$$singularProperty") @@ -246,7 +265,7 @@ private function generateMutators( } $parameter = $remover->addParameter($singularProperty); if ($this->typeHint) { - $parameter->setType($this->adderRemoverTypeHint); + $parameter->setType($this->adderRemoverTypeHint ? $this->resolveName($namespace, $this->adderRemoverTypeHint) : $this->adderRemoverTypeHint); } if ($useDoctrineCollections && $this->typeHint && 'array' !== $this->typeHint && !$this->isEnum) { @@ -277,7 +296,7 @@ private function generateMutators( $setter->addComment($annotation); } $setter->addParameter($this->name()) - ->setType($this->typeHint) + ->setType($this->typeHint ? $this->resolveName($namespace, $this->typeHint) : $this->typeHint) ->setNullable($this->isNullable); $setter->addBody('$this->? = $?;', [$this->name(), $this->name()]); diff --git a/src/Model/ResolveNameTrait.php b/src/Model/ResolveNameTrait.php new file mode 100644 index 00000000..e3af5821 --- /dev/null +++ b/src/Model/ResolveNameTrait.php @@ -0,0 +1,31 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model; + +use Nette\PhpGenerator\PhpNamespace; + +/** + * BC layer for the resolveName method of PhpNamespace. + */ +trait ResolveNameTrait +{ + private function resolveName(PhpNamespace $namespace, string $name): string + { + if (method_exists(PhpNamespace::class, 'resolveName')) { + return $namespace->resolveName($name); + } + + return $name; + } +} diff --git a/src/Printer.php b/src/Printer.php index 71f88375..c9804e0f 100644 --- a/src/Printer.php +++ b/src/Printer.php @@ -13,17 +13,20 @@ namespace ApiPlatform\SchemaGenerator; +use Nette\PhpGenerator\PhpNamespace; use Nette\PhpGenerator\Printer as NettePrinter; final class Printer extends NettePrinter { - /** @var int */ - protected $linesBetweenMethods = 1; - public function __construct() { parent::__construct(); - $this->setTypeResolving(false); + $this->linesBetweenMethods = 1; + // If the type name cannot be resolved with the namespace and its uses (nette/php-generator >= 4), + // disable type resolving to avoid using the root namespace. + if (!method_exists(PhpNamespace::class, 'resolveName')) { + $this->setTypeResolving(false); + } } } diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index e86df991..68ff3c84 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -28,6 +28,7 @@ use EasyRdf\RdfNamespace; use EasyRdf\Resource as RdfResource; use Nette\InvalidArgumentException as NetteInvalidArgumentException; +use Nette\PhpGenerator\PhpFile; use PhpCsFixer\Cache\NullCacheManager; use PhpCsFixer\Differ\NullDiffer; use PhpCsFixer\Error\ErrorsManager; @@ -37,6 +38,8 @@ use PhpCsFixer\RuleSet\RuleSet; use PhpCsFixer\Runner\Runner; use Psr\Log\LoggerInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; use Twig\Environment; @@ -91,11 +94,12 @@ class TypesGenerator private Filesystem $filesystem; private PropertyGenerator $propertyGenerator; private Printer $printer; + private SymfonyStyle $io; /** * @param RdfGraph[] $graphs */ - public function __construct(Inflector $inflector, Environment $twig, LoggerInterface $logger, array $graphs, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge, Printer $printer) + public function __construct(Inflector $inflector, Environment $twig, LoggerInterface $logger, array $graphs, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge, Printer $printer, SymfonyStyle $io) { if (!$graphs) { throw new \InvalidArgumentException('At least one graph must be injected.'); @@ -111,6 +115,7 @@ public function __construct(Inflector $inflector, Environment $twig, LoggerInter $this->cardinalities = $cardinalitiesExtractor->extract(); $this->propertyGenerator = new PropertyGenerator($this->goodRelationsBridge, $this->phpTypeConverter, $this->cardinalities, $this->logger); $this->printer = $printer; + $this->io = $io; RdfNamespace::set('schema', 'https://schema.org/'); } @@ -254,8 +259,17 @@ public function generate(array $config): void $path = sprintf('%s%s.php', $classDir, $className); + $file = null; + if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) { + $confirmation = $this->io->askQuestion(new ConfirmationQuestion(sprintf('File "%s" already exists, use it (if no it will be overwritten)?', $path))); + if ($confirmation) { + $file = PhpFile::fromCode($fileContent); + $this->logger->info(sprintf('Using "%s" as base file.', $path)); + } + } + try { - file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector))); + file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector, $file))); } catch (NetteInvalidArgumentException $exception) { $this->logger->warning($exception->getMessage()); } diff --git a/tests/Model/ClassTest.php b/tests/Model/ClassTest.php index b438479a..7bfd9b73 100644 --- a/tests/Model/ClassTest.php +++ b/tests/Model/ClassTest.php @@ -51,12 +51,11 @@ public function testClass(): void $this->assertStringContainsString('class Book', $generated); $this->assertStringContainsString('namespace App\Entity;', $generated); $this->assertStringContainsString('use OtherApp\Interfaces\Printable;', $generated); - $this->assertStringContainsString('class Book implements \Printable', $generated); + $this->assertStringContainsString('class Book implements Printable', $generated); $this->assertStringContainsString('/** @see https://schema.org/Author */', $generated); - $this->assertStringContainsString('private ?Author $author = null;', $generated); - $this->assertStringContainsString('private ?Author $author = null;', $generated); - $this->assertStringContainsString('public function setAuthor(?Author $author): self', $generated); - $this->assertStringContainsString('public function getAuthor(): ?Author', $generated); + $this->assertStringContainsString('private ?App\Entity\Author $author = null;', $generated); + $this->assertStringContainsString('public function setAuthor(?App\Entity\Author $author): self', $generated); + $this->assertStringContainsString('public function getAuthor(): ?App\Entity\Author', $generated); $this->assertFalse($class->isEmbeddable); $this->assertFalse($class->hasChild); $this->assertFalse($class->hasParent()); diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 94f6d2f6..777e7bae 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -26,6 +26,9 @@ use Prophecy\PhpUnit\ProphecyTrait; use Psr\Log\NullLogger; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\Console\Input\ArrayInput; +use Symfony\Component\Console\Output\NullOutput; +use Symfony\Component\Console\Style\SymfonyStyle; use Twig\Environment; /** @@ -61,7 +64,8 @@ public function testGenerate(): void new PhpTypeConverter(), $cardinalitiesExtractor, $goodRelationsBridge, - new Printer() + new Printer(), + new SymfonyStyle(new ArrayInput([]), new NullOutput()) ); $outputDir = 'build/type-generator-test'; diff --git a/tests/e2e/customized/App/Entity/Person.php b/tests/e2e/customized/App/Entity/Person.php new file mode 100644 index 00000000..51b50125 --- /dev/null +++ b/tests/e2e/customized/App/Entity/Person.php @@ -0,0 +1,222 @@ + ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], + collectionOperations: ['get' => ['route_name' => 'get_person_collection']], +)] +#[UniqueEntity('email')] +#[MyCustomAttribute(foo: 'bar')] +class Person extends MyCustomClass implements MyCustomInterface +{ + public const PERSON_TRAITS = ['nice', 'funny']; + + private string $myProperty = 'foo'; + + #[MyCustomAttribute] + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + /** + * Family name. In the U.S., the last name of a Person. + * + * @see https://schema.org/familyName + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/familyName')] + private ?string $familyName = null; + + /** + * Given name. In the U.S., the first name of a Person. + * + * @see https://schema.org/givenName + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/givenName')] + private ?string $givenName = null; + + /** + * An additional name for a Person, can be used for a middle name. + * + * @see https://schema.org/additionalName + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/additionalName')] + #[Groups(['extra'])] + private ?string $additionalName = null; + + /** + * Physical address of the item. + * + * @see https://schema.org/address + */ + #[ORM\ManyToOne(targetEntity: 'App\Entity\PostalAddress')] + #[ApiProperty(iri: 'https://schema.org/address')] + private ?PostalAddress $address = null; + + /** + * Date of birth. + * + * @see https://schema.org/birthDate + */ + #[ORM\Column(type: 'date', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/birthDate')] + #[Assert\Type(\DateTimeInterface::class)] + private ?\DateTimeInterface $birthDate = null; + + /** + * The telephone number. + * + * @see https://schema.org/telephone + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/telephone')] + private ?string $telephone = null; + + /** + * Email address. + * + * @see https://schema.org/email + */ + #[ORM\Column(type: 'text', nullable: true, unique: true)] + #[ApiProperty(iri: 'https://schema.org/email', security: 'is_granted(\'ROLE_ADMIN\')')] + #[Assert\Email] + private ?string $email = null; + + /** + * URL of the item. + * + * @see https://schema.org/url + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/url')] + #[Assert\Url] + private ?string $url = null; + + /** @see _:customColumn */ + #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] + private ?Person $customColumn = null; + + public function getMyProperty(): string + { + return $this->myProperty; + } + + public function getId(): ?int + { + return $this->id; + } + + public function setFamilyName(?string $familyName): void + { + $this->familyName = $familyName; + } + + public function getFamilyName(): ?string + { + return $this->familyName; + } + + public function setGivenName(?string $givenName): void + { + $this->givenName = $givenName; + } + + public function getGivenName(): ?string + { + return $this->givenName; + } + + public function setAdditionalName(?string $additionalName): void + { + $this->additionalName = $additionalName; + } + + public function getAdditionalName(): ?string + { + return $this->additionalName; + } + + public function setAddress(?PostalAddress $address): void + { + $this->address = $address; + } + + public function getAddress(): ?PostalAddress + { + return $this->address; + } + + public function setBirthDate(?\DateTimeInterface $birthDate): void + { + $this->birthDate = $birthDate; + } + + public function getBirthDate(): ?\DateTimeInterface + { + return $this->birthDate; + } + + public function setTelephone(?string $telephone): void + { + $this->telephone = $telephone; + } + + public function getTelephone(): ?string + { + return $this->telephone; + } + + public function setEmail(?string $email): void + { + $this->email = $email; + } + + public function getEmail(): ?string + { + return $this->email; + } + + public function setUrl(?string $url): void + { + $this->url = $url; + } + + public function getUrl(): ?string + { + return $this->url; + } + + public function setCustomColumn(?Person $customColumn): void + { + $this->customColumn = $customColumn; + } + + public function getCustomColumn(): ?Person + { + return $this->customColumn; + } +} diff --git a/tests/e2e/src/App/Entity/PostalAddress.php b/tests/e2e/customized/App/Entity/PostalAddress.php similarity index 100% rename from tests/e2e/src/App/Entity/PostalAddress.php rename to tests/e2e/customized/App/Entity/PostalAddress.php diff --git a/tests/e2e/src/App/Entity/Thing.php b/tests/e2e/customized/App/Entity/Thing.php similarity index 100% rename from tests/e2e/src/App/Entity/Thing.php rename to tests/e2e/customized/App/Entity/Thing.php diff --git a/tests/e2e/src/App/Entity/Person.php b/tests/e2e/original/App/Entity/Person.php similarity index 99% rename from tests/e2e/src/App/Entity/Person.php rename to tests/e2e/original/App/Entity/Person.php index 454e6a6a..645d3c84 100644 --- a/tests/e2e/src/App/Entity/Person.php +++ b/tests/e2e/original/App/Entity/Person.php @@ -21,7 +21,7 @@ iri: 'https://schema.org/Person', security: 'is_granted(\'ROLE_USER\')', itemOperations: ['get' => ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], - collectionOperations: ['get' => ['route_name' => 'get_person_collection']] + collectionOperations: ['get' => ['route_name' => 'get_person_collection']], )] #[UniqueEntity('email')] class Person diff --git a/tests/e2e/original/App/Entity/PostalAddress.php b/tests/e2e/original/App/Entity/PostalAddress.php new file mode 100644 index 00000000..f17cf43e --- /dev/null +++ b/tests/e2e/original/App/Entity/PostalAddress.php @@ -0,0 +1,143 @@ +id; + } + + public function setAddressCountry(?string $addressCountry): void + { + $this->addressCountry = $addressCountry; + } + + public function getAddressCountry(): ?string + { + return $this->addressCountry; + } + + public function setAddressLocality(?string $addressLocality): void + { + $this->addressLocality = $addressLocality; + } + + public function getAddressLocality(): ?string + { + return $this->addressLocality; + } + + public function setAddressRegion(?string $addressRegion): void + { + $this->addressRegion = $addressRegion; + } + + public function getAddressRegion(): ?string + { + return $this->addressRegion; + } + + public function setPostOfficeBoxNumber(?string $postOfficeBoxNumber): void + { + $this->postOfficeBoxNumber = $postOfficeBoxNumber; + } + + public function getPostOfficeBoxNumber(): ?string + { + return $this->postOfficeBoxNumber; + } + + public function setPostalCode(?string $postalCode): void + { + $this->postalCode = $postalCode; + } + + public function getPostalCode(): ?string + { + return $this->postalCode; + } + + public function setStreetAddress(?string $streetAddress): void + { + $this->streetAddress = $streetAddress; + } + + public function getStreetAddress(): ?string + { + return $this->streetAddress; + } +} diff --git a/tests/e2e/original/App/Entity/Thing.php b/tests/e2e/original/App/Entity/Thing.php new file mode 100644 index 00000000..6d37a3b1 --- /dev/null +++ b/tests/e2e/original/App/Entity/Thing.php @@ -0,0 +1,48 @@ +id; + } + + public function setName(?string $name): void + { + $this->name = $name; + } + + public function getName(): ?string + { + return $this->name; + } +} From 24428da23c4897bf43194f545068ca7fd65bc1e5 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Wed, 24 Nov 2021 23:36:39 +0100 Subject: [PATCH 198/258] fix: only one extends should be generated (#357) --- src/Model/Class_.php | 9 +++------ tests/e2e/customized/App/Entity/Thing.php | 16 ++-------------- tests/e2e/original/App/Entity/Person.php | 2 +- tests/e2e/original/App/Entity/Thing.php | 16 ++-------------- tests/e2e/schema.yml | 1 + 5 files changed, 9 insertions(+), 35 deletions(-) diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 189cd420..cfe2aa46 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -311,16 +311,13 @@ public function toNetteFile(array $config, Inflector $inflector, ?PhpFile $file $class->setImplements($implements); } - if ($this->parent()) { + if ($this->parent() && !$class->getExtends()) { $parentExtend = $this->resolveName($namespace, $this->parent()); if ($this->isParentEnum()) { $parentExtend = MyCLabsEnum::class; } - $extends = (array) $class->getExtends(); - if (!\in_array($parentExtend, $extends, true)) { - $extends[] = $parentExtend; - } - $class->setExtends($extends); + + $class->setExtends($parentExtend); } $netteConstants = $class->getConstants(); diff --git a/tests/e2e/customized/App/Entity/Thing.php b/tests/e2e/customized/App/Entity/Thing.php index 6d37a3b1..e8405b00 100644 --- a/tests/e2e/customized/App/Entity/Thing.php +++ b/tests/e2e/customized/App/Entity/Thing.php @@ -5,7 +5,6 @@ namespace App\Entity; use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; use Doctrine\ORM\Mapping as ORM; /** @@ -13,15 +12,9 @@ * * @see https://schema.org/Thing */ -#[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Thing')] -class Thing +#[ORM\MappedSuperclass] +abstract class Thing { - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'AUTO')] - #[ORM\Column(type: 'integer')] - private ?int $id = null; - /** * The name of the item. * @@ -31,11 +24,6 @@ class Thing #[ApiProperty(iri: 'https://schema.org/name')] private ?string $name = null; - public function getId(): ?int - { - return $this->id; - } - public function setName(?string $name): void { $this->name = $name; diff --git a/tests/e2e/original/App/Entity/Person.php b/tests/e2e/original/App/Entity/Person.php index 645d3c84..3fa4ad83 100644 --- a/tests/e2e/original/App/Entity/Person.php +++ b/tests/e2e/original/App/Entity/Person.php @@ -24,7 +24,7 @@ collectionOperations: ['get' => ['route_name' => 'get_person_collection']], )] #[UniqueEntity('email')] -class Person +class Person extends Thing { #[ORM\Id] #[ORM\GeneratedValue(strategy: 'AUTO')] diff --git a/tests/e2e/original/App/Entity/Thing.php b/tests/e2e/original/App/Entity/Thing.php index 6d37a3b1..e8405b00 100644 --- a/tests/e2e/original/App/Entity/Thing.php +++ b/tests/e2e/original/App/Entity/Thing.php @@ -5,7 +5,6 @@ namespace App\Entity; use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; use Doctrine\ORM\Mapping as ORM; /** @@ -13,15 +12,9 @@ * * @see https://schema.org/Thing */ -#[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Thing')] -class Thing +#[ORM\MappedSuperclass] +abstract class Thing { - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'AUTO')] - #[ORM\Column(type: 'integer')] - private ?int $id = null; - /** * The name of the item. * @@ -31,11 +24,6 @@ class Thing #[ApiProperty(iri: 'https://schema.org/name')] private ?string $name = null; - public function getId(): ?int - { - return $this->id; - } - public function setName(?string $name): void { $this->name = $name; diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 7f8b8873..6a53ae81 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -7,6 +7,7 @@ types: properties: name: ~ Person: + parent: ~ operations: item: get: From 0d3cf8553109d0fd031dc628f33103ff7cc5d4ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 24 Dec 2021 15:34:38 +0100 Subject: [PATCH 199/258] feat: compatibility with Symfony 6 (#359) --- composer.json | 27 +- composer.lock | 1474 +++++++++++++++++++++++-------------------------- 2 files changed, 706 insertions(+), 795 deletions(-) diff --git a/composer.json b/composer.json index dd32e162..f5b2d996 100644 --- a/composer.json +++ b/composer.json @@ -3,6 +3,8 @@ "type": "library", "description": "Various tools to generate a data model based on Schema.org vocables", "keywords": [ + "rdf", + "owl", "schema.org", "semantic", "model", @@ -36,11 +38,11 @@ "easyrdf/easyrdf": "^1.1", "friendsofphp/php-cs-fixer": "^2.15 || ^3.0", "league/html-to-markdown": "^5.0", - "psr/log": "^1.0", - "symfony/config": "^5.2", - "symfony/console": "^5.2", - "symfony/yaml": "^5.2", - "symfony/filesystem": "^5.2", + "psr/log": "^1.0 || ^2.0 || ^3.0", + "symfony/config": "^5.2 || ^6.0" , + "symfony/console": "^5.2 || ^6.0", + "symfony/yaml": "^5.2 || ^6.0", + "symfony/filesystem": "^5.2 || ^6.0", "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0-dev", "nette/utils": "^3.1 || ^4.0-dev", @@ -50,14 +52,19 @@ "api-platform/core": "^2.5", "doctrine/orm": "^2.7", "myclabs/php-enum": "^1.7", - "symfony/doctrine-bridge": "^5.2", - "symfony/phpunit-bridge": "^5.2", - "symfony/serializer": "^5.2", - "symfony/validator": "^5.2", + "symfony/doctrine-bridge": "^5.2 || ^6.0", + "symfony/phpunit-bridge": "^5.2 || ^6.0", + "symfony/serializer": "^5.2 || ^6.0", + "symfony/validator": "^5.2 || ^6.0", "phpspec/prophecy-phpunit": "^2.0", "phpstan/phpstan": "^1.2.0" }, "bin": [ "bin/schema" - ] + ], + "config": { + "allow-plugins": { + "composer/package-versions-deprecated": true + } + } } diff --git a/composer.lock b/composer.lock index 72383d94..aa9575bd 100644 --- a/composer.lock +++ b/composer.lock @@ -4,8 +4,79 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "da97bd866ab6d3cfc52b8ce1087cd5eb", + "content-hash": "a702c875fd3b5aef3897034689a0c521", "packages": [ + { + "name": "composer/pcre", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/composer/pcre.git", + "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", + "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "shasum": "" + }, + "require": { + "php": "^5.3.2 || ^7.0 || ^8.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\Pcre\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be/" + } + ], + "description": "PCRE wrapping library that offers type-safe preg_* replacements.", + "keywords": [ + "PCRE", + "preg", + "regex", + "regular expression" + ], + "support": { + "issues": "https://github.com/composer/pcre/issues", + "source": "https://github.com/composer/pcre/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com/", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2021-12-06T15:17:27+00:00" + }, { "name": "composer/semver", "version": "3.2.6", @@ -89,25 +160,27 @@ }, { "name": "composer/xdebug-handler", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339" + "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/84674dd3a7575ba617f5a76d7e9e29a7d3891339", - "reference": "84674dd3a7575ba617f5a76d7e9e29a7d3891339", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6555461e76962fd0379c444c46fd558a0fcfb65e", + "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e", "shasum": "" }, "require": { + "composer/pcre": "^1", "php": "^5.3.2 || ^7.0 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { - "phpstan/phpstan": "^0.12.55", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" }, "type": "library", "autoload": { @@ -133,7 +206,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.2" + "source": "https://github.com/composer/xdebug-handler/tree/2.0.3" }, "funding": [ { @@ -149,7 +222,7 @@ "type": "tidelift" } ], - "time": "2021-07-31T17:03:58+00:00" + "time": "2021-12-08T13:07:32+00:00" }, { "name": "doctrine/annotations", @@ -471,16 +544,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.3.2", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "06bdbdfcd619183dd7a1a6948360f8af73b9ecec" + "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/06bdbdfcd619183dd7a1a6948360f8af73b9ecec", - "reference": "06bdbdfcd619183dd7a1a6948360f8af73b9ecec", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", + "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", "shasum": "" }, "require": { @@ -491,33 +564,32 @@ "ext-tokenizer": "*", "php": "^7.2.5 || ^8.0", "php-cs-fixer/diff": "^2.0", - "symfony/console": "^5.1.3", - "symfony/event-dispatcher": "^5.0", - "symfony/filesystem": "^5.0", - "symfony/finder": "^5.0", - "symfony/options-resolver": "^5.0", + "symfony/console": "^4.4.20 || ^5.1.3 || ^6.0", + "symfony/event-dispatcher": "^4.4.20 || ^5.0 || ^6.0", + "symfony/filesystem": "^4.4.20 || ^5.0 || ^6.0", + "symfony/finder": "^4.4.20 || ^5.0 || ^6.0", + "symfony/options-resolver": "^4.4.20 || ^5.0 || ^6.0", "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.23", "symfony/polyfill-php81": "^1.23", - "symfony/process": "^5.0", - "symfony/stopwatch": "^5.0" + "symfony/process": "^4.4.20 || ^5.0 || ^6.0", + "symfony/stopwatch": "^4.4.20 || ^5.0 || ^6.0" }, "require-dev": { "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^1.5", "mikey179/vfsstream": "^1.6.8", - "php-coveralls/php-coveralls": "^2.4.3", + "php-coveralls/php-coveralls": "^2.5.2", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.10.3", + "phpspec/prophecy": "^1.15", "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^7.5.20 || ^8.5.14 || ^9.5", + "phpunit/phpunit": "^8.5.21 || ^9.5", "phpunitgoodpractices/polyfill": "^1.5", "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^5.2.4", - "symfony/yaml": "^5.0" + "symfony/phpunit-bridge": "^5.2.4 || ^6.0", + "symfony/yaml": "^4.4.20 || ^5.0 || ^6.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -549,7 +621,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.3.2" + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.4.0" }, "funding": [ { @@ -557,7 +629,7 @@ "type": "github" } ], - "time": "2021-11-15T18:06:47+00:00" + "time": "2021-12-11T16:25:08+00:00" }, { "name": "league/html-to-markdown", @@ -654,12 +726,12 @@ "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "d4efca79da759eb9ae22fac765666b554898bba3" + "reference": "26e35e848779f5900b2352c1791027d0f1d2f9d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/d4efca79da759eb9ae22fac765666b554898bba3", - "reference": "d4efca79da759eb9ae22fac765666b554898bba3", + "url": "https://api.github.com/repos/nette/php-generator/zipball/26e35e848779f5900b2352c1791027d0f1d2f9d4", + "reference": "26e35e848779f5900b2352c1791027d0f1d2f9d4", "shasum": "" }, "require": { @@ -715,7 +787,7 @@ "issues": "https://github.com/nette/php-generator/issues", "source": "https://github.com/nette/php-generator/tree/master" }, - "time": "2021-11-23T15:34:51+00:00" + "time": "2021-12-12T17:19:35+00:00" }, { "name": "nette/utils", @@ -723,12 +795,12 @@ "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "32809e8000f727a3e5f30ff1e4faf66793b05f39" + "reference": "f9483d3fa79168ec10e2f5fc78d49f3f404c4eb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/32809e8000f727a3e5f30ff1e4faf66793b05f39", - "reference": "32809e8000f727a3e5f30ff1e4faf66793b05f39", + "url": "https://api.github.com/repos/nette/utils/zipball/f9483d3fa79168ec10e2f5fc78d49f3f404c4eb7", + "reference": "f9483d3fa79168ec10e2f5fc78d49f3f404c4eb7", "shasum": "" }, "require": { @@ -801,20 +873,20 @@ "issues": "https://github.com/nette/utils/issues", "source": "https://github.com/nette/utils/tree/master" }, - "time": "2021-11-22T23:58:34+00:00" + "time": "2021-12-12T17:35:24+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.1", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/63a79e8daa781cac14e5195e63ed8ae231dd10fd", - "reference": "63a79e8daa781cac14e5195e63ed8ae231dd10fd", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -855,9 +927,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, - "time": "2021-11-03T20:52:16+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "php-cs-fixer/diff", @@ -962,22 +1034,27 @@ }, { "name": "psr/container", - "version": "1.1.2", + "version": "2.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { "php": ">=7.4.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, "autoload": { "psr-4": { "Psr\\Container\\": "src/" @@ -1004,9 +1081,9 @@ ], "support": { "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "source": "https://github.com/php-fig/container/tree/2.0.2" }, - "time": "2021-11-05T16:50:12+00:00" + "time": "2021-11-05T16:47:00+00:00" }, { "name": "psr/event-dispatcher", @@ -1060,30 +1137,30 @@ }, { "name": "psr/log", - "version": "1.1.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1104,41 +1181,40 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "source": "https://github.com/php-fig/log/tree/3.0.0" }, - "time": "2021-05-03T11:20:27+00:00" + "time": "2021-07-14T16:46:02+00:00" }, { "name": "symfony/config", - "version": "v5.3.11", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "f080af00c441f1df40cf5c269707fdebe5740557" + "reference": "df4871981fd37f953c117b55feac03462be5a2d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/f080af00c441f1df40cf5c269707fdebe5740557", - "reference": "f080af00c441f1df40cf5c269707fdebe5740557", + "url": "https://api.github.com/repos/symfony/config/zipball/df4871981fd37f953c117b55feac03462be5a2d6", + "reference": "df4871981fd37f953c117b55feac03462be5a2d6", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/filesystem": "^4.4|^5.0", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/filesystem": "^5.4|^6.0", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.16", "symfony/polyfill-php81": "^1.22" }, "conflict": { "symfony/finder": "<4.4" }, "require-dev": { - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/yaml": "^4.4|^5.0" + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/yaml": "^5.4|^6.0" }, "suggest": { "symfony/yaml": "To use the yaml reference dumper" @@ -1169,7 +1245,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v5.3.11" + "source": "https://github.com/symfony/config/tree/v6.0.0" }, "funding": [ { @@ -1185,49 +1261,46 @@ "type": "tidelift" } ], - "time": "2021-10-29T16:05:40+00:00" + "time": "2021-11-23T19:05:29+00:00" }, { "name": "symfony/console", - "version": "v5.3.11", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "3e7ab8f5905058984899b05a4648096f558bfeba" + "reference": "fafd9802d386bf1c267e0249ddb7ceb14dcfdad4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/3e7ab8f5905058984899b05a4648096f558bfeba", - "reference": "3e7ab8f5905058984899b05a4648096f558bfeba", + "url": "https://api.github.com/repos/symfony/console/zipball/fafd9802d386bf1c267e0249ddb7ceb14dcfdad4", + "reference": "fafd9802d386bf1c267e0249ddb7ceb14dcfdad4", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "php": ">=8.0.2", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.4|^6.0" }, "conflict": { - "symfony/dependency-injection": "<4.4", - "symfony/dotenv": "<5.1", - "symfony/event-dispatcher": "<4.4", - "symfony/lock": "<4.4", - "symfony/process": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/dotenv": "<5.4", + "symfony/event-dispatcher": "<5.4", + "symfony/lock": "<5.4", + "symfony/process": "<5.4" }, "provide": { - "psr/log-implementation": "1.0|2.0" + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "psr/log": "^1|^2", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "psr/log": "^1|^2|^3", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/lock": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -1267,7 +1340,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.3.11" + "source": "https://github.com/symfony/console/tree/v6.0.1" }, "funding": [ { @@ -1283,29 +1356,29 @@ "type": "tidelift" } ], - "time": "2021-11-21T19:41:05+00:00" + "time": "2021-12-09T12:47:37+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -1334,7 +1407,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" }, "funding": [ { @@ -1350,44 +1423,42 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2021-11-01T23:48:49+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v5.3.11", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "661a7a6e085394f8513945669e31f7c1338a7e69" + "reference": "4f06d19a5f78087061f9de6df3269c139c3d289d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/661a7a6e085394f8513945669e31f7c1338a7e69", - "reference": "661a7a6e085394f8513945669e31f7c1338a7e69", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4f06d19a5f78087061f9de6df3269c139c3d289d", + "reference": "4f06d19a5f78087061f9de6df3269c139c3d289d", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2", + "symfony/event-dispatcher-contracts": "^2|^3" }, "conflict": { - "symfony/dependency-injection": "<4.4" + "symfony/dependency-injection": "<5.4" }, "provide": { "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" + "symfony/event-dispatcher-implementation": "2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^4.4|^5.0" + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/stopwatch": "^5.4|^6.0" }, "suggest": { "symfony/dependency-injection": "", @@ -1419,7 +1490,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v5.3.11" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.1" }, "funding": [ { @@ -1435,24 +1506,24 @@ "type": "tidelift" } ], - "time": "2021-11-17T12:16:12+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a" + "reference": "aa5422287b75594b90ee9cd807caf8f0df491385" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", - "reference": "66bea3b09be61613cd3b4043a65a8ec48cfa6d2a", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385", + "reference": "aa5422287b75594b90ee9cd807caf8f0df491385", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "psr/event-dispatcher": "^1" }, "suggest": { @@ -1461,7 +1532,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -1498,7 +1569,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0" }, "funding": [ { @@ -1514,26 +1585,26 @@ "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2021-07-15T12:33:35+00:00" }, { "name": "symfony/filesystem", - "version": "v5.3.4", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32" + "reference": "52b3c9cce673b014915445a432339f282e002ce6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/343f4fe324383ca46792cae728a3b6e2f708fb32", - "reference": "343f4fe324383ca46792cae728a3b6e2f708fb32", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/52b3c9cce673b014915445a432339f282e002ce6", + "reference": "52b3c9cce673b014915445a432339f282e002ce6", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.16" + "symfony/polyfill-mbstring": "~1.8" }, "type": "library", "autoload": { @@ -1561,7 +1632,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.3.4" + "source": "https://github.com/symfony/filesystem/tree/v6.0.0" }, "funding": [ { @@ -1577,25 +1648,24 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:40:44+00:00" + "time": "2021-10-29T07:35:21+00:00" }, { "name": "symfony/finder", - "version": "v5.3.7", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93" + "reference": "07debda41a4d32d33e59e6ab302af1701e15f173" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/a10000ada1e600d109a6c7632e9ac42e8bf2fb93", - "reference": "a10000ada1e600d109a6c7632e9ac42e8bf2fb93", + "url": "https://api.github.com/repos/symfony/finder/zipball/07debda41a4d32d33e59e6ab302af1701e15f173", + "reference": "07debda41a4d32d33e59e6ab302af1701e15f173", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2" }, "type": "library", "autoload": { @@ -1623,7 +1693,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v5.3.7" + "source": "https://github.com/symfony/finder/tree/v6.0.0" }, "funding": [ { @@ -1639,27 +1709,25 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-28T15:34:37+00:00" }, { "name": "symfony/options-resolver", - "version": "v5.3.7", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "4b78e55b179003a42523a362cc0e8327f7a69b5e" + "reference": "be0facf48a42a232d6c0daadd76e4eb5657a4798" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/4b78e55b179003a42523a362cc0e8327f7a69b5e", - "reference": "4b78e55b179003a42523a362cc0e8327f7a69b5e", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/be0facf48a42a232d6c0daadd76e4eb5657a4798", + "reference": "be0facf48a42a232d6c0daadd76e4eb5657a4798", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3" }, "type": "library", "autoload": { @@ -1692,7 +1760,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v5.3.7" + "source": "https://github.com/symfony/options-resolver/tree/v6.0.0" }, "funding": [ { @@ -1708,7 +1776,7 @@ "type": "tidelift" } ], - "time": "2021-08-04T21:20:46+00:00" + "time": "2021-11-23T19:05:29+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2034,161 +2102,6 @@ ], "time": "2021-05-27T12:26:48+00:00" }, - { - "name": "symfony/polyfill-php72", - "version": "v1.23.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com/", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-05-27T09:17:38+00:00" - }, - { - "name": "symfony/polyfill-php73", - "version": "v1.23.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", - "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php73\\": "" - }, - "files": [ - "bootstrap.php" - ], - "classmap": [ - "Resources/stubs" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", - "homepage": "https://symfony.com/", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-02-19T12:13:01+00:00" - }, { "name": "symfony/polyfill-php80", "version": "v1.23.1", @@ -2353,21 +2266,20 @@ }, { "name": "symfony/process", - "version": "v5.3.12", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a" + "reference": "d970c45c2186aa4331d1656950a82df64e232580" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/e498803a6e95ede78e9d5646ad32a2255c033a6a", - "reference": "e498803a6e95ede78e9d5646ad32a2255c033a6a", + "url": "https://api.github.com/repos/symfony/process/zipball/d970c45c2186aa4331d1656950a82df64e232580", + "reference": "d970c45c2186aa4331d1656950a82df64e232580", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2" }, "type": "library", "autoload": { @@ -2395,7 +2307,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v5.3.12" + "source": "https://github.com/symfony/process/tree/v6.0.0" }, "funding": [ { @@ -2411,26 +2323,25 @@ "type": "tidelift" } ], - "time": "2021-11-22T22:39:13+00:00" + "time": "2021-11-28T15:34:37+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc" + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", - "reference": "1ab11b933cd6bc5464b08e81e2c5b07dec58b0fc", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1", - "symfony/deprecation-contracts": "^2.1" + "php": ">=8.0.2", + "psr/container": "^2.0" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -2441,7 +2352,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -2478,7 +2389,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" }, "funding": [ { @@ -2494,25 +2405,25 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:48:04+00:00" + "time": "2021-11-04T17:53:12+00:00" }, { "name": "symfony/stopwatch", - "version": "v5.3.4", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "b24c6a92c6db316fee69e38c80591e080e41536c" + "reference": "0e0ed55d1ffdfadd03af180443fbdca9876483b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b24c6a92c6db316fee69e38c80591e080e41536c", - "reference": "b24c6a92c6db316fee69e38c80591e080e41536c", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/0e0ed55d1ffdfadd03af180443fbdca9876483b3", + "reference": "0e0ed55d1ffdfadd03af180443fbdca9876483b3", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/service-contracts": "^1.0|^2" + "php": ">=8.0.2", + "symfony/service-contracts": "^1|^2|^3" }, "type": "library", "autoload": { @@ -2540,7 +2451,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v5.3.4" + "source": "https://github.com/symfony/stopwatch/tree/v6.0.0" }, "funding": [ { @@ -2556,35 +2467,37 @@ "type": "tidelift" } ], - "time": "2021-07-10T08:58:57+00:00" + "time": "2021-11-23T19:05:29+00:00" }, { "name": "symfony/string", - "version": "v5.3.10", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c" + "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", - "reference": "d70c35bb20bbca71fc4ab7921e3c6bda1a82a60c", + "url": "https://api.github.com/repos/symfony/string/zipball/0cfed595758ec6e0a25591bdc8ca733c1896af32", + "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -2623,7 +2536,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.3.10" + "source": "https://github.com/symfony/string/tree/v6.0.1" }, "funding": [ { @@ -2639,32 +2552,31 @@ "type": "tidelift" } ], - "time": "2021-10-27T18:21:46+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "symfony/yaml", - "version": "v5.3.11", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "226638aa877bc4104e619a15f27d8141cd6b4e4a" + "reference": "d34390fe7e8c0fe7e4192c67c27ecf58bc7d3ed7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/226638aa877bc4104e619a15f27d8141cd6b4e4a", - "reference": "226638aa877bc4104e619a15f27d8141cd6b4e4a", + "url": "https://api.github.com/repos/symfony/yaml/zipball/d34390fe7e8c0fe7e4192c67c27ecf58bc7d3ed7", + "reference": "d34390fe7e8c0fe7e4192c67c27ecf58bc7d3ed7", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8" + "php": ">=8.0.2", + "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^4.4|^5.0" + "symfony/console": "^5.4|^6.0" }, "suggest": { "symfony/console": "For validating YAML files using the lint command" @@ -2698,7 +2610,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v5.3.11" + "source": "https://github.com/symfony/yaml/tree/v6.0.1" }, "funding": [ { @@ -2714,20 +2626,20 @@ "type": "tidelift" } ], - "time": "2021-11-20T16:42:42+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "twig/twig", - "version": "v3.3.3", + "version": "v3.3.4", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569" + "reference": "65cb6f0b956485e1664f13d023c55298a4bb59ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/a27fa056df8a6384316288ca8b0fa3a35fdeb569", - "reference": "a27fa056df8a6384316288ca8b0fa3a35fdeb569", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/65cb6f0b956485e1664f13d023c55298a4bb59ca", + "reference": "65cb6f0b956485e1664f13d023c55298a4bb59ca", "shasum": "" }, "require": { @@ -2778,7 +2690,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.3.3" + "source": "https://github.com/twigphp/Twig/tree/v3.3.4" }, "funding": [ { @@ -2790,22 +2702,22 @@ "type": "tidelift" } ], - "time": "2021-09-17T08:44:23+00:00" + "time": "2021-11-25T13:46:55+00:00" } ], "packages-dev": [ { "name": "api-platform/core", - "version": "v2.6.6", + "version": "v2.6.7", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "25c71b216473844cdbe5bf284ccbeeb26acd76e7" + "reference": "8a19950a816ccd7cbf38323addbba72b14ac2372" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/25c71b216473844cdbe5bf284ccbeeb26acd76e7", - "reference": "25c71b216473844cdbe5bf284ccbeeb26acd76e7", + "url": "https://api.github.com/repos/api-platform/core/zipball/8a19950a816ccd7cbf38323addbba72b14ac2372", + "reference": "8a19950a816ccd7cbf38323addbba72b14ac2372", "shasum": "" }, "require": { @@ -2813,13 +2725,13 @@ "fig/link-util": "^1.0", "php": ">=7.1", "psr/cache": "^1.0 || ^2.0 || ^3.0", - "psr/container": "^1.0", - "symfony/http-foundation": "^4.4 || ^5.1", - "symfony/http-kernel": "^4.4 || ^5.1", - "symfony/property-access": "^3.4.19 || ^4.4 || ^5.1", - "symfony/property-info": "^3.4 || ^4.4 || ^5.2.1", - "symfony/serializer": "^4.4 || ^5.1", - "symfony/web-link": "^4.4 || ^5.1", + "psr/container": "^1.0 || ^2.0", + "symfony/http-foundation": "^4.4 || ^5.1 || ^6.0", + "symfony/http-kernel": "^4.4 || ^5.1 || ^6.0", + "symfony/property-access": "^3.4.19 || ^4.4 || ^5.1 || ^6.0", + "symfony/property-info": "^3.4 || ^4.4 || ^5.2.1 || ^6.0", + "symfony/serializer": "^4.4 || ^5.1 || ^6.0", + "symfony/web-link": "^4.4 || ^5.1 || ^6.0", "willdurand/negotiation": "^2.0.3 || ^3.0" }, "conflict": { @@ -2830,60 +2742,61 @@ }, "require-dev": { "behat/behat": "^3.1", - "behat/mink": "^1.7", + "behat/mink": "^1.9@dev", "doctrine/annotations": "^1.7", - "doctrine/cache": "^1.11", + "doctrine/cache": "^1.11 || ^2.1", "doctrine/common": "^2.11 || ^3.0", "doctrine/data-fixtures": "^1.2.2", + "doctrine/dbal": "^2.6 || ^3.0", "doctrine/doctrine-bundle": "^1.12 || ^2.0", "doctrine/mongodb-odm": "^2.2", "doctrine/mongodb-odm-bundle": "^4.0", - "doctrine/orm": "^2.6.4 || ^3.0", + "doctrine/orm": "^2.6.4", "elasticsearch/elasticsearch": "^6.0 || ^7.0", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", "friends-of-behat/symfony-extension": "^2.1", "guzzlehttp/guzzle": "^6.0 || ^7.0", - "jangregor/phpstan-prophecy": "^0.8", + "jangregor/phpstan-prophecy": "^1.0", "justinrainbow/json-schema": "^5.2.1", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.1", "phpdocumentor/type-resolver": "^0.3 || ^0.4 || ^1.4", - "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^0.12.65", - "phpstan/phpstan-doctrine": "^0.12.7", - "phpstan/phpstan-phpunit": "^0.12.4", - "phpstan/phpstan-symfony": "^0.12.4", - "psr/log": "^1.0", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.1", + "phpstan/phpstan-doctrine": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-symfony": "^1.0", + "psr/log": "^1.0 || ^2.0 || ^3.0", "ramsey/uuid": "^3.7 || ^4.0", "ramsey/uuid-doctrine": "^1.4", - "soyuka/contexts": "^3.3.1", + "soyuka/contexts": "dev-main", "soyuka/stubs-mongodb": "^1.0", - "symfony/asset": "^3.4 || ^4.4 || ^5.1", - "symfony/browser-kit": "^4.4 || ^5.1", - "symfony/cache": "^3.4 || ^4.4 || ^5.1", - "symfony/config": "^3.4 || ^4.4 || ^5.1", - "symfony/console": "^3.4 || ^4.4 || ^5.1", - "symfony/css-selector": "^3.4 || ^4.4 || ^5.1", - "symfony/debug": "^3.4 || ^4.4 || ^5.1", - "symfony/dependency-injection": "^3.4 || ^4.4 || ^5.1", - "symfony/doctrine-bridge": "^3.4 || ^4.4 || ^5.1", - "symfony/dom-crawler": "^3.4 || ^4.4 || ^5.1", - "symfony/event-dispatcher": "^3.4 || ^4.4 || ^5.1", - "symfony/expression-language": "^3.4 || ^4.4 || ^5.1", - "symfony/finder": "^3.4 || ^4.4 || ^5.1", - "symfony/form": "^3.4 || ^4.4 || ^5.1", - "symfony/framework-bundle": "^4.4 || ^5.1", - "symfony/http-client": "^4.4 || ^5.1", + "symfony/asset": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/browser-kit": "^4.4 || ^5.1 || ^6.0", + "symfony/cache": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/config": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/console": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/css-selector": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/debug": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/dependency-injection": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/doctrine-bridge": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/dom-crawler": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/event-dispatcher": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/expression-language": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/finder": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/form": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/framework-bundle": "^4.4 || ^5.1 || ^6.0", + "symfony/http-client": "^4.4 || ^5.1 || ^6.0", "symfony/mercure-bundle": "*", - "symfony/messenger": "^4.4 || ^5.1", - "symfony/phpunit-bridge": "^5.1.7", - "symfony/routing": "^3.4 || ^4.4 || ^5.1", - "symfony/security-bundle": "^3.4 || ^4.4 || ^5.1", - "symfony/security-core": "^4.4 || ^5.1", - "symfony/twig-bundle": "^3.4 || ^4.4 || ^5.1", - "symfony/validator": "^3.4 || ^4.4 || ^5.1", - "symfony/web-profiler-bundle": "^4.4 || ^5.1", - "symfony/yaml": "^3.4 || ^4.4 || ^5.1", + "symfony/messenger": "^4.4 || ^5.1 || ^6.0", + "symfony/phpunit-bridge": "^5.4 || ^6.0", + "symfony/routing": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/security-bundle": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/security-core": "^4.4 || ^5.1 || ^6.0", + "symfony/twig-bundle": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/validator": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/web-profiler-bundle": "^4.4 || ^5.1 || ^6.0", + "symfony/yaml": "^3.4 || ^4.4 || ^5.1 || ^6.0", "twig/twig": "^1.42.3 || ^2.12 || ^3.0", "webonyx/graphql-php": "^14.0" }, @@ -2907,10 +2820,10 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.7.x-dev" + "dev-main": "2.6.x-dev" }, "symfony": { - "require": "^3.4 || ^4.4 || ^5.1" + "require": "^3.4 || ^4.4 || ^5.1 || ^6.0" } }, "autoload": { @@ -2944,7 +2857,7 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v2.6.6" + "source": "https://github.com/api-platform/core/tree/v2.6.7" }, "funding": [ { @@ -2952,7 +2865,7 @@ "type": "tidelift" } ], - "time": "2021-09-29T19:11:04+00:00" + "time": "2021-12-24T14:12:38+00:00" }, { "name": "composer/package-versions-deprecated", @@ -3287,36 +3200,38 @@ }, { "name": "doctrine/dbal", - "version": "3.1.4", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9" + "reference": "5d54f63541d7bed1156cb5c9b79274ced61890e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/821b4f01a36ce63ed36c090ea74767b72db367e9", - "reference": "821b4f01a36ce63ed36c090ea74767b72db367e9", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/5d54f63541d7bed1156cb5c9b79274ced61890e4", + "reference": "5d54f63541d7bed1156cb5c9b79274ced61890e4", "shasum": "" }, "require": { "composer/package-versions-deprecated": "^1.11.99", - "doctrine/cache": "^1.0|^2.0", + "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", - "php": "^7.3 || ^8.0" + "php": "^7.3 || ^8.0", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" }, "require-dev": { "doctrine/coding-standard": "9.0.0", "jetbrains/phpstorm-stubs": "2021.1", - "phpstan/phpstan": "1.1.1", - "phpstan/phpstan-strict-rules": "^1", + "phpstan/phpstan": "1.2.0", + "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "9.5.10", "psalm/plugin-phpunit": "0.16.1", "squizlabs/php_codesniffer": "3.6.1", "symfony/cache": "^5.2|^6.0", "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0", - "vimeo/psalm": "4.12.0" + "vimeo/psalm": "4.13.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -3376,7 +3291,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.1.4" + "source": "https://github.com/doctrine/dbal/tree/3.2.0" }, "funding": [ { @@ -3392,7 +3307,7 @@ "type": "tidelift" } ], - "time": "2021-11-15T16:44:33+00:00" + "time": "2021-11-26T21:00:12+00:00" }, { "name": "doctrine/deprecations", @@ -3602,16 +3517,16 @@ }, { "name": "doctrine/orm", - "version": "2.10.2", + "version": "2.10.4", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "81d472f6f96b8b571cafefe8d2fef89ed9446a62" + "reference": "cccb2e2fdfed2969afb3d65c5ea82bafdefbe1a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/81d472f6f96b8b571cafefe8d2fef89ed9446a62", - "reference": "81d472f6f96b8b571cafefe8d2fef89ed9446a62", + "url": "https://api.github.com/repos/doctrine/orm/zipball/cccb2e2fdfed2969afb3d65c5ea82bafdefbe1a7", + "reference": "cccb2e2fdfed2969afb3d65c5ea82bafdefbe1a7", "shasum": "" }, "require": { @@ -3641,12 +3556,12 @@ "doctrine/annotations": "^1.13", "doctrine/coding-standard": "^9.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "0.12.99", + "phpstan/phpstan": "1.2.0", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", - "squizlabs/php_codesniffer": "3.6.1", + "squizlabs/php_codesniffer": "3.6.2", "symfony/cache": "^4.4 || ^5.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.10.0" + "vimeo/psalm": "4.15.0" }, "suggest": { "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", @@ -3695,9 +3610,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.10.2" + "source": "https://github.com/doctrine/orm/tree/2.10.4" }, - "time": "2021-10-21T17:57:02+00:00" + "time": "2021-12-20T21:23:47+00:00" }, { "name": "doctrine/persistence", @@ -3864,9 +3779,6 @@ "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" - }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", @@ -4238,16 +4150,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.14.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { @@ -4299,9 +4211,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" }, - "time": "2021-09-10T09:02:12+00:00" + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpspec/prophecy-phpunit", @@ -4421,16 +4333,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.9", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { @@ -4486,7 +4398,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.9" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" }, "funding": [ { @@ -4494,20 +4406,20 @@ "type": "github" } ], - "time": "2021-11-19T15:21:02+00:00" + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -4546,7 +4458,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -4554,7 +4466,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -4842,25 +4754,28 @@ }, { "name": "psr/link", - "version": "1.1.1", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/php-fig/link.git", - "reference": "846c25f58a1f02b93a00f2404e3626b6bf9b7807" + "reference": "84b159194ecfd7eaa472280213976e96415433f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/link/zipball/846c25f58a1f02b93a00f2404e3626b6bf9b7807", - "reference": "846c25f58a1f02b93a00f2404e3626b6bf9b7807", + "url": "https://api.github.com/repos/php-fig/link/zipball/84b159194ecfd7eaa472280213976e96415433f7", + "reference": "84b159194ecfd7eaa472280213976e96415433f7", "shasum": "" }, "require": { "php": ">=8.0.0" }, + "suggest": { + "fig/link-util": "Provides some useful PSR-13 utilities" + }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -4889,9 +4804,9 @@ "rest" ], "support": { - "source": "https://github.com/php-fig/link/tree/1.1.1" + "source": "https://github.com/php-fig/link/tree/2.0.1" }, - "time": "2021-03-11T22:59:13+00:00" + "time": "2021-03-11T23:00:27+00:00" }, { "name": "sebastian/cli-parser", @@ -5746,7 +5661,6 @@ "type": "github" } ], - "abandoned": true, "time": "2020-09-28T06:45:17+00:00" }, { @@ -5860,65 +5774,67 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v5.3.11", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "9b220ebc6fb4d5f15a8b74887c059b4d57ba85f8" + "reference": "d5b0bef7fc93f60a5a5acafffea4f651ffa01ce5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/9b220ebc6fb4d5f15a8b74887c059b4d57ba85f8", - "reference": "9b220ebc6fb4d5f15a8b74887c059b4d57ba85f8", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/d5b0bef7fc93f60a5a5acafffea4f651ffa01ce5", + "reference": "d5b0bef7fc93f60a5a5acafffea4f651ffa01ce5", "shasum": "" }, "require": { "doctrine/event-manager": "~1.0", "doctrine/persistence": "^2", - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/service-contracts": "^1.1|^2" + "symfony/service-contracts": "^1.1|^2|^3" }, "conflict": { - "doctrine/dbal": "<2.10", + "doctrine/dbal": "<2.13.1", + "doctrine/lexer": "<1.1", "doctrine/orm": "<2.7.3", "phpunit/phpunit": "<5.4.3", - "symfony/dependency-injection": "<4.4", - "symfony/form": "<5.1", - "symfony/http-kernel": "<5", - "symfony/messenger": "<4.4", - "symfony/property-info": "<5", - "symfony/security-bundle": "<5", - "symfony/security-core": "<5.3", - "symfony/validator": "<5.2" + "symfony/cache": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/form": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/messenger": "<5.4", + "symfony/property-info": "<5.4", + "symfony/security-bundle": "<5.4", + "symfony/security-core": "<6.0", + "symfony/validator": "<5.4" }, "require-dev": { "composer/package-versions-deprecated": "^1.8", "doctrine/annotations": "^1.10.4", "doctrine/collections": "~1.0", "doctrine/data-fixtures": "^1.1", - "doctrine/dbal": "^2.10|^3.0", + "doctrine/dbal": "^2.13.1|^3.0", "doctrine/orm": "^2.7.3", - "symfony/cache": "^5.1", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/doctrine-messenger": "^5.1", - "symfony/expression-language": "^4.4|^5.0", - "symfony/form": "^5.1.3", - "symfony/http-kernel": "^5.0", - "symfony/messenger": "^4.4|^5.0", - "symfony/property-access": "^4.4|^5.0", - "symfony/property-info": "^5.0", - "symfony/proxy-manager-bridge": "^4.4|^5.0", - "symfony/security-core": "^5.3", - "symfony/stopwatch": "^4.4|^5.0", - "symfony/translation": "^4.4|^5.0", - "symfony/uid": "^5.1", - "symfony/validator": "^5.2", - "symfony/var-dumper": "^4.4|^5.0" + "psr/log": "^1|^2|^3", + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/doctrine-messenger": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/form": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/messenger": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/proxy-manager-bridge": "^5.4|^6.0", + "symfony/security-core": "^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "symfony/validator": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0" }, "suggest": { "doctrine/data-fixtures": "", @@ -5954,7 +5870,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v5.3.11" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.0.1" }, "funding": [ { @@ -5970,32 +5886,35 @@ "type": "tidelift" } ], - "time": "2021-11-12T11:38:27+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "symfony/error-handler", - "version": "v5.3.11", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "eec73dd7218713f48a7996583a741b3bae58c8d3" + "reference": "944193d25c564c8c80411a5d02eb2be823d57d5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/eec73dd7218713f48a7996583a741b3bae58c8d3", - "reference": "eec73dd7218713f48a7996583a741b3bae58c8d3", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/944193d25c564c8c80411a5d02eb2be823d57d5c", + "reference": "944193d25c564c8c80411a5d02eb2be823d57d5c", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^4.4|^5.0" + "symfony/var-dumper": "^5.4|^6.0" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" }, + "bin": [ + "Resources/bin/patch-type-declarations" + ], "type": "library", "autoload": { "psr-4": { @@ -6022,7 +5941,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.3.11" + "source": "https://github.com/symfony/error-handler/tree/v6.0.1" }, "funding": [ { @@ -6038,42 +5957,44 @@ "type": "tidelift" } ], - "time": "2021-11-13T13:42:37+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { - "name": "symfony/http-client-contracts", - "version": "v2.5.0", + "name": "symfony/http-foundation", + "version": "v6.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/http-client-contracts.git", - "reference": "ec82e57b5b714dbb69300d348bd840b345e24166" + "url": "https://github.com/symfony/http-foundation.git", + "reference": "4c55dff16ba400dc81c56b6234e5942f9b9c7bcc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-client-contracts/zipball/ec82e57b5b714dbb69300d348bd840b345e24166", - "reference": "ec82e57b5b714dbb69300d348bd840b345e24166", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4c55dff16ba400dc81c56b6234e5942f9b9c7bcc", + "reference": "4c55dff16ba400dc81c56b6234e5942f9b9c7bcc", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=8.0.2", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.1" + }, + "require-dev": { + "predis/predis": "~1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0" }, "suggest": { - "symfony/http-client-implementation": "" + "symfony/mime": "To use the file extension guesser" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" - } - }, "autoload": { "psr-4": { - "Symfony\\Contracts\\HttpClient\\": "" - } + "Symfony\\Component\\HttpFoundation\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6081,26 +6002,18 @@ ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" + "name": "Fabien Potencier", + "email": "fabien@symfony.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Generic abstractions related to HTTP clients", + "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], "support": { - "source": "https://github.com/symfony/http-client-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/http-foundation/tree/v6.0.1" }, "funding": [ { @@ -6116,41 +6029,77 @@ "type": "tidelift" } ], - "time": "2021-11-03T09:24:47+00:00" + "time": "2021-12-09T12:47:37+00:00" }, { - "name": "symfony/http-foundation", - "version": "v5.3.11", + "name": "symfony/http-kernel", + "version": "v6.0.1", "source": { "type": "git", - "url": "https://github.com/symfony/http-foundation.git", - "reference": "d1e7059ebeb0b8f9fe5eb5b26eacd2e3c1f371cc" + "url": "https://github.com/symfony/http-kernel.git", + "reference": "cd7ed5337e67e1be91526184006fe7c1603283cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d1e7059ebeb0b8f9fe5eb5b26eacd2e3c1f371cc", - "reference": "d1e7059ebeb0b8f9fe5eb5b26eacd2e3c1f371cc", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cd7ed5337e67e1be91526184006fe7c1603283cb", + "reference": "cd7ed5337e67e1be91526184006fe7c1603283cb", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-mbstring": "~1.1", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2", + "psr/log": "^1|^2|^3", + "symfony/error-handler": "^5.4|^6.0", + "symfony/event-dispatcher": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "symfony/browser-kit": "<5.4", + "symfony/cache": "<5.4", + "symfony/config": "<5.4", + "symfony/console": "<5.4", + "symfony/dependency-injection": "<5.4", + "symfony/doctrine-bridge": "<5.4", + "symfony/form": "<5.4", + "symfony/http-client": "<5.4", + "symfony/mailer": "<5.4", + "symfony/messenger": "<5.4", + "symfony/translation": "<5.4", + "symfony/twig-bridge": "<5.4", + "symfony/validator": "<5.4", + "twig/twig": "<2.13" + }, + "provide": { + "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { - "predis/predis": "~1.0", - "symfony/cache": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0" + "psr/cache": "^1.0|^2.0|^3.0", + "symfony/browser-kit": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/css-selector": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/dom-crawler": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/process": "^5.4|^6.0", + "symfony/routing": "^5.4|^6.0", + "symfony/stopwatch": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/translation-contracts": "^1.1|^2|^3", + "twig/twig": "^2.13|^3.0.4" }, "suggest": { - "symfony/mime": "To use the file extension guesser" + "symfony/browser-kit": "", + "symfony/config": "", + "symfony/console": "", + "symfony/dependency-injection": "" }, "type": "library", "autoload": { "psr-4": { - "Symfony\\Component\\HttpFoundation\\": "" + "Symfony\\Component\\HttpKernel\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6170,10 +6119,10 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Defines an object-oriented layer for the HTTP specification", + "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.3.11" + "source": "https://github.com/symfony/http-kernel/tree/v6.0.1" }, "funding": [ { @@ -6189,80 +6138,51 @@ "type": "tidelift" } ], - "time": "2021-11-04T16:37:19+00:00" + "time": "2021-12-09T13:42:47+00:00" }, { - "name": "symfony/http-kernel", - "version": "v5.3.12", + "name": "symfony/phpunit-bridge", + "version": "v6.0.0", "source": { "type": "git", - "url": "https://github.com/symfony/http-kernel.git", - "reference": "f53025cd1d91b1af85d6d9e17eefa98e31ee953b" + "url": "https://github.com/symfony/phpunit-bridge.git", + "reference": "5d6cc6720085084f504d2482fc4a2f268784006b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/f53025cd1d91b1af85d6d9e17eefa98e31ee953b", - "reference": "f53025cd1d91b1af85d6d9e17eefa98e31ee953b", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/5d6cc6720085084f504d2482fc4a2f268784006b", + "reference": "5d6cc6720085084f504d2482fc4a2f268784006b", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/log": "^1|^2", - "symfony/deprecation-contracts": "^2.1", - "symfony/error-handler": "^4.4|^5.0", - "symfony/event-dispatcher": "^5.0", - "symfony/http-client-contracts": "^1.1|^2", - "symfony/http-foundation": "^5.3.7", - "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-php73": "^1.9", - "symfony/polyfill-php80": "^1.16" + "php": ">=7.1.3" }, "conflict": { - "symfony/browser-kit": "<4.4", - "symfony/cache": "<5.0", - "symfony/config": "<5.0", - "symfony/console": "<4.4", - "symfony/dependency-injection": "<5.3", - "symfony/doctrine-bridge": "<5.0", - "symfony/form": "<5.0", - "symfony/http-client": "<5.0", - "symfony/mailer": "<5.0", - "symfony/messenger": "<5.0", - "symfony/translation": "<5.0", - "symfony/twig-bridge": "<5.0", - "symfony/validator": "<5.0", - "twig/twig": "<2.13" - }, - "provide": { - "psr/log-implementation": "1.0|2.0" + "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { - "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^4.4|^5.0", - "symfony/config": "^5.0", - "symfony/console": "^4.4|^5.0", - "symfony/css-selector": "^4.4|^5.0", - "symfony/dependency-injection": "^5.3", - "symfony/dom-crawler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/finder": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/routing": "^4.4|^5.0", - "symfony/stopwatch": "^4.4|^5.0", - "symfony/translation": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "twig/twig": "^2.13|^3.0.4" + "symfony/deprecation-contracts": "^2.1|^3.0", + "symfony/error-handler": "^5.4|^6.0" }, "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" + "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + }, + "bin": [ + "bin/simple-phpunit" + ], + "type": "symfony-bridge", + "extra": { + "thanks": { + "name": "phpunit/phpunit", + "url": "https://github.com/sebastianbergmann/phpunit" + } }, - "type": "library", "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\HttpKernel\\": "" + "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ "/Tests/" @@ -6274,18 +6194,18 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides a structured process for converting a Request into a Response", + "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.3.12" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.0.0" }, "funding": [ { @@ -6301,54 +6221,41 @@ "type": "tidelift" } ], - "time": "2021-11-24T08:46:46+00:00" + "time": "2021-11-29T15:32:57+00:00" }, { - "name": "symfony/phpunit-bridge", - "version": "v5.3.11", + "name": "symfony/polyfill-php72", + "version": "v1.23.0", "source": { "type": "git", - "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "7b3637f0ce55c510a0fbe6e4d49b223103b7bf7b" + "url": "https://github.com/symfony/polyfill-php72.git", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/7b3637f0ce55c510a0fbe6e4d49b223103b7bf7b", - "reference": "7b3637f0ce55c510a0fbe6e4d49b223103b7bf7b", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", + "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", "shasum": "" }, "require": { - "php": ">=7.1.3", - "symfony/deprecation-contracts": "^2.1" - }, - "conflict": { - "phpunit/phpunit": "<7.5|9.1.2" - }, - "require-dev": { - "symfony/error-handler": "^4.4|^5.0" - }, - "suggest": { - "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + "php": ">=7.1" }, - "bin": [ - "bin/simple-phpunit" - ], - "type": "symfony-bridge", + "type": "library", "extra": { + "branch-alias": { + "dev-main": "1.23-dev" + }, "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" } }, "autoload": { - "files": [ - "bootstrap.php" - ], "psr-4": { - "Symfony\\Bridge\\PhpUnit\\": "" + "Symfony\\Polyfill\\Php72\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "files": [ + "bootstrap.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -6365,10 +6272,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Provides utilities for PHPUnit, especially user deprecation notices management", + "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", "homepage": "https://symfony.com/", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v5.3.11" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" }, "funding": [ { @@ -6384,30 +6297,28 @@ "type": "tidelift" } ], - "time": "2021-11-12T11:38:27+00:00" + "time": "2021-05-27T09:17:38+00:00" }, { "name": "symfony/property-access", - "version": "v5.3.8", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66" + "reference": "e0b66975319b4648e0cbf267878b07d8e2d11e2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66", - "reference": "2fbab5f95ddb6b8e85f38a6a8a04a17c0acc4d66", + "url": "https://api.github.com/repos/symfony/property-access/zipball/e0b66975319b4648e0cbf267878b07d8e2d11e2e", + "reference": "e0b66975319b4648e0cbf267878b07d8e2d11e2e", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.16", - "symfony/property-info": "^5.2" + "php": ">=8.0.2", + "symfony/property-info": "^5.4|^6.0" }, "require-dev": { - "symfony/cache": "^4.4|^5.0" + "symfony/cache": "^5.4|^6.0" }, "suggest": { "psr/cache-implementation": "To cache access methods." @@ -6449,7 +6360,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v5.3.8" + "source": "https://github.com/symfony/property-access/tree/v6.0.0" }, "funding": [ { @@ -6465,39 +6376,38 @@ "type": "tidelift" } ], - "time": "2021-09-10T11:55:24+00:00" + "time": "2021-11-28T15:34:37+00:00" }, { "name": "symfony/property-info", - "version": "v5.3.8", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "39de5bed8c036f76ec0457ec52908e45d5497947" + "reference": "56e98f48ee2dc89688d1870e66d834627a17db6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/39de5bed8c036f76ec0457ec52908e45d5497947", - "reference": "39de5bed8c036f76ec0457ec52908e45d5497947", + "url": "https://api.github.com/repos/symfony/property-info/zipball/56e98f48ee2dc89688d1870e66d834627a17db6d", + "reference": "56e98f48ee2dc89688d1870e66d834627a17db6d", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php80": "^1.16", - "symfony/string": "^5.1" + "php": ">=8.0.2", + "symfony/string": "^5.4|^6.0" }, "conflict": { - "phpdocumentor/reflection-docblock": "<3.2.2", + "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/dependency-injection": "<4.4" + "symfony/dependency-injection": "<5.4" }, "require-dev": { "doctrine/annotations": "^1.10.4", - "phpdocumentor/reflection-docblock": "^3.0|^4.0|^5.0", - "symfony/cache": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/serializer": "^4.4|^5.0" + "phpdocumentor/reflection-docblock": "^5.2", + "phpstan/phpdoc-parser": "^1.0", + "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/serializer": "^5.4|^6.0" }, "suggest": { "phpdocumentor/reflection-docblock": "To use the PHPDoc", @@ -6539,7 +6449,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v5.3.8" + "source": "https://github.com/symfony/property-info/tree/v6.0.0" }, "funding": [ { @@ -6555,56 +6465,54 @@ "type": "tidelift" } ], - "time": "2021-09-07T07:41:40+00:00" + "time": "2021-11-04T18:05:01+00:00" }, { "name": "symfony/serializer", - "version": "v5.3.12", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "bf570839e289e0bdde69c9fa867d3a42f5e8fde1" + "reference": "60637437ca5bfa519e4085e9ea28ead456f9d85e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/bf570839e289e0bdde69c9fa867d3a42f5e8fde1", - "reference": "bf570839e289e0bdde69c9fa867d3a42f5e8fde1", + "url": "https://api.github.com/repos/symfony/serializer/zipball/60637437ca5bfa519e4085e9ea28ead456f9d85e", + "reference": "60637437ca5bfa519e4085e9ea28ead456f9d85e", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2", + "symfony/polyfill-ctype": "~1.8" }, "conflict": { "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/dependency-injection": "<4.4", - "symfony/property-access": "<4.4", - "symfony/property-info": "<5.3", - "symfony/yaml": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/property-access": "<5.4", + "symfony/property-info": "<5.4", + "symfony/yaml": "<5.4" }, "require-dev": { "doctrine/annotations": "^1.12", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", - "symfony/cache": "^4.4|^5.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/filesystem": "^4.4|^5.0", - "symfony/form": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0", - "symfony/property-access": "^4.4.9|^5.0.9", - "symfony/property-info": "^5.3", - "symfony/uid": "^5.1", - "symfony/validator": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0", - "symfony/var-exporter": "^4.4|^5.0", - "symfony/yaml": "^4.4|^5.0" + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/filesystem": "^5.4|^6.0", + "symfony/form": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", + "symfony/validator": "^5.4|^6.0", + "symfony/var-dumper": "^5.4|^6.0", + "symfony/var-exporter": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" }, "suggest": { "psr/cache-implementation": "For using the metadata cache.", @@ -6641,7 +6549,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v5.3.12" + "source": "https://github.com/symfony/serializer/tree/v6.0.1" }, "funding": [ { @@ -6657,24 +6565,24 @@ "type": "tidelift" } ], - "time": "2021-11-24T08:13:09+00:00" + "time": "2021-12-01T16:45:37+00:00" }, { "name": "symfony/translation-contracts", - "version": "v2.5.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e" + "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/d28150f0f44ce854e942b671fc2620a98aae1b1e", - "reference": "d28150f0f44ce854e942b671fc2620a98aae1b1e", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", + "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", "shasum": "" }, "require": { - "php": ">=7.2.5" + "php": ">=8.0.2" }, "suggest": { "symfony/translation-implementation": "" @@ -6682,7 +6590,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.5-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -6719,7 +6627,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v2.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.0" }, "funding": [ { @@ -6735,61 +6643,58 @@ "type": "tidelift" } ], - "time": "2021-08-17T14:20:01+00:00" + "time": "2021-09-07T12:43:40+00:00" }, { "name": "symfony/validator", - "version": "v5.3.12", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "379ca8939ebcab78d835e188673396a9f8d6eee8" + "reference": "981c9baef0f1052bc9a6cedb63da8608b71de348" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/379ca8939ebcab78d835e188673396a9f8d6eee8", - "reference": "379ca8939ebcab78d835e188673396a9f8d6eee8", + "url": "https://api.github.com/repos/symfony/validator/zipball/981c9baef0f1052bc9a6cedb63da8608b71de348", + "reference": "981c9baef0f1052bc9a6cedb63da8608b71de348", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.16", - "symfony/translation-contracts": "^1.1|^2" + "symfony/translation-contracts": "^1.1|^2|^3" }, "conflict": { - "doctrine/lexer": "<1.0.2", + "doctrine/annotations": "<1.13", + "doctrine/lexer": "<1.1", "phpunit/phpunit": "<5.4.3", - "symfony/dependency-injection": "<4.4", - "symfony/expression-language": "<5.1", - "symfony/http-kernel": "<4.4", - "symfony/intl": "<4.4", - "symfony/property-info": "<5.3", - "symfony/translation": "<4.4", - "symfony/yaml": "<4.4" + "symfony/dependency-injection": "<5.4", + "symfony/expression-language": "<5.4", + "symfony/http-kernel": "<5.4", + "symfony/intl": "<5.4", + "symfony/property-info": "<5.4", + "symfony/translation": "<5.4", + "symfony/yaml": "<5.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4", - "doctrine/cache": "^1.0|^2.0", + "doctrine/annotations": "^1.13", "egulias/email-validator": "^2.1.10|^3", - "symfony/cache": "^4.4|^5.0", - "symfony/config": "^4.4|^5.0", - "symfony/console": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/expression-language": "^5.1", - "symfony/finder": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/http-kernel": "^4.4|^5.0", - "symfony/intl": "^4.4|^5.0", - "symfony/mime": "^4.4|^5.0", - "symfony/property-access": "^4.4|^5.0", - "symfony/property-info": "^5.3", - "symfony/translation": "^4.4|^5.0", - "symfony/yaml": "^4.4|^5.0" + "symfony/cache": "^5.4|^6.0", + "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", + "symfony/expression-language": "^5.4|^6.0", + "symfony/finder": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/http-foundation": "^5.4|^6.0", + "symfony/http-kernel": "^5.4|^6.0", + "symfony/intl": "^5.4|^6.0", + "symfony/mime": "^5.4|^6.0", + "symfony/property-access": "^5.4|^6.0", + "symfony/property-info": "^5.4|^6.0", + "symfony/translation": "^5.4|^6.0", + "symfony/yaml": "^5.4|^6.0" }, "suggest": { "egulias/email-validator": "Strict (RFC compliant) email validation", @@ -6829,7 +6734,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v5.3.12" + "source": "https://github.com/symfony/validator/tree/v6.0.1" }, "funding": [ { @@ -6845,35 +6750,35 @@ "type": "tidelift" } ], - "time": "2021-11-22T22:24:25+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "symfony/var-dumper", - "version": "v5.3.11", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "a029b3a11b757f9cc8693040339153b4745a913f" + "reference": "9ca4948ec35bb15175e5475ba83dfdb13042a86c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/a029b3a11b757f9cc8693040339153b4745a913f", - "reference": "a029b3a11b757f9cc8693040339153b4745a913f", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9ca4948ec35bb15175e5475ba83dfdb13042a86c", + "reference": "9ca4948ec35bb15175e5475ba83dfdb13042a86c", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2", + "symfony/polyfill-mbstring": "~1.0" }, "conflict": { "phpunit/phpunit": "<5.4.3", - "symfony/console": "<4.4" + "symfony/console": "<5.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", + "symfony/console": "^5.4|^6.0", + "symfony/process": "^5.4|^6.0", + "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -6917,7 +6822,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.3.11" + "source": "https://github.com/symfony/var-dumper/tree/v6.0.1" }, "funding": [ { @@ -6933,35 +6838,34 @@ "type": "tidelift" } ], - "time": "2021-11-12T11:38:27+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "symfony/web-link", - "version": "v5.3.4", + "version": "v6.0.1", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "0075c9949c30a61d9b9e7483686d72d261480ef1" + "reference": "bc5ac011d2670331b8d5fab89253c774568f6877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/0075c9949c30a61d9b9e7483686d72d261480ef1", - "reference": "0075c9949c30a61d9b9e7483686d72d261480ef1", + "url": "https://api.github.com/repos/symfony/web-link/zipball/bc5ac011d2670331b8d5fab89253c774568f6877", + "reference": "bc5ac011d2670331b8d5fab89253c774568f6877", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/link": "^1.0", - "symfony/polyfill-php80": "^1.16" + "php": ">=8.0.2", + "psr/link": "^1.1|^2.0" }, "conflict": { - "symfony/http-kernel": "<5.3" + "symfony/http-kernel": "<5.4" }, "provide": { - "psr/link-implementation": "1.0" + "psr/link-implementation": "1.0|2.0" }, "require-dev": { - "symfony/http-kernel": "^5.3" + "symfony/http-kernel": "^5.4|^6.0" }, "suggest": { "symfony/http-kernel": "" @@ -7004,7 +6908,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v5.3.4" + "source": "https://github.com/symfony/web-link/tree/v6.0.1" }, "funding": [ { @@ -7020,7 +6924,7 @@ "type": "tidelift" } ], - "time": "2021-07-21T12:40:44+00:00" + "time": "2021-12-08T15:13:44+00:00" }, { "name": "theseer/tokenizer", @@ -7200,5 +7104,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.2.0" } From 49d017719f97165d414c73361c97cdadd24856b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 24 Dec 2021 15:42:39 +0100 Subject: [PATCH 200/258] docs: changelog for version 4.0.0 (#360) --- CHANGELOG.md | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c80f0959..e6d947d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog +## 4.0.0 + +* feat: support updating existing files +* feat: generate PHP 8 attributes +* feat: generate API Platform Core `security` properties for classes and properties +* feat: support for HTTPS URLs of Schema.org +* feat: add YAML support for Doctrine ORM "resolve entity" +* feat: support for interface namespaces +* feat: compatibility with Symfony 6 +* feat: compatibility with PHP 8.1 +* feat: now uses Nette generator +* fix: the whole code base has been refactored, a log of bugs have been fixed + ## 3.0.0 * Support for [the Web Ontology Language (OWL)](https://en.wikipedia.org/wiki/Web_Ontology_Language) (including for [the ActivityStream vocabulary](https://www.w3.org/TR/activitystreams-core/)) From 28c699ce430fb1caef35da5c2901f2aaa0da56d0 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Fri, 4 Feb 2022 17:37:32 +0100 Subject: [PATCH 201/258] fix: use FQCN when using an enum in callback constraint and remove ApiResource from the enum (#362) --- bin/compile | 2 ++ .../ApiPlatformCoreAttributeGenerator.php | 4 ++-- .../ConstraintAttributeGenerator.php | 2 +- src/Model/Attribute.php | 6 +++--- .../ApiPlatformCoreAttributeGeneratorTest.php | 21 ++++++++----------- .../ConstraintAttributeGeneratorTest.php | 3 ++- tests/e2e/customized/App/Entity/Person.php | 21 +++++++++++++++++++ tests/e2e/customized/App/Enum/GenderType.php | 21 +++++++++++++++++++ tests/e2e/original/App/Entity/Person.php | 21 +++++++++++++++++++ tests/e2e/original/App/Enum/GenderType.php | 21 +++++++++++++++++++ tests/e2e/schema.yml | 3 +++ 11 files changed, 106 insertions(+), 19 deletions(-) create mode 100644 tests/e2e/customized/App/Enum/GenderType.php create mode 100644 tests/e2e/original/App/Enum/GenderType.php diff --git a/bin/compile b/bin/compile index 49d9818e..d003ab15 100755 --- a/bin/compile +++ b/bin/compile @@ -11,6 +11,7 @@ php schema.phar generate tmp/original tests/e2e/schema.yml -n -vv --ansi; diff tests/e2e/original/App/Entity/Person.php tmp/original/App/Entity/Person.php; diff tests/e2e/original/App/Entity/PostalAddress.php tmp/original/App/Entity/PostalAddress.php; diff tests/e2e/original/App/Entity/Thing.php tmp/original/App/Entity/Thing.php; +diff tests/e2e/original/App/Enum/GenderType.php tmp/original/App/Enum/GenderType.php; # Already generated files @@ -21,3 +22,4 @@ php schema.phar generate tmp/customized tests/e2e/schema.yml -n -vv --ansi; diff tests/e2e/customized/App/Entity/Person.php tmp/customized/App/Entity/Person.php; diff tests/e2e/customized/App/Entity/PostalAddress.php tmp/customized/App/Entity/PostalAddress.php; diff tests/e2e/customized/App/Entity/Thing.php tmp/customized/App/Entity/Thing.php; +diff tests/e2e/customized/App/Enum/GenderType.php tmp/customized/App/Enum/GenderType.php; diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 1832cc53..33fbc3bc 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -35,7 +35,7 @@ final class ApiPlatformCoreAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($class->isAbstract) { + if ($class->isAbstract || $class->isEnum()) { return []; } @@ -104,6 +104,6 @@ public function generatePropertyAttributes(Property $property, string $className */ public function generateUses(Class_ $class): array { - return !$class->isEnum() ? [new Use_(ApiResource::class), new Use_(ApiProperty::class)] : []; + return [new Use_(ApiResource::class), new Use_(ApiProperty::class)]; } } diff --git a/src/AttributeGenerator/ConstraintAttributeGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php index aefc9ae8..f307c53b 100644 --- a/src/AttributeGenerator/ConstraintAttributeGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -71,7 +71,7 @@ public function generatePropertyAttributes(Property $property, string $className } if ($property->isEnum && $property->range && $property->rangeName) { - $args = ['callback' => [$property->rangeName, 'toArray']]; + $args = ['callback' => [new Literal(sprintf('%s::class', $property->rangeName)), 'toArray']]; if ($property->isArray) { $args['multiple'] = true; diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php index 9678f924..b68b5e3b 100644 --- a/src/Model/Attribute.php +++ b/src/Model/Attribute.php @@ -22,11 +22,11 @@ final class Attribute private string $name; - /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] */ + /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] */ private array $args; /** - * @param (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] $args + * @param (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] $args */ public function __construct(string $name, array $args = []) { @@ -40,7 +40,7 @@ public function name(): string } /** - * @return (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal)[] + * @return (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] */ public function args(): array { diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index ca369ca0..c99682df 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -58,9 +58,9 @@ public function testGenerateClassAttributes(Class_ $class, array $attributes): v public function provideGenerateClassAttributesCases(): \Generator { - yield 'classical' => [new Class_('Res', new RdfResource('https://schema.org/Res')), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])]]; + yield 'classical' => [new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])]]; - $class = new Class_('WithOperations', new RdfResource('https://schema.org/WithOperations')); + $class = new Class_('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); $class->operations = [ 'item' => ['get' => ['route_name' => 'api_about_get']], 'collection' => [], @@ -71,9 +71,14 @@ public function provideGenerateClassAttributesCases(): \Generator $class->isAbstract = true; yield 'abstract' => [$class, []]; - yield 'with short name' => [(new Class_('WithShortName', new RdfResource('https://schema.org/DifferentLocalName'))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; + $resource = new RdfResource('https://schema.org/MyEnum', new RdfGraph()); + $resource->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); + $class = new Class_('Enum', $resource); + yield 'enum' => [$class, []]; - $class = new Class_('WithSecurity', new RdfResource('https://schema.org/WithSecurity')); + yield 'with short name' => [(new Class_('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; + + $class = new Class_('WithSecurity', new RdfResource('https://schema.org/WithSecurity', new RdfGraph())); $class->security = "is_granted('ROLE_USER')"; yield 'with security' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"])]]; } @@ -107,12 +112,4 @@ public function testGenerateUses(): void { $this->assertEquals([new Use_(ApiResource::class), new Use_(ApiProperty::class)], $this->generator->generateUses(new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); } - - public function testGenerateNoUsesForEnum(): void - { - $graph = new RdfGraph(); - $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); - $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - $this->assertSame([], $this->generator->generateUses(new Class_('MyEnum', $myEnum))); - } } diff --git a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php index b9f83ff0..31820df6 100644 --- a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php @@ -23,6 +23,7 @@ use Doctrine\Inflector\InflectorFactory; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use Nette\PhpGenerator\Literal; use PHPUnit\Framework\TestCase; use Psr\Log\NullLogger; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; @@ -105,7 +106,7 @@ public function provideGeneratePropertyAttributesCases(): \Generator $property->rangeName = 'Enum'; $property->isEnum = true; $property->isArray = true; - yield 'enum' => [$property, [new Attribute('Assert\Choice', ['callback' => ['Enum', 'toArray'], 'multiple' => true])]]; + yield 'enum' => [$property, [new Attribute('Assert\Choice', ['callback' => [new Literal('Enum::class'), 'toArray'], 'multiple' => true])]]; } public function testGenerateUses(): void diff --git a/tests/e2e/customized/App/Entity/Person.php b/tests/e2e/customized/App/Entity/Person.php index 51b50125..29aa1c86 100644 --- a/tests/e2e/customized/App/Entity/Person.php +++ b/tests/e2e/customized/App/Entity/Person.php @@ -7,6 +7,7 @@ use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; use App\Attribute\MyCustomAttribute; +use App\Enum\GenderType; use App\Model\MyCustomClass; use App\Model\MyCustomInterface; use Doctrine\ORM\Mapping as ORM; @@ -68,6 +69,16 @@ class Person extends MyCustomClass implements MyCustomInterface #[Groups(['extra'])] private ?string $additionalName = null; + /** + * Gender of something, typically a \[\[Person\]\], but possibly also fictional characters, animals, etc. While https://schema.org/Male and https://schema.org/Female may be used, text strings are also acceptable for people who do not identify as a binary gender. The \[\[gender\]\] property can also be used in an extended sense to cover e.g. the gender of sports teams. As with the gender of individuals, we do not try to enumerate all possibilities. A mixed-gender \[\[SportsTeam\]\] can be indicated with a text value of "Mixed". + * + * @see https://schema.org/gender + */ + #[ORM\Column(nullable: true)] + #[ApiProperty(iri: 'https://schema.org/gender')] + #[Assert\Choice(callback: [GenderType::class, 'toArray'])] + private ?string $gender = null; + /** * Physical address of the item. * @@ -160,6 +171,16 @@ public function getAdditionalName(): ?string return $this->additionalName; } + public function setGender(?string $gender): void + { + $this->gender = $gender; + } + + public function getGender(): ?string + { + return $this->gender; + } + public function setAddress(?PostalAddress $address): void { $this->address = $address; diff --git a/tests/e2e/customized/App/Enum/GenderType.php b/tests/e2e/customized/App/Enum/GenderType.php new file mode 100644 index 00000000..bb68634a --- /dev/null +++ b/tests/e2e/customized/App/Enum/GenderType.php @@ -0,0 +1,21 @@ +additionalName; } + public function setGender(?string $gender): void + { + $this->gender = $gender; + } + + public function getGender(): ?string + { + return $this->gender; + } + public function setAddress(?PostalAddress $address): void { $this->address = $address; diff --git a/tests/e2e/original/App/Enum/GenderType.php b/tests/e2e/original/App/Enum/GenderType.php new file mode 100644 index 00000000..bb68634a --- /dev/null +++ b/tests/e2e/original/App/Enum/GenderType.php @@ -0,0 +1,21 @@ + Date: Mon, 7 Feb 2022 16:45:55 +0100 Subject: [PATCH 202/258] fix: make sure relations are generated (#363) --- .../DoctrineMongoDBAttributeGenerator.php | 7 ++-- .../DoctrineOrmAttributeGenerator.php | 9 +++--- .../DoctrineMongoDBAttributeGeneratorTest.php | 5 +-- .../DoctrineOrmAttributeGeneratorTest.php | 7 ++-- tests/e2e/customized/App/Entity/Person.php | 32 +++++++++++++++++++ tests/e2e/original/App/Entity/Person.php | 32 +++++++++++++++++++ tests/e2e/schema.yml | 1 + 7 files changed, 82 insertions(+), 11 deletions(-) diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index c7324027..727d81a5 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -68,7 +68,7 @@ public function generateClassAttributes(Class_ $class): array */ public function generatePropertyAttributes(Property $property, string $className): array { - if (null === $property->range) { + if (null === $property->range || null === $property->rangeName) { return []; } @@ -77,11 +77,12 @@ public function generatePropertyAttributes(Property $property, string $className } $type = null; + $isDataType = $this->phpTypeConverter->isDatatype($property->range); if ($property->isEnum) { $type = $property->isArray ? 'simple_array' : 'string'; - } elseif ($property->isArray ?? false) { + } elseif ($property->isArray && $isDataType) { $type = 'collection'; - } elseif (null !== $phpType = $this->phpTypeConverter->getPhpType($property, $this->config, [])) { + } elseif (!$property->isArray && $isDataType && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { switch ($property->range->getUri()) { case 'http://www.w3.org/2001/XMLSchema#time': case 'https://schema.org/Time': diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index b35660bd..fda8ca03 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -93,7 +93,7 @@ public function generateClassAttributes(Class_ $class): array */ public function generatePropertyAttributes(Property $property, string $className): array { - if (null === $property->rangeName) { + if (null === $property->range || null === $property->rangeName) { return []; } @@ -110,11 +110,12 @@ public function generatePropertyAttributes(Property $property, string $className } $type = null; + $isDataType = $this->phpTypeConverter->isDatatype($property->range); if ($property->isEnum) { $type = $property->isArray ? 'simple_array' : 'string'; - } elseif ($property->isArray) { + } elseif ($property->isArray && $isDataType) { $type = 'json'; - } elseif ($property->range && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { + } elseif (!$property->isArray && $isDataType && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { switch ($property->range->getUri()) { // TODO: use more precise types for int (smallint, bigint...) case 'http://www.w3.org/2001/XMLSchema#time': @@ -173,7 +174,7 @@ public function generatePropertyAttributes(Property $property, string $className } if (null === $relationName = $this->getRelationName($property->rangeName)) { - $this->logger->error('The type "{type}" of the property "{property}" from the class "{class}" doesn\'t exist', ['type' => $property->range ? $property->range->getUri() : $property->rangeName, 'property' => $property->name(), 'class' => $className]); + $this->logger->error('The type "{type}" of the property "{property}" from the class "{class}" doesn\'t exist', ['type' => $property->range->getUri(), 'property' => $property->name(), 'class' => $className]); return []; } diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 1c178769..1915b2c3 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -55,8 +55,8 @@ protected function setUp(): void $enumProperty->isArray = true; $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); - $collectionProperty->rangeName = 'Thing'; - $collectionProperty->range = new RdfResource('https://schema.org/Thing'); + $collectionProperty->rangeName = 'string'; + $collectionProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#string'); $collectionProperty->isArray = true; $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); @@ -72,6 +72,7 @@ protected function setUp(): void $relationsProperty->rangeName = 'Person'; $relationsProperty->range = new RdfResource('https://schema.org/Person'); $relationsProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; + $relationsProperty->isArray = true; $vehicle->addProperty($relationsProperty); $this->classMap[$vehicle->name()] = $vehicle; diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index 190afd40..97879b4b 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -58,8 +58,8 @@ protected function setUp(): void $enumProperty->isArray = true; $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); - $collectionProperty->rangeName = 'Thing'; - $collectionProperty->range = new RdfResource('https://schema.org/Thing'); + $collectionProperty->rangeName = 'string'; + $collectionProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#string'); $collectionProperty->isArray = true; $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); @@ -96,16 +96,19 @@ protected function setUp(): void $relation0NProperty->rangeName = 'QuantitativeValue'; $relation0NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation0NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_0_N; + $relation0NProperty->isArray = true; $vehicle->addProperty($relation0NProperty); $relation1NProperty = new Property('relation1_N'); $relation1NProperty->rangeName = 'QuantitativeValue'; $relation1NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation1NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; + $relation1NProperty->isArray = true; $vehicle->addProperty($relation1NProperty); $relationNNProperty = new Property('relationN_N'); $relationNNProperty->rangeName = 'QuantitativeValue'; $relationNNProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relationNNProperty->cardinality = CardinalitiesExtractor::CARDINALITY_N_N; + $relationNNProperty->isArray = true; $vehicle->addProperty($relationNNProperty); $this->classMap[$vehicle->name()] = $vehicle; diff --git a/tests/e2e/customized/App/Entity/Person.php b/tests/e2e/customized/App/Entity/Person.php index 29aa1c86..99e5e15b 100644 --- a/tests/e2e/customized/App/Entity/Person.php +++ b/tests/e2e/customized/App/Entity/Person.php @@ -10,6 +10,8 @@ use App\Enum\GenderType; use App\Model\MyCustomClass; use App\Model\MyCustomInterface; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Serializer\Annotation\Groups; @@ -127,10 +129,25 @@ class Person extends MyCustomClass implements MyCustomInterface #[Assert\Url] private ?string $url = null; + /** + * A sibling of the person. + * + * @see https://schema.org/siblings + */ + #[ORM\ManyToMany(targetEntity: 'App\Entity\Person')] + #[ORM\InverseJoinColumn(unique: true)] + #[ApiProperty(iri: 'https://schema.org/siblings')] + private ?Collection $siblings = null; + /** @see _:customColumn */ #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] private ?Person $customColumn = null; + public function __construct() + { + $this->siblings = new ArrayCollection(); + } + public function getMyProperty(): string { return $this->myProperty; @@ -231,6 +248,21 @@ public function getUrl(): ?string return $this->url; } + public function addSibling(Person $sibling): void + { + $this->siblings[] = $sibling; + } + + public function removeSibling(Person $sibling): void + { + $this->siblings->removeElement($sibling); + } + + public function getSiblings(): Collection + { + return $this->siblings; + } + public function setCustomColumn(?Person $customColumn): void { $this->customColumn = $customColumn; diff --git a/tests/e2e/original/App/Entity/Person.php b/tests/e2e/original/App/Entity/Person.php index 647f41a2..55416876 100644 --- a/tests/e2e/original/App/Entity/Person.php +++ b/tests/e2e/original/App/Entity/Person.php @@ -7,6 +7,8 @@ use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; use App\Enum\GenderType; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\Serializer\Annotation\Groups; @@ -118,12 +120,27 @@ class Person extends Thing #[Assert\Url] private ?string $url = null; + /** + * A sibling of the person. + * + * @see https://schema.org/siblings + */ + #[ORM\ManyToMany(targetEntity: 'App\Entity\Person')] + #[ORM\InverseJoinColumn(unique: true)] + #[ApiProperty(iri: 'https://schema.org/siblings')] + private ?Collection $siblings = null; + /** * @see _:customColumn */ #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] private ?Person $customColumn = null; + public function __construct() + { + $this->siblings = new ArrayCollection(); + } + public function getId(): ?int { return $this->id; @@ -219,6 +236,21 @@ public function getUrl(): ?string return $this->url; } + public function addSibling(Person $sibling): void + { + $this->siblings[] = $sibling; + } + + public function removeSibling(Person $sibling): void + { + $this->siblings->removeElement($sibling); + } + + public function getSiblings(): Collection + { + return $this->siblings; + } + public function setCustomColumn(?Person $customColumn): void { $this->customColumn = $customColumn; diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 74398b69..5350becd 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -29,6 +29,7 @@ types: telephone: ~ email: { unique: true, security: "is_granted('ROLE_ADMIN')" } url: ~ + siblings: { cardinality: "(0..*)" } customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } PostalAddress: properties: From 019e21cbb7772581094d8ad0baa73a75b496a004 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 8 Feb 2022 18:31:08 +0100 Subject: [PATCH 203/258] fix: inheritance from Intangible should not create warning (#365) --- bin/compile | 2 + src/ClassMutator/ClassPropertiesAppender.php | 2 +- tests/e2e/customized/App/Entity/Brand.php | 67 ++++++++++++++++++++ tests/e2e/original/App/Entity/Brand.php | 67 ++++++++++++++++++++ tests/e2e/schema.yml | 4 ++ 5 files changed, 141 insertions(+), 1 deletion(-) create mode 100644 tests/e2e/customized/App/Entity/Brand.php create mode 100644 tests/e2e/original/App/Entity/Brand.php diff --git a/bin/compile b/bin/compile index d003ab15..8a720065 100755 --- a/bin/compile +++ b/bin/compile @@ -8,6 +8,7 @@ rm -rf tmp/original php schema.phar generate tmp/original tests/e2e/schema.yml -n -vv --ansi; +diff tests/e2e/original/App/Entity/Brand.php tmp/original/App/Entity/Brand.php; diff tests/e2e/original/App/Entity/Person.php tmp/original/App/Entity/Person.php; diff tests/e2e/original/App/Entity/PostalAddress.php tmp/original/App/Entity/PostalAddress.php; diff tests/e2e/original/App/Entity/Thing.php tmp/original/App/Entity/Thing.php; @@ -19,6 +20,7 @@ cp -r tests/e2e/customized tmp/ php schema.phar generate tmp/customized tests/e2e/schema.yml -n -vv --ansi; +diff tests/e2e/customized/App/Entity/Brand.php tmp/customized/App/Entity/Brand.php; diff tests/e2e/customized/App/Entity/Person.php tmp/customized/App/Entity/Person.php; diff tests/e2e/customized/App/Entity/PostalAddress.php tmp/customized/App/Entity/PostalAddress.php; diff tests/e2e/customized/App/Entity/Thing.php tmp/customized/App/Entity/Thing.php; diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 4da0eed0..006c6925 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -62,7 +62,7 @@ public function __invoke(Class_ $class): Class_ } foreach ($this->getParentClasses($class->resource()) as $typeInHierarchy) { - foreach ($this->propertiesMap[$typeInHierarchy->getUri()] as $property) { + foreach ($this->propertiesMap[$typeInHierarchy->getUri()] ?? [] as $property) { if ($key !== $property->localName()) { continue; } diff --git a/tests/e2e/customized/App/Entity/Brand.php b/tests/e2e/customized/App/Entity/Brand.php new file mode 100644 index 00000000..a4093a2a --- /dev/null +++ b/tests/e2e/customized/App/Entity/Brand.php @@ -0,0 +1,67 @@ +id; + } + + public function setName(?string $name): void + { + $this->name = $name; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setSlogan(?string $slogan): void + { + $this->slogan = $slogan; + } + + public function getSlogan(): ?string + { + return $this->slogan; + } +} diff --git a/tests/e2e/original/App/Entity/Brand.php b/tests/e2e/original/App/Entity/Brand.php new file mode 100644 index 00000000..a4093a2a --- /dev/null +++ b/tests/e2e/original/App/Entity/Brand.php @@ -0,0 +1,67 @@ +id; + } + + public function setName(?string $name): void + { + $this->name = $name; + } + + public function getName(): ?string + { + return $this->name; + } + + public function setSlogan(?string $slogan): void + { + $this->slogan = $slogan; + } + + public function getSlogan(): ?string + { + return $this->slogan; + } +} diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 5350becd..e917a6bd 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -31,6 +31,10 @@ types: url: ~ siblings: { cardinality: "(0..*)" } customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } + Brand: + properties: + name: ~ + slogan: ~ PostalAddress: properties: addressCountry: { range: https://schema.org/Text } From 29df094eda8f50581b6a8586828c034e42632830 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 8 Feb 2022 18:31:36 +0100 Subject: [PATCH 204/258] chore: update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e6d947d4..c7531ca8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 4.0.1 + +* fix: use FQCN when using an enum in callback constraint and remove ApiResource from the enum +* fix: make sure relations are generated +* fix: inheritance from Intangible should not create warning + ## 4.0.0 * feat: support updating existing files From 9a6d5c773ee8247ab7b2546b3aa9f746787ae24a Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 9 Jun 2022 11:32:08 +0200 Subject: [PATCH 205/258] feat: add OpenAPI support (#368) --- README.md | 6 +- bin/compile | 33 +- box.json.dist | 3 + composer.json | 4 +- composer.lock | 1269 ++++---- phpstan.neon | 4 +- .../AbstractAnnotationGenerator.php | 25 +- .../PhpDocAnnotationGenerator.php | 43 +- .../AbstractAttributeGenerator.php | 25 +- .../ApiPlatformCoreAttributeGenerator.php | 14 +- .../ConstraintAttributeGenerator.php | 27 +- .../DoctrineMongoDBAttributeGenerator.php | 42 +- .../DoctrineOrmAttributeGenerator.php | 41 +- src/ClassMutator/AnnotationsAppender.php | 42 +- src/ClassMutator/AttributeAppender.php | 28 +- src/ClassMutator/ClassIdAppender.php | 12 +- src/ClassMutator/ClassInterfaceMutator.php | 4 +- src/ClassMutator/ClassMutatorInterface.php | 2 +- src/ClassMutator/ClassParentMutator.php | 21 +- src/ClassMutator/ClassPropertiesAppender.php | 49 +- .../ClassPropertiesTypehintMutator.php | 6 +- src/ClassMutator/EnumClassMutator.php | 34 +- src/Command/DumpConfigurationCommand.php | 4 +- src/Command/ExtractCardinalitiesCommand.php | 6 +- src/Command/GenerateCommand.php | 104 +- src/FilesGenerator.php | 175 ++ src/GoodRelationsBridge.php | 17 +- src/Model/Class_.php | 56 +- src/Model/Constant.php | 16 +- src/Model/Property.php | 24 +- src/OpenApi/ClassGenerator.php | 282 ++ src/OpenApi/ClassMutator/EnumClassMutator.php | 46 + src/OpenApi/Generator.php | 62 + src/OpenApi/Model/Class_.php | 53 + src/OpenApi/Model/Constant.php | 39 + src/OpenApi/Model/Property.php | 43 + src/OpenApi/PhpTypeConverter.php | 68 + .../PropertyGenerator/IdPropertyGenerator.php | 34 + .../PropertyGenerator/PropertyGenerator.php | 90 + src/PhpTypeConverter.php | 39 +- src/PhpTypeConverterInterface.php | 63 - src/PropertyGenerator/IdPropertyGenerator.php | 21 +- .../IdPropertyGeneratorInterface.php | 21 + src/PropertyGenerator/PropertyGenerator.php | 180 +- .../PropertyGeneratorInterface.php | 33 + src/Schema/ClassMutator/EnumClassMutator.php | 54 + src/Schema/Generator.php | 77 + src/Schema/Model/Class_.php | 71 + src/Schema/Model/Constant.php | 39 + src/Schema/Model/Property.php | 44 + .../PropertyGenerator/IdPropertyGenerator.php | 50 + .../PropertyGenerator/PropertyGenerator.php | 210 ++ src/Schema/TypeConverter.php | 112 + ...n.php => SchemaGeneratorConfiguration.php} | 13 +- src/TwigBuilder.php | 38 + src/TypesGenerator.php | 244 +- .../PhpDocAnnotationGeneratorTest.php | 13 +- .../ApiPlatformCoreAttributeGeneratorTest.php | 28 +- .../ConstraintAttributeGeneratorTest.php | 29 +- .../DoctrineMongoDBAttributeGeneratorTest.php | 30 +- .../DoctrineOrmAttributeGeneratorTest.php | 38 +- .../SerializerGroupAttributeGeneratorTest.php | 12 +- tests/ClassMutator/ClassParentMutatorTest.php | 25 +- .../ClassPropertiesAppenderTest.php | 36 +- tests/Command/DumpConfigurationTest.php | 5 + tests/Model/InterfaceTest.php | 2 +- tests/{ => Schema}/Model/ClassTest.php | 23 +- tests/TypesGeneratorTest.php | 24 +- .../App/Schema}/Entity/Brand.php | 2 +- .../App/{ => Schema}/Entity/Person.php | 13 +- .../App/Schema}/Entity/PostalAddress.php | 2 +- .../App/{ => Schema}/Entity/Thing.php | 2 +- .../App/{ => Schema}/Enum/GenderType.php | 2 +- tests/e2e/openapi.yml | 2757 +++++++++++++++++ tests/e2e/openapi_ref.yml | 800 +++++ .../e2e/original/App/OpenApi/Entity/Book.php | 190 ++ .../e2e/original/App/OpenApi/Entity/Order.php | 107 + .../original/App/OpenApi/Entity/Parchment.php | 64 + tests/e2e/original/App/OpenApi/Entity/Pet.php | 128 + .../original/App/OpenApi/Entity/Review.php | 145 + .../original/App/OpenApi/Entity/TopBook.php | 103 + .../e2e/original/App/OpenApi/Entity/User.php | 133 + .../original/App/OpenApi/Enum/OrderStatus.php | 33 + .../original/App/OpenApi/Enum/PetStatus.php | 33 + .../App/Schema}/Entity/Brand.php | 2 +- .../App/{ => Schema}/Entity/Person.php | 13 +- .../App/Schema}/Entity/PostalAddress.php | 2 +- .../App/{ => Schema}/Entity/Thing.php | 2 +- .../App/{ => Schema}/Enum/GenderType.php | 2 +- tests/e2e/schema.yml | 5 + tests/e2e/schema_openapi.yml | 7 + tests/e2e/schema_openapi_ref.yml | 7 + 92 files changed, 7426 insertions(+), 1555 deletions(-) create mode 100644 src/FilesGenerator.php create mode 100644 src/OpenApi/ClassGenerator.php create mode 100644 src/OpenApi/ClassMutator/EnumClassMutator.php create mode 100644 src/OpenApi/Generator.php create mode 100644 src/OpenApi/Model/Class_.php create mode 100644 src/OpenApi/Model/Constant.php create mode 100644 src/OpenApi/Model/Property.php create mode 100644 src/OpenApi/PhpTypeConverter.php create mode 100644 src/OpenApi/PropertyGenerator/IdPropertyGenerator.php create mode 100644 src/OpenApi/PropertyGenerator/PropertyGenerator.php create mode 100644 src/PropertyGenerator/IdPropertyGeneratorInterface.php create mode 100644 src/PropertyGenerator/PropertyGeneratorInterface.php create mode 100644 src/Schema/ClassMutator/EnumClassMutator.php create mode 100644 src/Schema/Generator.php create mode 100644 src/Schema/Model/Class_.php create mode 100644 src/Schema/Model/Constant.php create mode 100644 src/Schema/Model/Property.php create mode 100644 src/Schema/PropertyGenerator/IdPropertyGenerator.php create mode 100644 src/Schema/PropertyGenerator/PropertyGenerator.php create mode 100644 src/Schema/TypeConverter.php rename src/{TypesGeneratorConfiguration.php => SchemaGeneratorConfiguration.php} (96%) create mode 100644 src/TwigBuilder.php rename tests/{ => Schema}/Model/ClassTest.php (78%) rename tests/e2e/{original/App => customized/App/Schema}/Entity/Brand.php (97%) rename tests/e2e/customized/App/{ => Schema}/Entity/Person.php (95%) rename tests/e2e/{original/App => customized/App/Schema}/Entity/PostalAddress.php (99%) rename tests/e2e/customized/App/{ => Schema}/Entity/Thing.php (95%) rename tests/e2e/customized/App/{ => Schema}/Enum/GenderType.php (93%) create mode 100644 tests/e2e/openapi.yml create mode 100644 tests/e2e/openapi_ref.yml create mode 100644 tests/e2e/original/App/OpenApi/Entity/Book.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/Order.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/Parchment.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/Pet.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/Review.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/TopBook.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/User.php create mode 100644 tests/e2e/original/App/OpenApi/Enum/OrderStatus.php create mode 100644 tests/e2e/original/App/OpenApi/Enum/PetStatus.php rename tests/e2e/{customized/App => original/App/Schema}/Entity/Brand.php (97%) rename tests/e2e/original/App/{ => Schema}/Entity/Person.php (95%) rename tests/e2e/{customized/App => original/App/Schema}/Entity/PostalAddress.php (99%) rename tests/e2e/original/App/{ => Schema}/Entity/Thing.php (95%) rename tests/e2e/original/App/{ => Schema}/Enum/GenderType.php (93%) create mode 100644 tests/e2e/schema_openapi.yml create mode 100644 tests/e2e/schema_openapi_ref.yml diff --git a/README.md b/README.md index 21487cc9..0f3b266c 100644 --- a/README.md +++ b/README.md @@ -2,10 +2,10 @@ `schema` is a command line tool part of [the API Platform framework](https://api-platform.com) that instantly generates a set of PHP classes from vocabularies such as (but not limited to) [Schema.org](https://schema.org) -or [ActivityStreams](https://www.w3.org/TR/activitystreams-core/). +or [ActivityStreams](https://www.w3.org/TR/activitystreams-core/) or from an [OpenAPI](https://www.openapis.org/) documentation. -[![GitHub Actions](https://github.com/api-platform/schema-generator/workflows/CI/badge.svg?branch=master)](https://github.com/api-platform/schema-generator/actions?query=workflow%3ACI+branch%3Amaster) -[![Coverage Status](https://coveralls.io/repos/github/api-platform/schema-generator/badge.svg?branch=master)](https://coveralls.io/github/api-platform/schema-generator?branch=master) +[![GitHub Actions](https://github.com/api-platform/schema-generator/workflows/CI/badge.svg?branch=main)](https://github.com/api-platform/schema-generator/actions?query=workflow%3ACI+branch%3Amain) +[![Coverage Status](https://coveralls.io/repos/github/api-platform/schema-generator/badge.svg?branch=main)](https://coveralls.io/github/api-platform/schema-generator?branch=main) ## Documentation diff --git a/bin/compile b/bin/compile index 8a720065..66318e24 100755 --- a/bin/compile +++ b/bin/compile @@ -8,11 +8,11 @@ rm -rf tmp/original php schema.phar generate tmp/original tests/e2e/schema.yml -n -vv --ansi; -diff tests/e2e/original/App/Entity/Brand.php tmp/original/App/Entity/Brand.php; -diff tests/e2e/original/App/Entity/Person.php tmp/original/App/Entity/Person.php; -diff tests/e2e/original/App/Entity/PostalAddress.php tmp/original/App/Entity/PostalAddress.php; -diff tests/e2e/original/App/Entity/Thing.php tmp/original/App/Entity/Thing.php; -diff tests/e2e/original/App/Enum/GenderType.php tmp/original/App/Enum/GenderType.php; +diff tests/e2e/original/App/Schema/Entity/Brand.php tmp/original/App/Schema/Entity/Brand.php; +diff tests/e2e/original/App/Schema/Entity/Person.php tmp/original/App/Schema/Entity/Person.php; +diff tests/e2e/original/App/Schema/Entity/PostalAddress.php tmp/original/App/Schema/Entity/PostalAddress.php; +diff tests/e2e/original/App/Schema/Entity/Thing.php tmp/original/App/Schema/Entity/Thing.php; +diff tests/e2e/original/App/Schema/Enum/GenderType.php tmp/original/App/Schema/Enum/GenderType.php; # Already generated files @@ -20,8 +20,21 @@ cp -r tests/e2e/customized tmp/ php schema.phar generate tmp/customized tests/e2e/schema.yml -n -vv --ansi; -diff tests/e2e/customized/App/Entity/Brand.php tmp/customized/App/Entity/Brand.php; -diff tests/e2e/customized/App/Entity/Person.php tmp/customized/App/Entity/Person.php; -diff tests/e2e/customized/App/Entity/PostalAddress.php tmp/customized/App/Entity/PostalAddress.php; -diff tests/e2e/customized/App/Entity/Thing.php tmp/customized/App/Entity/Thing.php; -diff tests/e2e/customized/App/Enum/GenderType.php tmp/customized/App/Enum/GenderType.php; +diff tests/e2e/customized/App/Schema/Entity/Brand.php tmp/customized/App/Schema/Entity/Brand.php; +diff tests/e2e/customized/App/Schema/Entity/Person.php tmp/customized/App/Schema/Entity/Person.php; +diff tests/e2e/customized/App/Schema/Entity/PostalAddress.php tmp/customized/App/Schema/Entity/PostalAddress.php; +diff tests/e2e/customized/App/Schema/Entity/Thing.php tmp/customized/App/Schema/Entity/Thing.php; +diff tests/e2e/customized/App/Schema/Enum/GenderType.php tmp/customized/App/Schema/Enum/GenderType.php; + +php schema.phar generate tmp/original tests/e2e/schema_openapi.yml -n -vv --ansi; + +diff tests/e2e/original/App/OpenApi/Entity/Book.php tmp/original/App/OpenApi/Entity/Book.php; +diff tests/e2e/original/App/OpenApi/Entity/Parchment.php tmp/original/App/OpenApi/Entity/Parchment.php; +diff tests/e2e/original/App/OpenApi/Entity/Review.php tmp/original/App/OpenApi/Entity/Review.php; +diff tests/e2e/original/App/OpenApi/Entity/TopBook.php tmp/original/App/OpenApi/Entity/TopBook.php; + +php schema.phar generate tmp/original tests/e2e/schema_openapi_ref.yml -n -vv --ansi; + +diff tests/e2e/original/App/OpenApi/Entity/Order.php tmp/original/App/OpenApi/Entity/Order.php; +diff tests/e2e/original/App/OpenApi/Entity/Pet.php tmp/original/App/OpenApi/Entity/Pet.php; +diff tests/e2e/original/App/OpenApi/Entity/User.php tmp/original/App/OpenApi/Entity/User.php; diff --git a/box.json.dist b/box.json.dist index 85d3a276..def052f6 100644 --- a/box.json.dist +++ b/box.json.dist @@ -14,6 +14,9 @@ "files": [ "vendor/twig/twig/src/TwigTest.php" ], + "directories": [ + "vendor/cebe/php-openapi/src/spec" + ], "force-autodiscovery": true, "compression": "GZ", diff --git a/composer.json b/composer.json index f5b2d996..a14df74f 100644 --- a/composer.json +++ b/composer.json @@ -46,7 +46,9 @@ "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0-dev", "nette/utils": "^3.1 || ^4.0-dev", - "nikic/php-parser": "^4.13" + "nikic/php-parser": "^4.13", + "cebe/php-openapi": "^1.6", + "symfony/string": "^5.2 || ^6.0" }, "require-dev": { "api-platform/core": "^2.5", diff --git a/composer.lock b/composer.lock index aa9575bd..e0364352 100644 --- a/composer.lock +++ b/composer.lock @@ -4,34 +4,103 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "a702c875fd3b5aef3897034689a0c521", + "content-hash": "6c3e382a4abfab20197f48b9bb9e1e68", "packages": [ + { + "name": "cebe/php-openapi", + "version": "1.7.0", + "source": { + "type": "git", + "url": "https://github.com/cebe/php-openapi.git", + "reference": "020d72b8e3a9a60bc229953e93eda25c49f46f45" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/cebe/php-openapi/zipball/020d72b8e3a9a60bc229953e93eda25c49f46f45", + "reference": "020d72b8e3a9a60bc229953e93eda25c49f46f45", + "shasum": "" + }, + "require": { + "ext-json": "*", + "justinrainbow/json-schema": "^5.2", + "php": ">=7.1.0", + "symfony/yaml": "^3.4 || ^4 || ^5 || ^6" + }, + "conflict": { + "symfony/yaml": "3.4.0 - 3.4.4 || 4.0.0 - 4.4.17 || 5.0.0 - 5.1.9 || 5.2.0" + }, + "require-dev": { + "apis-guru/openapi-directory": "1.0.0", + "cebe/indent": "*", + "mermade/openapi3-examples": "1.0.0", + "nexmo/api-specification": "1.0.0", + "oai/openapi-specification": "3.0.3", + "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^6.5 || ^7.5 || ^8.5 || ^9.4" + }, + "bin": [ + "bin/php-openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "cebe\\openapi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "https://cebe.cc/", + "role": "Creator" + } + ], + "description": "Read and write OpenAPI yaml/json files and make the content accessable in PHP objects.", + "homepage": "https://github.com/cebe/php-openapi#readme", + "keywords": [ + "openapi" + ], + "support": { + "issues": "https://github.com/cebe/php-openapi/issues", + "source": "https://github.com/cebe/php-openapi" + }, + "time": "2022-04-20T14:46:44+00:00" + }, { "name": "composer/pcre", - "version": "1.0.0", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2" + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/3d322d715c43a1ac36c7fe215fa59336265500f2", - "reference": "3d322d715c43a1ac36c7fe215fa59336265500f2", + "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1", + "phpstan/phpstan": "^1.3", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5" + "symfony/phpunit-bridge": "^5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.x-dev" + "dev-main": "3.x-dev" } }, "autoload": { @@ -59,7 +128,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/1.0.0" + "source": "https://github.com/composer/pcre/tree/3.0.0" }, "funding": [ { @@ -75,27 +144,27 @@ "type": "tidelift" } ], - "time": "2021-12-06T15:17:27+00:00" + "time": "2022-02-25T20:21:48+00:00" }, { "name": "composer/semver", - "version": "3.2.6", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "83e511e247de329283478496f7a1e114c9517506" + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/83e511e247de329283478496f7a1e114c9517506", - "reference": "83e511e247de329283478496f7a1e114c9517506", + "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", + "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.54", + "phpstan/phpstan": "^1.4", "symfony/phpunit-bridge": "^4.2 || ^5" }, "type": "library", @@ -140,7 +209,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.2.6" + "source": "https://github.com/composer/semver/tree/3.3.2" }, "funding": [ { @@ -156,31 +225,31 @@ "type": "tidelift" } ], - "time": "2021-10-25T11:34:17+00:00" + "time": "2022-04-01T19:23:25+00:00" }, { "name": "composer/xdebug-handler", - "version": "2.0.3", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e" + "reference": "ced299686f41dce890debac69273b47ffe98a40c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6555461e76962fd0379c444c46fd558a0fcfb65e", - "reference": "6555461e76962fd0379c444c46fd558a0fcfb65e", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", + "reference": "ced299686f41dce890debac69273b47ffe98a40c", "shasum": "" }, "require": { - "composer/pcre": "^1", - "php": "^5.3.2 || ^7.0 || ^8.0", + "composer/pcre": "^1 || ^2 || ^3", + "php": "^7.2.5 || ^8.0", "psr/log": "^1 || ^2 || ^3" }, "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^4.2 || ^5.0 || ^6.0" + "symfony/phpunit-bridge": "^6.0" }, "type": "library", "autoload": { @@ -206,7 +275,7 @@ "support": { "irc": "irc://irc.freenode.org/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/2.0.3" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" }, "funding": [ { @@ -222,7 +291,7 @@ "type": "tidelift" } ], - "time": "2021-12-08T13:07:32+00:00" + "time": "2022-02-25T21:32:43+00:00" }, { "name": "doctrine/annotations", @@ -389,32 +458,28 @@ }, { "name": "doctrine/lexer", - "version": "1.2.1", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan": "^0.11.8", - "phpunit/phpunit": "^8.2" + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.11" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" @@ -449,7 +514,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.1" + "source": "https://github.com/doctrine/lexer/tree/1.2.3" }, "funding": [ { @@ -465,7 +530,7 @@ "type": "tidelift" } ], - "time": "2020-05-25T17:44:05+00:00" + "time": "2022-02-28T11:07:21+00:00" }, { "name": "easyrdf/easyrdf", @@ -544,52 +609,52 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.4.0", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad" + "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", - "reference": "47177af1cfb9dab5d1cc4daf91b7179c2efe7fad", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", "shasum": "" }, "require": { "composer/semver": "^3.2", - "composer/xdebug-handler": "^2.0", - "doctrine/annotations": "^1.12", + "composer/xdebug-handler": "^3.0.3", + "doctrine/annotations": "^1.13", "ext-json": "*", "ext-tokenizer": "*", - "php": "^7.2.5 || ^8.0", + "php": "^7.4 || ^8.0", "php-cs-fixer/diff": "^2.0", - "symfony/console": "^4.4.20 || ^5.1.3 || ^6.0", - "symfony/event-dispatcher": "^4.4.20 || ^5.0 || ^6.0", - "symfony/filesystem": "^4.4.20 || ^5.0 || ^6.0", - "symfony/finder": "^4.4.20 || ^5.0 || ^6.0", - "symfony/options-resolver": "^4.4.20 || ^5.0 || ^6.0", + "symfony/console": "^5.4 || ^6.0", + "symfony/event-dispatcher": "^5.4 || ^6.0", + "symfony/filesystem": "^5.4 || ^6.0", + "symfony/finder": "^5.4 || ^6.0", + "symfony/options-resolver": "^5.4 || ^6.0", "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.23", - "symfony/polyfill-php81": "^1.23", - "symfony/process": "^4.4.20 || ^5.0 || ^6.0", - "symfony/stopwatch": "^4.4.20 || ^5.0 || ^6.0" + "symfony/polyfill-php80": "^1.25", + "symfony/polyfill-php81": "^1.25", + "symfony/process": "^5.4 || ^6.0", + "symfony/stopwatch": "^5.4 || ^6.0" }, "require-dev": { "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^1.5", - "mikey179/vfsstream": "^1.6.8", + "mikey179/vfsstream": "^1.6.10", "php-coveralls/php-coveralls": "^2.5.2", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", "phpspec/prophecy": "^1.15", - "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^8.5.21 || ^9.5", + "phpspec/prophecy-phpunit": "^2.0", + "phpunit/phpunit": "^9.5", "phpunitgoodpractices/polyfill": "^1.5", "phpunitgoodpractices/traits": "^1.9.1", - "symfony/phpunit-bridge": "^5.2.4 || ^6.0", - "symfony/yaml": "^4.4.20 || ^5.0 || ^6.0" + "symfony/phpunit-bridge": "^6.0", + "symfony/yaml": "^5.4 || ^6.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -621,7 +686,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.4.0" + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0" }, "funding": [ { @@ -629,20 +694,90 @@ "type": "github" } ], - "time": "2021-12-11T16:25:08+00:00" + "time": "2022-03-18T17:20:59+00:00" + }, + { + "name": "justinrainbow/json-schema", + "version": "5.2.12", + "source": { + "type": "git", + "url": "https://github.com/justinrainbow/json-schema.git", + "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "json-schema/json-schema-test-suite": "1.2.0", + "phpunit/phpunit": "^4.8.35" + }, + "bin": [ + "bin/validate-json" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "JsonSchema\\": "src/JsonSchema/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bruno Prieto Reis", + "email": "bruno.p.reis@gmail.com" + }, + { + "name": "Justin Rainbow", + "email": "justin.rainbow@gmail.com" + }, + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + }, + { + "name": "Robert Schönthal", + "email": "seroscho@googlemail.com" + } + ], + "description": "A library to validate a json schema.", + "homepage": "https://github.com/justinrainbow/json-schema", + "keywords": [ + "json", + "schema" + ], + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" + }, + "time": "2022-04-13T08:02:27+00:00" }, { "name": "league/html-to-markdown", - "version": "5.0.2", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "4d0394e120dc14b0d5c52fd1755fd48656da2ec9" + "reference": "e0fc8cf07bdabbcd3765341ecb50c34c271d64e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/4d0394e120dc14b0d5c52fd1755fd48656da2ec9", - "reference": "4d0394e120dc14b0d5c52fd1755fd48656da2ec9", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/e0fc8cf07bdabbcd3765341ecb50c34c271d64e1", + "reference": "e0fc8cf07bdabbcd3765341ecb50c34c271d64e1", "shasum": "" }, "require": { @@ -652,11 +787,11 @@ }, "require-dev": { "mikehaertl/php-shellcommand": "^1.1.0", - "phpstan/phpstan": "^0.12.82", + "phpstan/phpstan": "^0.12.99", "phpunit/phpunit": "^8.5 || ^9.2", "scrutinizer/ocular": "^1.6", "unleashedtech/php-coding-standard": "^2.7", - "vimeo/psalm": "^4.6" + "vimeo/psalm": "^4.22" }, "bin": [ "bin/html-to-markdown" @@ -664,7 +799,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-master": "5.2-dev" } }, "autoload": { @@ -698,7 +833,7 @@ ], "support": { "issues": "https://github.com/thephpleague/html-to-markdown/issues", - "source": "https://github.com/thephpleague/html-to-markdown/tree/5.0.2" + "source": "https://github.com/thephpleague/html-to-markdown/tree/5.1.0" }, "funding": [ { @@ -718,7 +853,7 @@ "type": "tidelift" } ], - "time": "2021-11-06T05:38:26+00:00" + "time": "2022-03-02T17:24:08+00:00" }, { "name": "nette/php-generator", @@ -726,16 +861,16 @@ "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "26e35e848779f5900b2352c1791027d0f1d2f9d4" + "reference": "a88a6c560b9d7e6f2f234444dd7f0e8feacfe300" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/26e35e848779f5900b2352c1791027d0f1d2f9d4", - "reference": "26e35e848779f5900b2352c1791027d0f1d2f9d4", + "url": "https://api.github.com/repos/nette/php-generator/zipball/a88a6c560b9d7e6f2f234444dd7f0e8feacfe300", + "reference": "a88a6c560b9d7e6f2f234444dd7f0e8feacfe300", "shasum": "" }, "require": { - "nette/utils": "^4.0", + "nette/utils": "^3.2.7 || ^4.0", "php": ">=8.0 <8.2" }, "require-dev": { @@ -787,7 +922,7 @@ "issues": "https://github.com/nette/php-generator/issues", "source": "https://github.com/nette/php-generator/tree/master" }, - "time": "2021-12-12T17:19:35+00:00" + "time": "2022-05-23T19:11:20+00:00" }, { "name": "nette/utils", @@ -795,12 +930,12 @@ "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "f9483d3fa79168ec10e2f5fc78d49f3f404c4eb7" + "reference": "fb7403eecc701e1932d6e9b213342c5957cf4e3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/f9483d3fa79168ec10e2f5fc78d49f3f404c4eb7", - "reference": "f9483d3fa79168ec10e2f5fc78d49f3f404c4eb7", + "url": "https://api.github.com/repos/nette/utils/zipball/fb7403eecc701e1932d6e9b213342c5957cf4e3f", + "reference": "fb7403eecc701e1932d6e9b213342c5957cf4e3f", "shasum": "" }, "require": { @@ -873,20 +1008,20 @@ "issues": "https://github.com/nette/utils/issues", "source": "https://github.com/nette/utils/tree/master" }, - "time": "2021-12-12T17:35:24+00:00" + "time": "2022-06-02T11:43:37+00:00" }, { "name": "nikic/php-parser", - "version": "v4.13.2", + "version": "v4.14.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077" + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", - "reference": "210577fe3cf7badcc5814d99455df46564f3c077", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", + "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", "shasum": "" }, "require": { @@ -927,9 +1062,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" }, - "time": "2021-11-30T19:35:32+00:00" + "time": "2022-05-31T20:59:12+00:00" }, { "name": "php-cs-fixer/diff", @@ -1187,16 +1322,16 @@ }, { "name": "symfony/config", - "version": "v6.0.0", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "df4871981fd37f953c117b55feac03462be5a2d6" + "reference": "9c40f44bc38d91aeefbcdd1d42609033984ce062" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/df4871981fd37f953c117b55feac03462be5a2d6", - "reference": "df4871981fd37f953c117b55feac03462be5a2d6", + "url": "https://api.github.com/repos/symfony/config/zipball/9c40f44bc38d91aeefbcdd1d42609033984ce062", + "reference": "9c40f44bc38d91aeefbcdd1d42609033984ce062", "shasum": "" }, "require": { @@ -1245,7 +1380,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v6.0.0" + "source": "https://github.com/symfony/config/tree/v6.0.9" }, "funding": [ { @@ -1261,20 +1396,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T19:05:29+00:00" + "time": "2022-05-17T12:08:13+00:00" }, { "name": "symfony/console", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "fafd9802d386bf1c267e0249ddb7ceb14dcfdad4" + "reference": "9b190bc7a19d19add1dbb3382721973836e59b50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/fafd9802d386bf1c267e0249ddb7ceb14dcfdad4", - "reference": "fafd9802d386bf1c267e0249ddb7ceb14dcfdad4", + "url": "https://api.github.com/repos/symfony/console/zipball/9b190bc7a19d19add1dbb3382721973836e59b50", + "reference": "9b190bc7a19d19add1dbb3382721973836e59b50", "shasum": "" }, "require": { @@ -1340,7 +1475,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.1" + "source": "https://github.com/symfony/console/tree/v6.0.9" }, "funding": [ { @@ -1356,20 +1491,20 @@ "type": "tidelift" } ], - "time": "2021-12-09T12:47:37+00:00" + "time": "2022-05-27T06:40:13+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", - "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", "shasum": "" }, "require": { @@ -1407,7 +1542,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" }, "funding": [ { @@ -1423,20 +1558,20 @@ "type": "tidelift" } ], - "time": "2021-11-01T23:48:49+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "4f06d19a5f78087061f9de6df3269c139c3d289d" + "reference": "5c85b58422865d42c6eb46f7693339056db098a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/4f06d19a5f78087061f9de6df3269c139c3d289d", - "reference": "4f06d19a5f78087061f9de6df3269c139c3d289d", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/5c85b58422865d42c6eb46f7693339056db098a8", + "reference": "5c85b58422865d42c6eb46f7693339056db098a8", "shasum": "" }, "require": { @@ -1490,7 +1625,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.1" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.9" }, "funding": [ { @@ -1506,20 +1641,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-05-05T16:45:52+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "aa5422287b75594b90ee9cd807caf8f0df491385" + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/aa5422287b75594b90ee9cd807caf8f0df491385", - "reference": "aa5422287b75594b90ee9cd807caf8f0df491385", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", + "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", "shasum": "" }, "require": { @@ -1569,7 +1704,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" }, "funding": [ { @@ -1585,20 +1720,20 @@ "type": "tidelift" } ], - "time": "2021-07-15T12:33:35+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/filesystem", - "version": "v6.0.0", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "52b3c9cce673b014915445a432339f282e002ce6" + "reference": "bf7b9d2ee692b6df2a41017d6023a2fe732d240c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/52b3c9cce673b014915445a432339f282e002ce6", - "reference": "52b3c9cce673b014915445a432339f282e002ce6", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/bf7b9d2ee692b6df2a41017d6023a2fe732d240c", + "reference": "bf7b9d2ee692b6df2a41017d6023a2fe732d240c", "shasum": "" }, "require": { @@ -1632,7 +1767,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.0" + "source": "https://github.com/symfony/filesystem/tree/v6.0.9" }, "funding": [ { @@ -1648,20 +1783,20 @@ "type": "tidelift" } ], - "time": "2021-10-29T07:35:21+00:00" + "time": "2022-05-21T13:33:31+00:00" }, { "name": "symfony/finder", - "version": "v6.0.0", + "version": "v6.0.8", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "07debda41a4d32d33e59e6ab302af1701e15f173" + "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/07debda41a4d32d33e59e6ab302af1701e15f173", - "reference": "07debda41a4d32d33e59e6ab302af1701e15f173", + "url": "https://api.github.com/repos/symfony/finder/zipball/af7edab28d17caecd1f40a9219fc646ae751c21f", + "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f", "shasum": "" }, "require": { @@ -1693,7 +1828,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.0" + "source": "https://github.com/symfony/finder/tree/v6.0.8" }, "funding": [ { @@ -1709,20 +1844,20 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:34:37+00:00" + "time": "2022-04-15T08:07:58+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.0.0", + "version": "v6.0.3", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "be0facf48a42a232d6c0daadd76e4eb5657a4798" + "reference": "51f7006670febe4cbcbae177cbffe93ff833250d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/be0facf48a42a232d6c0daadd76e4eb5657a4798", - "reference": "be0facf48a42a232d6c0daadd76e4eb5657a4798", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/51f7006670febe4cbcbae177cbffe93ff833250d", + "reference": "51f7006670febe4cbcbae177cbffe93ff833250d", "shasum": "" }, "require": { @@ -1760,7 +1895,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.0.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.0.3" }, "funding": [ { @@ -1776,32 +1911,35 @@ "type": "tidelift" } ], - "time": "2021-11-23T19:05:29+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-ctype": "*" + }, "suggest": { "ext-ctype": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1809,12 +1947,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1839,7 +1977,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" }, "funding": [ { @@ -1855,20 +1993,20 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" + "reference": "433d05519ce6990bf3530fba6957499d327395c2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", - "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", + "reference": "433d05519ce6990bf3530fba6957499d327395c2", "shasum": "" }, "require": { @@ -1880,7 +2018,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1888,12 +2026,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Grapheme\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1920,7 +2058,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" }, "funding": [ { @@ -1936,20 +2074,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" + "reference": "219aa369ceff116e673852dce47c3a41794c14bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", - "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", + "reference": "219aa369ceff116e673852dce47c3a41794c14bd", "shasum": "" }, "require": { @@ -1961,7 +2099,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1969,12 +2107,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Intl\\Normalizer\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2004,7 +2142,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" }, "funding": [ { @@ -2020,32 +2158,35 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", - "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-mbstring": "*" + }, "suggest": { "ext-mbstring": "For best performance" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2053,12 +2194,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2084,7 +2225,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" }, "funding": [ { @@ -2100,20 +2241,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T12:26:48+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.23.1", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", - "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", "shasum": "" }, "require": { @@ -2122,7 +2263,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2130,12 +2271,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2167,7 +2308,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" }, "funding": [ { @@ -2183,20 +2324,20 @@ "type": "tidelift" } ], - "time": "2021-07-28T13:41:28+00:00" + "time": "2022-05-10T07:21:04+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "e66119f3de95efc359483f810c4c3e6436279436" + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/e66119f3de95efc359483f810c4c3e6436279436", - "reference": "e66119f3de95efc359483f810c4c3e6436279436", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", "shasum": "" }, "require": { @@ -2205,7 +2346,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2213,12 +2354,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php81\\": "" - }, "files": [ "bootstrap.php" ], + "psr-4": { + "Symfony\\Polyfill\\Php81\\": "" + }, "classmap": [ "Resources/stubs" ] @@ -2246,7 +2387,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" }, "funding": [ { @@ -2262,20 +2403,20 @@ "type": "tidelift" } ], - "time": "2021-05-21T13:25:03+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/process", - "version": "v6.0.0", + "version": "v6.0.8", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d970c45c2186aa4331d1656950a82df64e232580" + "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d970c45c2186aa4331d1656950a82df64e232580", - "reference": "d970c45c2186aa4331d1656950a82df64e232580", + "url": "https://api.github.com/repos/symfony/process/zipball/d074154ea8b1443a96391f6e39f9e547b2dd01b9", + "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9", "shasum": "" }, "require": { @@ -2307,7 +2448,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v6.0.0" + "source": "https://github.com/symfony/process/tree/v6.0.8" }, "funding": [ { @@ -2323,20 +2464,20 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:34:37+00:00" + "time": "2022-04-12T16:11:42+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", - "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", + "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", "shasum": "" }, "require": { @@ -2389,7 +2530,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" }, "funding": [ { @@ -2405,20 +2546,20 @@ "type": "tidelift" } ], - "time": "2021-11-04T17:53:12+00:00" + "time": "2022-03-13T20:10:05+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.0.0", + "version": "v6.0.5", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "0e0ed55d1ffdfadd03af180443fbdca9876483b3" + "reference": "f2c1780607ec6502f2121d9729fd8150a655d337" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/0e0ed55d1ffdfadd03af180443fbdca9876483b3", - "reference": "0e0ed55d1ffdfadd03af180443fbdca9876483b3", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f2c1780607ec6502f2121d9729fd8150a655d337", + "reference": "f2c1780607ec6502f2121d9729fd8150a655d337", "shasum": "" }, "require": { @@ -2451,7 +2592,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.0.0" + "source": "https://github.com/symfony/stopwatch/tree/v6.0.5" }, "funding": [ { @@ -2467,20 +2608,20 @@ "type": "tidelift" } ], - "time": "2021-11-23T19:05:29+00:00" + "time": "2022-02-21T17:15:17+00:00" }, { "name": "symfony/string", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32" + "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/0cfed595758ec6e0a25591bdc8ca733c1896af32", - "reference": "0cfed595758ec6e0a25591bdc8ca733c1896af32", + "url": "https://api.github.com/repos/symfony/string/zipball/df9f03d595aa2d446498ba92fe803a519b2c43cc", + "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc", "shasum": "" }, "require": { @@ -2501,12 +2642,12 @@ }, "type": "library", "autoload": { - "psr-4": { - "Symfony\\Component\\String\\": "" - }, "files": [ "Resources/functions.php" ], + "psr-4": { + "Symfony\\Component\\String\\": "" + }, "exclude-from-classmap": [ "/Tests/" ] @@ -2536,7 +2677,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.1" + "source": "https://github.com/symfony/string/tree/v6.0.9" }, "funding": [ { @@ -2552,20 +2693,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-04-22T08:18:02+00:00" }, { "name": "symfony/yaml", - "version": "v6.0.1", + "version": "v6.0.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "d34390fe7e8c0fe7e4192c67c27ecf58bc7d3ed7" + "reference": "e77f3ea0b21141d771d4a5655faa54f692b34af5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/d34390fe7e8c0fe7e4192c67c27ecf58bc7d3ed7", - "reference": "d34390fe7e8c0fe7e4192c67c27ecf58bc7d3ed7", + "url": "https://api.github.com/repos/symfony/yaml/zipball/e77f3ea0b21141d771d4a5655faa54f692b34af5", + "reference": "e77f3ea0b21141d771d4a5655faa54f692b34af5", "shasum": "" }, "require": { @@ -2610,7 +2751,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.0.1" + "source": "https://github.com/symfony/yaml/tree/v6.0.3" }, "funding": [ { @@ -2626,20 +2767,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-01-26T17:23:29+00:00" }, { "name": "twig/twig", - "version": "v3.3.4", + "version": "v3.4.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "65cb6f0b956485e1664f13d023c55298a4bb59ca" + "reference": "e939eae92386b69b49cfa4599dd9bead6bf4a342" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/65cb6f0b956485e1664f13d023c55298a4bb59ca", - "reference": "65cb6f0b956485e1664f13d023c55298a4bb59ca", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/e939eae92386b69b49cfa4599dd9bead6bf4a342", + "reference": "e939eae92386b69b49cfa4599dd9bead6bf4a342", "shasum": "" }, "require": { @@ -2654,7 +2795,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.3-dev" + "dev-master": "3.4-dev" } }, "autoload": { @@ -2690,7 +2831,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.3.4" + "source": "https://github.com/twigphp/Twig/tree/v3.4.1" }, "funding": [ { @@ -2702,22 +2843,22 @@ "type": "tidelift" } ], - "time": "2021-11-25T13:46:55+00:00" + "time": "2022-05-17T05:48:52+00:00" } ], "packages-dev": [ { "name": "api-platform/core", - "version": "v2.6.7", + "version": "v2.6.8", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "8a19950a816ccd7cbf38323addbba72b14ac2372" + "reference": "ff3aab5b196709c721960c0bb4f1d52759af737d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/8a19950a816ccd7cbf38323addbba72b14ac2372", - "reference": "8a19950a816ccd7cbf38323addbba72b14ac2372", + "url": "https://api.github.com/repos/api-platform/core/zipball/ff3aab5b196709c721960c0bb4f1d52759af737d", + "reference": "ff3aab5b196709c721960c0bb4f1d52759af737d", "shasum": "" }, "require": { @@ -2857,7 +2998,7 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v2.6.7" + "source": "https://github.com/api-platform/core/tree/v2.6.8" }, "funding": [ { @@ -2865,93 +3006,20 @@ "type": "tidelift" } ], - "time": "2021-12-24T14:12:38+00:00" - }, - { - "name": "composer/package-versions-deprecated", - "version": "1.11.99.4", - "source": { - "type": "git", - "url": "https://github.com/composer/package-versions-deprecated.git", - "reference": "b174585d1fe49ceed21928a945138948cb394600" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/package-versions-deprecated/zipball/b174585d1fe49ceed21928a945138948cb394600", - "reference": "b174585d1fe49ceed21928a945138948cb394600", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.1.0 || ^2.0", - "php": "^7 || ^8" - }, - "replace": { - "ocramius/package-versions": "1.11.99" - }, - "require-dev": { - "composer/composer": "^1.9.3 || ^2.0@dev", - "ext-zip": "^1.13", - "phpunit/phpunit": "^6.5 || ^7" - }, - "type": "composer-plugin", - "extra": { - "class": "PackageVersions\\Installer", - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "PackageVersions\\": "src/PackageVersions" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be" - } - ], - "description": "Composer plugin that provides efficient querying for installed package versions (no runtime IO)", - "support": { - "issues": "https://github.com/composer/package-versions-deprecated/issues", - "source": "https://github.com/composer/package-versions-deprecated/tree/1.11.99.4" - }, - "funding": [ - { - "url": "https://packagist.com/", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2021-09-13T08:41:34+00:00" + "time": "2022-01-11T10:29:54+00:00" }, { "name": "doctrine/cache", - "version": "2.1.1", + "version": "2.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/cache.git", - "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce" + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/331b4d5dbaeab3827976273e9356b3b453c300ce", - "reference": "331b4d5dbaeab3827976273e9356b3b453c300ce", + "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", + "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", "shasum": "" }, "require": { @@ -2961,18 +3029,12 @@ "doctrine/common": ">2.2,<2.4" }, "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^8.0", - "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "predis/predis": "~1.0", + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.2 || ^6.0@dev", - "symfony/var-exporter": "^4.4 || ^5.2 || ^6.0@dev" - }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" + "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6" }, "type": "library", "autoload": { @@ -3021,7 +3083,7 @@ ], "support": { "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.1.1" + "source": "https://github.com/doctrine/cache/tree/2.2.0" }, "funding": [ { @@ -3037,7 +3099,7 @@ "type": "tidelift" } ], - "time": "2021-07-17T14:49:29+00:00" + "time": "2022-05-20T20:07:39+00:00" }, { "name": "doctrine/collections", @@ -3110,26 +3172,26 @@ }, { "name": "doctrine/common", - "version": "3.2.0", + "version": "3.3.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "6d970a11479275300b5144e9373ce5feacfa9b91" + "reference": "c824e95d4c83b7102d8bc60595445a6f7d540f96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/6d970a11479275300b5144e9373ce5feacfa9b91", - "reference": "6d970a11479275300b5144e9373ce5feacfa9b91", + "url": "https://api.github.com/repos/doctrine/common/zipball/c824e95d4c83b7102d8bc60595445a6f7d540f96", + "reference": "c824e95d4c83b7102d8bc60595445a6f7d540f96", "shasum": "" }, "require": { - "doctrine/persistence": "^2.0", + "doctrine/persistence": "^2.0 || ^3.0", "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0 || ^8.0", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", + "doctrine/coding-standard": "^9.0", + "phpstan/phpstan": "^1.4.1", + "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.0", "symfony/phpunit-bridge": "^4.0.5", @@ -3180,7 +3242,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.2.0" + "source": "https://github.com/doctrine/common/tree/3.3.0" }, "funding": [ { @@ -3196,26 +3258,26 @@ "type": "tidelift" } ], - "time": "2021-10-19T06:47:22+00:00" + "time": "2022-02-05T18:28:51+00:00" }, { "name": "doctrine/dbal", - "version": "3.2.0", + "version": "3.3.6", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "5d54f63541d7bed1156cb5c9b79274ced61890e4" + "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/5d54f63541d7bed1156cb5c9b79274ced61890e4", - "reference": "5d54f63541d7bed1156cb5c9b79274ced61890e4", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/9e7f76dd1cde81c62574fdffa5a9c655c847ad21", + "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21", "shasum": "" }, "require": { - "composer/package-versions-deprecated": "^1.11.99", + "composer-runtime-api": "^2", "doctrine/cache": "^1.11|^2.0", - "doctrine/deprecations": "^0.5.3", + "doctrine/deprecations": "^0.5.3|^1", "doctrine/event-manager": "^1.0", "php": "^7.3 || ^8.0", "psr/cache": "^1|^2|^3", @@ -3223,15 +3285,15 @@ }, "require-dev": { "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2021.1", - "phpstan/phpstan": "1.2.0", - "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "9.5.10", + "jetbrains/phpstorm-stubs": "2022.1", + "phpstan/phpstan": "1.6.3", + "phpstan/phpstan-strict-rules": "^1.2", + "phpunit/phpunit": "9.5.20", "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.6.1", + "squizlabs/php_codesniffer": "3.6.2", "symfony/cache": "^5.2|^6.0", - "symfony/console": "^2.0.5|^3.0|^4.0|^5.0|^6.0", - "vimeo/psalm": "4.13.0" + "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0", + "vimeo/psalm": "4.23.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -3291,7 +3353,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.2.0" + "source": "https://github.com/doctrine/dbal/tree/3.3.6" }, "funding": [ { @@ -3307,29 +3369,29 @@ "type": "tidelift" } ], - "time": "2021-11-26T21:00:12+00:00" + "time": "2022-05-02T17:21:01+00:00" }, { "name": "doctrine/deprecations", - "version": "v0.5.3", + "version": "v1.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "9504165960a1f83cc1480e2be1dd0a0478561314" + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/9504165960a1f83cc1480e2be1dd0a0478561314", - "reference": "9504165960a1f83cc1480e2be1dd0a0478561314", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", "shasum": "" }, "require": { "php": "^7.1|^8.0" }, "require-dev": { - "doctrine/coding-standard": "^6.0|^7.0|^8.0", - "phpunit/phpunit": "^7.0|^8.0|^9.0", - "psr/log": "^1.0" + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -3348,9 +3410,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v0.5.3" + "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" }, - "time": "2021-03-21T12:59:47+00:00" + "time": "2022-05-02T15:47:09+00:00" }, { "name": "doctrine/event-manager", @@ -3448,29 +3510,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.4.0", + "version": "1.4.1", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b" + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/d56bf6102915de5702778fe20f2de3b2fe570b5b", - "reference": "d56bf6102915de5702778fe20f2de3b2fe570b5b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", + "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.0", + "doctrine/coding-standard": "^9", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.13 || 1.0.0-alpha2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -3497,7 +3560,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + "source": "https://github.com/doctrine/instantiator/tree/1.4.1" }, "funding": [ { @@ -3513,41 +3576,40 @@ "type": "tidelift" } ], - "time": "2020-11-10T18:47:58+00:00" + "time": "2022-03-03T08:28:38+00:00" }, { "name": "doctrine/orm", - "version": "2.10.4", + "version": "2.12.2", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "cccb2e2fdfed2969afb3d65c5ea82bafdefbe1a7" + "reference": "8291a7f09b12d14783ed6537b4586583d155869e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/cccb2e2fdfed2969afb3d65c5ea82bafdefbe1a7", - "reference": "cccb2e2fdfed2969afb3d65c5ea82bafdefbe1a7", + "url": "https://api.github.com/repos/doctrine/orm/zipball/8291a7f09b12d14783ed6537b4586583d155869e", + "reference": "8291a7f09b12d14783ed6537b4586583d155869e", "shasum": "" }, "require": { - "composer/package-versions-deprecated": "^1.8", + "composer-runtime-api": "^2", "doctrine/cache": "^1.12.1 || ^2.1.1", "doctrine/collections": "^1.5", "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1 || ^3.1.1", - "doctrine/deprecations": "^0.5.3", + "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.1", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3", - "doctrine/lexer": "^1.0", - "doctrine/persistence": "^2.2", + "doctrine/lexer": "^1.2.3", + "doctrine/persistence": "^2.4 || ^3", "ext-ctype": "*", - "ext-pdo": "*", - "php": "^7.1 ||^8.0", + "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3", "symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0", "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.15" + "symfony/polyfill-php80": "^1.16" }, "conflict": { "doctrine/annotations": "<1.13 || >= 2.0" @@ -3556,12 +3618,13 @@ "doctrine/annotations": "^1.13", "doctrine/coding-standard": "^9.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "1.2.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.4", + "phpstan/phpstan": "~1.4.10 || 1.6.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.6.2", - "symfony/cache": "^4.4 || ^5.2", + "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.15.0" + "vimeo/psalm": "4.23.0" }, "suggest": { "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", @@ -3610,50 +3673,50 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.10.4" + "source": "https://github.com/doctrine/orm/tree/2.12.2" }, - "time": "2021-12-20T21:23:47+00:00" + "time": "2022-05-02T19:10:07+00:00" }, { "name": "doctrine/persistence", - "version": "2.2.3", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "5e7bdbbfe9811c06e1f745d1c166647d5c47d6ee" + "reference": "25ec98a8cbd1f850e60fdb62c0ef77c162da8704" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/5e7bdbbfe9811c06e1f745d1c166647d5c47d6ee", - "reference": "5e7bdbbfe9811c06e1f745d1c166647d5c47d6ee", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/25ec98a8cbd1f850e60fdb62c0ef77c162da8704", + "reference": "25ec98a8cbd1f850e60fdb62c0ef77c162da8704", "shasum": "" }, "require": { - "doctrine/annotations": "^1.0", - "doctrine/cache": "^1.11 || ^2.0", "doctrine/collections": "^1.0", - "doctrine/deprecations": "^0.5.3", "doctrine/event-manager": "^1.0", - "php": "^7.1 || ^8.0", - "psr/cache": "^1.0|^2.0|^3.0" + "php": "^7.2 || ^8.0", + "psr/cache": "^1.0 || ^2.0 || ^3.0" }, "conflict": { - "doctrine/common": "<2.10@dev" + "doctrine/annotations": "<1.7 || >=2.0", + "doctrine/common": "<2.10" }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "doctrine/coding-standard": "^6.0 || ^9.0", + "doctrine/annotations": "^1.7", + "doctrine/coding-standard": "^9.0", "doctrine/common": "^3.0", - "phpstan/phpstan": "0.12.84", - "phpunit/phpunit": "^7.5.20 || ^8.0 || ^9.0", - "symfony/cache": "^4.4|^5.0", - "vimeo/psalm": "4.7.0" + "phpstan/phpstan": "1.5.0", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "phpunit/phpunit": "^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6.0", + "vimeo/psalm": "4.22.0" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common", - "Doctrine\\Persistence\\": "lib/Doctrine/Persistence" + "Doctrine\\Persistence\\": "src/Persistence" } }, "notification-url": "https://packagist.org/downloads/", @@ -3687,7 +3750,7 @@ } ], "description": "The Doctrine Persistence project is a set of shared interfaces and functionality that the different Doctrine object mappers share.", - "homepage": "https://doctrine-project.org/projects/persistence.html", + "homepage": "https://www.doctrine-project.org/projects/persistence.html", "keywords": [ "mapper", "object", @@ -3697,9 +3760,23 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/2.2.3" + "source": "https://github.com/doctrine/persistence/tree/3.0.2" }, - "time": "2021-10-25T19:59:10+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fpersistence", + "type": "tidelift" + } + ], + "time": "2022-05-06T06:10:05+00:00" }, { "name": "fig/link-util", @@ -3764,34 +3841,38 @@ }, { "name": "myclabs/deep-copy", - "version": "1.10.2", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220" + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/776f831124e9c62e1a2c601ecc52e776d8bb7220", - "reference": "776f831124e9c62e1a2c601ecc52e776d8bb7220", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", + "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" + }, "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3807,7 +3888,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" }, "funding": [ { @@ -3815,7 +3896,7 @@ "type": "tidelift" } ], - "time": "2020-11-13T09:40:50+00:00" + "time": "2022-03-03T13:19:32+00:00" }, { "name": "myclabs/php-enum", @@ -3939,16 +4020,16 @@ }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { @@ -3984,9 +4065,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -4100,16 +4181,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "reference": "77a32518733312af16a44300404e945338981de3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", + "reference": "77a32518733312af16a44300404e945338981de3", "shasum": "" }, "require": { @@ -4144,9 +4225,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" }, - "time": "2021-10-02T14:08:47+00:00" + "time": "2022-03-15T21:29:03+00:00" }, { "name": "phpspec/prophecy", @@ -4269,20 +4350,20 @@ }, { "name": "phpstan/phpstan", - "version": "1.2.0", + "version": "1.7.11", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee" + "reference": "62fcadcde81b4037e42ad2489119d31c46f00191" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", - "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/62fcadcde81b4037e42ad2489119d31c46f00191", + "reference": "62fcadcde81b4037e42ad2489119d31c46f00191", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.2|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -4292,11 +4373,6 @@ "phpstan.phar" ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2-dev" - } - }, "autoload": { "files": [ "bootstrap.php" @@ -4309,7 +4385,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.2.0" + "source": "https://github.com/phpstan/phpstan/tree/1.7.11" }, "funding": [ { @@ -4329,20 +4405,20 @@ "type": "tidelift" } ], - "time": "2021-11-18T14:09:01+00:00" + "time": "2022-06-07T08:47:03+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.10", + "version": "9.2.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", - "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", "shasum": "" }, "require": { @@ -4398,7 +4474,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" }, "funding": [ { @@ -4406,7 +4482,7 @@ "type": "github" } ], - "time": "2021-12-05T09:12:13+00:00" + "time": "2022-03-07T09:28:20+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4651,16 +4727,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.10", + "version": "9.5.20", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", + "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", "shasum": "" }, "require": { @@ -4676,7 +4752,7 @@ "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.7", + "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -4690,7 +4766,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3.4", + "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, "require-dev": { @@ -4711,11 +4787,11 @@ } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -4738,11 +4814,11 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { @@ -4750,7 +4826,7 @@ "type": "github" } ], - "time": "2021-09-25T07:38:51+00:00" + "time": "2022-04-01T12:37:26+00:00" }, { "name": "psr/link", @@ -5174,16 +5250,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.3", + "version": "5.1.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac" + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/388b6ced16caa751030f6a69e588299fa09200ac", - "reference": "388b6ced16caa751030f6a69e588299fa09200ac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", "shasum": "" }, "require": { @@ -5225,7 +5301,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" }, "funding": [ { @@ -5233,7 +5309,7 @@ "type": "github" } ], - "time": "2020-09-28T05:52:38+00:00" + "time": "2022-04-03T09:37:03+00:00" }, { "name": "sebastian/exporter", @@ -5314,16 +5390,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { @@ -5366,7 +5442,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" }, "funding": [ { @@ -5374,7 +5450,7 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2022-02-14T08:28:10+00:00" }, { "name": "sebastian/lines-of-code", @@ -5665,28 +5741,28 @@ }, { "name": "sebastian/type", - "version": "2.3.4", + "version": "3.0.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", - "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", "shasum": "" }, "require": { "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^9.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.3-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -5709,7 +5785,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" }, "funding": [ { @@ -5717,7 +5793,7 @@ "type": "github" } ], - "time": "2021-06-15T12:49:02+00:00" + "time": "2022-03-15T09:54:48+00:00" }, { "name": "sebastian/version", @@ -5774,21 +5850,21 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "d5b0bef7fc93f60a5a5acafffea4f651ffa01ce5" + "reference": "34599e7deb63ec68ad72e206c2401a5448249783" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/d5b0bef7fc93f60a5a5acafffea4f651ffa01ce5", - "reference": "d5b0bef7fc93f60a5a5acafffea4f651ffa01ce5", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/34599e7deb63ec68ad72e206c2401a5448249783", + "reference": "34599e7deb63ec68ad72e206c2401a5448249783", "shasum": "" }, "require": { "doctrine/event-manager": "~1.0", - "doctrine/persistence": "^2", + "doctrine/persistence": "^2|^3", "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", @@ -5798,7 +5874,7 @@ "conflict": { "doctrine/dbal": "<2.13.1", "doctrine/lexer": "<1.1", - "doctrine/orm": "<2.7.3", + "doctrine/orm": "<2.7.4", "phpunit/phpunit": "<5.4.3", "symfony/cache": "<5.4", "symfony/dependency-injection": "<5.4", @@ -5811,19 +5887,18 @@ "symfony/validator": "<5.4" }, "require-dev": { - "composer/package-versions-deprecated": "^1.8", "doctrine/annotations": "^1.10.4", "doctrine/collections": "~1.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", - "doctrine/orm": "^2.7.3", + "doctrine/orm": "^2.7.4", "psr/log": "^1|^2|^3", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/doctrine-messenger": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", + "symfony/form": "^5.4.9|^6.0.9", "symfony/http-kernel": "^5.4|^6.0", "symfony/messenger": "^5.4|^6.0", "symfony/property-access": "^5.4|^6.0", @@ -5870,7 +5945,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.0.1" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.0.9" }, "funding": [ { @@ -5886,20 +5961,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-05-27T06:30:15+00:00" }, { "name": "symfony/error-handler", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "944193d25c564c8c80411a5d02eb2be823d57d5c" + "reference": "732ca203b3222cde3378d5ddf5e2883211acc53e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/944193d25c564c8c80411a5d02eb2be823d57d5c", - "reference": "944193d25c564c8c80411a5d02eb2be823d57d5c", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/732ca203b3222cde3378d5ddf5e2883211acc53e", + "reference": "732ca203b3222cde3378d5ddf5e2883211acc53e", "shasum": "" }, "require": { @@ -5941,7 +6016,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.0.1" + "source": "https://github.com/symfony/error-handler/tree/v6.0.9" }, "funding": [ { @@ -5957,20 +6032,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-05-23T10:32:42+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "4c55dff16ba400dc81c56b6234e5942f9b9c7bcc" + "reference": "05abe9aab47decfd793632787d0c6a25268e2a5b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/4c55dff16ba400dc81c56b6234e5942f9b9c7bcc", - "reference": "4c55dff16ba400dc81c56b6234e5942f9b9c7bcc", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/05abe9aab47decfd793632787d0c6a25268e2a5b", + "reference": "05abe9aab47decfd793632787d0c6a25268e2a5b", "shasum": "" }, "require": { @@ -6013,7 +6088,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.0.1" + "source": "https://github.com/symfony/http-foundation/tree/v6.0.9" }, "funding": [ { @@ -6029,20 +6104,20 @@ "type": "tidelift" } ], - "time": "2021-12-09T12:47:37+00:00" + "time": "2022-05-21T13:33:31+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "cd7ed5337e67e1be91526184006fe7c1603283cb" + "reference": "e78407f2a7b683fd1269057aa39355d77ddbcff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/cd7ed5337e67e1be91526184006fe7c1603283cb", - "reference": "cd7ed5337e67e1be91526184006fe7c1603283cb", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e78407f2a7b683fd1269057aa39355d77ddbcff9", + "reference": "e78407f2a7b683fd1269057aa39355d77ddbcff9", "shasum": "" }, "require": { @@ -6122,7 +6197,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.0.1" + "source": "https://github.com/symfony/http-kernel/tree/v6.0.9" }, "funding": [ { @@ -6138,20 +6213,20 @@ "type": "tidelift" } ], - "time": "2021-12-09T13:42:47+00:00" + "time": "2022-05-27T07:14:30+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.0.0", + "version": "v6.1.0", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "5d6cc6720085084f504d2482fc4a2f268784006b" + "reference": "092ccc3b364925cd8ed6046bc31dcf3a022bd5a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/5d6cc6720085084f504d2482fc4a2f268784006b", - "reference": "5d6cc6720085084f504d2482fc4a2f268784006b", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/092ccc3b364925cd8ed6046bc31dcf3a022bd5a4", + "reference": "092ccc3b364925cd8ed6046bc31dcf3a022bd5a4", "shasum": "" }, "require": { @@ -6205,7 +6280,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.0.0" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.1.0" }, "funding": [ { @@ -6221,20 +6296,20 @@ "type": "tidelift" } ], - "time": "2021-11-29T15:32:57+00:00" + "time": "2022-04-12T16:22:53+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.23.0", + "version": "v1.26.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976" + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/9a142215a36a3888e30d0a9eeea9766764e96976", - "reference": "9a142215a36a3888e30d0a9eeea9766764e96976", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", + "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", "shasum": "" }, "require": { @@ -6243,7 +6318,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.23-dev" + "dev-main": "1.26-dev" }, "thanks": { "name": "symfony/polyfill", @@ -6251,12 +6326,12 @@ } }, "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, "files": [ "bootstrap.php" - ] + ], + "psr-4": { + "Symfony\\Polyfill\\Php72\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6281,7 +6356,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" }, "funding": [ { @@ -6297,20 +6372,20 @@ "type": "tidelift" } ], - "time": "2021-05-27T09:17:38+00:00" + "time": "2022-05-24T11:49:31+00:00" }, { "name": "symfony/property-access", - "version": "v6.0.0", + "version": "v6.0.8", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "e0b66975319b4648e0cbf267878b07d8e2d11e2e" + "reference": "e5ac708a97933e9680b81b92eb90a5e301490d72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/e0b66975319b4648e0cbf267878b07d8e2d11e2e", - "reference": "e0b66975319b4648e0cbf267878b07d8e2d11e2e", + "url": "https://api.github.com/repos/symfony/property-access/zipball/e5ac708a97933e9680b81b92eb90a5e301490d72", + "reference": "e5ac708a97933e9680b81b92eb90a5e301490d72", "shasum": "" }, "require": { @@ -6360,7 +6435,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.0.0" + "source": "https://github.com/symfony/property-access/tree/v6.0.8" }, "funding": [ { @@ -6376,20 +6451,20 @@ "type": "tidelift" } ], - "time": "2021-11-28T15:34:37+00:00" + "time": "2022-04-20T15:01:42+00:00" }, { "name": "symfony/property-info", - "version": "v6.0.0", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "56e98f48ee2dc89688d1870e66d834627a17db6d" + "reference": "f6ca518cee8cac7e1e1a3f922a5731ab866b9b0b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/56e98f48ee2dc89688d1870e66d834627a17db6d", - "reference": "56e98f48ee2dc89688d1870e66d834627a17db6d", + "url": "https://api.github.com/repos/symfony/property-info/zipball/f6ca518cee8cac7e1e1a3f922a5731ab866b9b0b", + "reference": "f6ca518cee8cac7e1e1a3f922a5731ab866b9b0b", "shasum": "" }, "require": { @@ -6449,7 +6524,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.0.0" + "source": "https://github.com/symfony/property-info/tree/v6.0.9" }, "funding": [ { @@ -6465,20 +6540,20 @@ "type": "tidelift" } ], - "time": "2021-11-04T18:05:01+00:00" + "time": "2022-05-17T09:49:29+00:00" }, { "name": "symfony/serializer", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "60637437ca5bfa519e4085e9ea28ead456f9d85e" + "reference": "cd209717fce097ed002a218cbd9be9d56ed53e78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/60637437ca5bfa519e4085e9ea28ead456f9d85e", - "reference": "60637437ca5bfa519e4085e9ea28ead456f9d85e", + "url": "https://api.github.com/repos/symfony/serializer/zipball/cd209717fce097ed002a218cbd9be9d56ed53e78", + "reference": "cd209717fce097ed002a218cbd9be9d56ed53e78", "shasum": "" }, "require": { @@ -6492,6 +6567,7 @@ "symfony/dependency-injection": "<5.4", "symfony/property-access": "<5.4", "symfony/property-info": "<5.4", + "symfony/uid": "<5.4", "symfony/yaml": "<5.4" }, "require-dev": { @@ -6549,7 +6625,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.0.1" + "source": "https://github.com/symfony/serializer/tree/v6.0.9" }, "funding": [ { @@ -6565,20 +6641,20 @@ "type": "tidelift" } ], - "time": "2021-12-01T16:45:37+00:00" + "time": "2022-05-10T09:19:38+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.0.0", + "version": "v3.0.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77" + "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", - "reference": "1b6ea5a7442af5a12dba3dbd6d71034b5b234e77", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", + "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", "shasum": "" }, "require": { @@ -6627,7 +6703,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.0.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1" }, "funding": [ { @@ -6643,26 +6719,27 @@ "type": "tidelift" } ], - "time": "2021-09-07T12:43:40+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "symfony/validator", - "version": "v6.0.1", + "version": "v6.0.8", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "981c9baef0f1052bc9a6cedb63da8608b71de348" + "reference": "d8f47eea936014e9e9d1cd3248f8c73d57dc248b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/981c9baef0f1052bc9a6cedb63da8608b71de348", - "reference": "981c9baef0f1052bc9a6cedb63da8608b71de348", + "url": "https://api.github.com/repos/symfony/validator/zipball/d8f47eea936014e9e9d1cd3248f8c73d57dc248b", + "reference": "d8f47eea936014e9e9d1cd3248f8c73d57dc248b", "shasum": "" }, "require": { "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php81": "^1.22", "symfony/translation-contracts": "^1.1|^2|^3" }, "conflict": { @@ -6734,7 +6811,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.0.1" + "source": "https://github.com/symfony/validator/tree/v6.0.8" }, "funding": [ { @@ -6750,20 +6827,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-04-15T08:07:58+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.0.1", + "version": "v6.0.9", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "9ca4948ec35bb15175e5475ba83dfdb13042a86c" + "reference": "ac81072464221e73ee994d12f0b8a2af4a9ed798" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/9ca4948ec35bb15175e5475ba83dfdb13042a86c", - "reference": "9ca4948ec35bb15175e5475ba83dfdb13042a86c", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ac81072464221e73ee994d12f0b8a2af4a9ed798", + "reference": "ac81072464221e73ee994d12f0b8a2af4a9ed798", "shasum": "" }, "require": { @@ -6822,7 +6899,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.0.1" + "source": "https://github.com/symfony/var-dumper/tree/v6.0.9" }, "funding": [ { @@ -6838,20 +6915,20 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-05-21T13:33:31+00:00" }, { "name": "symfony/web-link", - "version": "v6.0.1", + "version": "v6.0.3", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "bc5ac011d2670331b8d5fab89253c774568f6877" + "reference": "52d6af6c4476c8ebdef968cb39030826253eb5e4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/bc5ac011d2670331b8d5fab89253c774568f6877", - "reference": "bc5ac011d2670331b8d5fab89253c774568f6877", + "url": "https://api.github.com/repos/symfony/web-link/zipball/52d6af6c4476c8ebdef968cb39030826253eb5e4", + "reference": "52d6af6c4476c8ebdef968cb39030826253eb5e4", "shasum": "" }, "require": { @@ -6908,7 +6985,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v6.0.1" + "source": "https://github.com/symfony/web-link/tree/v6.0.3" }, "funding": [ { @@ -6924,7 +7001,7 @@ "type": "tidelift" } ], - "time": "2021-12-08T15:13:44+00:00" + "time": "2022-01-02T09:55:41+00:00" }, { "name": "theseer/tokenizer", @@ -6978,21 +7055,21 @@ }, { "name": "webmozart/assert", - "version": "1.10.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", - "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/11cb2199493b2f8a3b53e7f19068fc6aac760991", + "reference": "11cb2199493b2f8a3b53e7f19068fc6aac760991", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", - "symfony/polyfill-ctype": "^1.8" + "ext-ctype": "*", + "php": "^7.2 || ^8.0" }, "conflict": { "phpstan/phpstan": "<0.12.20", @@ -7030,22 +7107,22 @@ ], "support": { "issues": "https://github.com/webmozarts/assert/issues", - "source": "https://github.com/webmozarts/assert/tree/1.10.0" + "source": "https://github.com/webmozarts/assert/tree/1.11.0" }, - "time": "2021-03-09T10:59:23+00:00" + "time": "2022-06-03T18:03:27+00:00" }, { "name": "willdurand/negotiation", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/willdurand/Negotiation.git", - "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c" + "reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/04e14f38d4edfcc974114a07d2777d90c98f3d9c", - "reference": "04e14f38d4edfcc974114a07d2777d90c98f3d9c", + "url": "https://api.github.com/repos/willdurand/Negotiation/zipball/68e9ea0553ef6e2ee8db5c1d98829f111e623ec2", + "reference": "68e9ea0553ef6e2ee8db5c1d98829f111e623ec2", "shasum": "" }, "require": { @@ -7086,9 +7163,9 @@ ], "support": { "issues": "https://github.com/willdurand/Negotiation/issues", - "source": "https://github.com/willdurand/Negotiation/tree/3.0.0" + "source": "https://github.com/willdurand/Negotiation/tree/3.1.0" }, - "time": "2020-09-25T08:01:41+00:00" + "time": "2022-01-30T20:08:53+00:00" } ], "aliases": [], @@ -7104,5 +7181,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/phpstan.neon b/phpstan.neon index 69f8f4c0..81cdbed9 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -17,6 +17,7 @@ parameters: readable: boolean, writable: boolean, nullable: boolean, + required: ?boolean, unique: boolean, embedded: boolean, columnPrefix: false|string @@ -61,7 +62,8 @@ parameters: annotationGenerators: class-string[], attributeGenerators: class-string[], generatorTemplates: string[], - output: string + output: string, + openApi: array{file: string} } ''' inferPrivatePropertyTypeFromConstructor: true diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php index 8f3d6534..5bc7d70b 100644 --- a/src/AnnotationGenerator/AbstractAnnotationGenerator.php +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -17,9 +17,8 @@ use ApiPlatform\SchemaGenerator\Model\Constant; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use Doctrine\Inflector\Inflector; -use EasyRdf\Graph as RdfGraph; -use Psr\Log\LoggerInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\String\Inflector\InflectorInterface; /** * Abstract annotation generator. @@ -28,31 +27,23 @@ */ abstract class AbstractAnnotationGenerator implements AnnotationGeneratorInterface { + use LoggerAwareTrait; + protected PhpTypeConverterInterface $phpTypeConverter; - protected Inflector $inflector; - protected LoggerInterface $logger; - /** @var RdfGraph[] */ - protected array $graphs; - /** @var array */ - protected array $cardinalities; + protected InflectorInterface $inflector; /** @var Configuration */ protected array $config; /** @var Class_[] */ protected array $classes; /** - * @param RdfGraph[] $graphs - * @param array $cardinalities - * @param Configuration $config - * @param Class_[] $classes + * @param Configuration $config + * @param Class_[] $classes */ - public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes) + public function __construct(PhpTypeConverterInterface $phpTypeConverter, InflectorInterface $inflector, array $config, array $classes) { $this->phpTypeConverter = $phpTypeConverter; $this->inflector = $inflector; - $this->logger = $logger; - $this->graphs = $graphs; - $this->cardinalities = $cardinalities; $this->config = $config; $this->classes = $classes; } diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index babf2735..5462f746 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -17,9 +17,8 @@ use ApiPlatform\SchemaGenerator\Model\Constant; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use Doctrine\Inflector\Inflector; use League\HTMLToMarkdown\HtmlConverter; -use Psr\Log\LoggerInterface; +use Symfony\Component\String\Inflector\InflectorInterface; /** * PHPDoc annotation generator. @@ -35,9 +34,9 @@ final class PhpDocAnnotationGenerator extends AbstractAnnotationGenerator /** * {@inheritdoc} */ - public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes) + public function __construct(PhpTypeConverterInterface $phpTypeConverter, InflectorInterface $inflector, array $config, array $classes) { - parent::__construct($phpTypeConverter, $logger, $inflector, $graphs, $cardinalities, $config, $classes); + parent::__construct($phpTypeConverter, $inflector, $config, $classes); $this->htmlToMarkdown = new HtmlConverter(); } @@ -74,9 +73,7 @@ public function generateConstantAnnotations(Constant $constant): array */ public function generatePropertyAnnotations(Property $property, string $className): array { - $comment = $property->resource ? $property->resource->get('rdfs:comment') : ''; - - $description = $this->formatDoc((string) $comment, true); + $description = $this->formatDoc((string) $property->description(), true); $annotations = []; if ($this->isDocUseful($property)) { @@ -86,8 +83,8 @@ public function generatePropertyAnnotations(Property $property, string $classNam $annotations[] = ''; } - if (null !== $property->resource) { - $annotations[] = sprintf('@see %s', $property->resourceUri()); + if (null !== $property->rdfType()) { + $annotations[] = sprintf('@see %s', $property->rdfType()); } $annotations[] = ''; @@ -128,7 +125,7 @@ public function generateAdderAnnotations(Property $property): array return []; } - return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name()))]; + return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; } /** @@ -140,14 +137,14 @@ public function generateRemoverAnnotations(Property $property): array return []; } - return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name()))]; + return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; } private function isDocUseful(Property $property, bool $adderOrRemover = false): bool { - $typeHint = $adderOrRemover ? $property->adderRemoverTypeHint ?? false : $property->typeHint ?? false; + $typeHint = $adderOrRemover ? $property->adderRemoverTypeHint : $property->typeHint; - return false === $typeHint || 'array' === $typeHint; + return \in_array($typeHint, [false, 'array', 'Collection'], true); } /** @@ -163,9 +160,13 @@ private function generateDoc(Class_ $class, bool $interface = false): array $annotations[] = '{@inheritdoc}'; $annotations[] = ''; } else { - $annotations = $this->formatDoc((string) $class->resourceComment()); - $annotations[] = ''; - $annotations[] = sprintf('@see %s', $class->resource()); + if ($class->description()) { + $annotations = $this->formatDoc($class->description()); + $annotations[] = ''; + } + if ($class->rdfType()) { + $annotations[] = sprintf('@see %s', $class->rdfType()); + } } if ($this->config['author']) { @@ -194,9 +195,6 @@ private function formatDoc(string $doc, bool $indent = false): array return $doc; } - /** - * Converts a RDF range to a PHPDoc type. - */ protected function toPhpDocType(Property $property, bool $adderOrRemover = false): ?string { $suffix = $property->isNullable ? '|null' : ''; @@ -211,16 +209,15 @@ protected function toPhpDocType(Property $property, bool $adderOrRemover = false $enforcedNonArrayProperty = clone $property; $enforcedNonArrayProperty->isArray = false; - if (null !== $phpDocType = $this->phpTypeConverter->getPhpType($enforcedNonArrayProperty)) { + if (!$property->reference && null !== $phpDocType = $this->phpTypeConverter->getPhpType($enforcedNonArrayProperty)) { return ($property->isArray ? sprintf('%s[]', $phpDocType) : $phpDocType).$suffix; } - if (null === $property->range) { + if (!$property->reference) { return null; } - $phpDocType = isset($this->classes[$property->rangeName]) && $this->classes[$property->rangeName]->interfaceName() ? - $this->classes[$property->rangeName]->interfaceName() : $property->rangeName; + $phpDocType = $property->reference->interfaceName() ?: $property->reference->name(); if (!$property->isArray || $adderOrRemover) { return $phpDocType.$suffix; } diff --git a/src/AttributeGenerator/AbstractAttributeGenerator.php b/src/AttributeGenerator/AbstractAttributeGenerator.php index baadd19a..b72d22fc 100644 --- a/src/AttributeGenerator/AbstractAttributeGenerator.php +++ b/src/AttributeGenerator/AbstractAttributeGenerator.php @@ -16,9 +16,8 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use Doctrine\Inflector\Inflector; -use EasyRdf\Graph as RdfGraph; -use Psr\Log\LoggerInterface; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\String\Inflector\InflectorInterface; /** * Abstract attribute generator. @@ -27,31 +26,23 @@ */ abstract class AbstractAttributeGenerator implements AttributeGeneratorInterface { + use LoggerAwareTrait; + protected PhpTypeConverterInterface $phpTypeConverter; - protected Inflector $inflector; - protected LoggerInterface $logger; - /** @var RdfGraph[] */ - protected array $graphs; - /** @var array */ - protected array $cardinalities; + protected InflectorInterface $inflector; /** @var Configuration */ protected array $config; /** @var Class_[] */ protected array $classes; /** - * @param RdfGraph[] $graphs - * @param array $cardinalities - * @param Configuration $config - * @param Class_[] $classes + * @param Configuration $config + * @param Class_[] $classes */ - public function __construct(PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger, Inflector $inflector, array $graphs, array $cardinalities, array $config, array $classes) + public function __construct(PhpTypeConverterInterface $phpTypeConverter, InflectorInterface $inflector, array $config, array $classes) { $this->phpTypeConverter = $phpTypeConverter; $this->inflector = $inflector; - $this->logger = $logger; - $this->graphs = $graphs; - $this->cardinalities = $cardinalities; $this->config = $config; $this->classes = $classes; } diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 33fbc3bc..3251093e 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -40,10 +40,12 @@ public function generateClassAttributes(Class_ $class): array } $arguments = []; - if ($class->name() !== $localName = $class->resourceLocalName()) { + if ($class->name() !== $localName = $class->shortName()) { $arguments['shortName'] = $localName; } - $arguments['iri'] = $class->resourceUri(); + if ($class->rdfType()) { + $arguments['iri'] = $class->rdfType(); + } if ($class->security) { $arguments['security'] = $class->security; } @@ -54,7 +56,7 @@ public function generateClassAttributes(Class_ $class): array $targetArguments = []; foreach ($targetOperations as $method => $methodConfig) { $methodArguments = []; - foreach ($methodConfig as $key => $value) { + foreach ($methodConfig ?? [] as $key => $value) { $methodArguments[$key] = $value; } $targetArguments[$method] = $methodArguments; @@ -90,7 +92,11 @@ private function validateClassOperations(array $operations): array */ public function generatePropertyAttributes(Property $property, string $className): array { - $arguments['iri'] = $property->resourceUri(); + $arguments = []; + + if ($property->rdfType()) { + $arguments['iri'] = $property->rdfType(); + } if ($property->security) { $arguments['security'] = $property->security; diff --git a/src/AttributeGenerator/ConstraintAttributeGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php index f307c53b..a50f4705 100644 --- a/src/AttributeGenerator/ConstraintAttributeGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -42,19 +42,20 @@ public function generatePropertyAttributes(Property $property, string $className $asserts = []; - if (!$property->isArray && $property->range) { - switch ($property->range->getUri()) { - case 'https://schema.org/URL': + if (!$property->isArray && $property->type) { + switch ($property->type) { + case 'url': $asserts[] = new Attribute('Assert\Url'); break; - case 'https://schema.org/Date': - case 'https://schema.org/DateTime': - case 'https://schema.org/Time': + case 'date': + case 'dateTime': + case 'duration': + case 'time': $asserts[] = new Attribute('Assert\Type', [new Literal('\DateTimeInterface::class')]); break; } - if (null !== $property->resource && 'https://schema.org/email' === $property->resourceUri()) { + if ('https://schema.org/email' === $property->rdfType()) { $asserts[] = new Attribute('Assert\Email'); } @@ -70,8 +71,8 @@ public function generatePropertyAttributes(Property $property, string $className $asserts[] = new Attribute('Assert\NotNull'); } - if ($property->isEnum && $property->range && $property->rangeName) { - $args = ['callback' => [new Literal(sprintf('%s::class', $property->rangeName)), 'toArray']]; + if ($property->isEnum && $property->reference) { + $args = ['callback' => [new Literal(sprintf('%s::class', $property->reference->name())), 'toArray']]; if ($property->isArray) { $args['multiple'] = true; @@ -97,11 +98,11 @@ public function generateUses(Class_ $class): array $uses[] = new Use_(UniqueEntity::class); foreach ($class->properties() as $property) { - if ($property->isEnum && $property->range) { - $rangeName = $property->rangeName; - $enumClass = $this->classes[$rangeName]; + if ($property->isEnum && $property->reference) { + $enumName = $property->reference->name(); + $enumClass = $this->classes[$enumName]; $enumNamespace = $enumClass->namespace ?? $this->config['namespaces']['enum']; - $use = new Use_(sprintf('%s\%s', $enumNamespace, $rangeName)); + $use = new Use_(sprintf('%s\%s', $enumNamespace, $enumName)); if (!\in_array($use, $uses, true)) { $uses[] = $use; diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index 727d81a5..563176f4 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -68,7 +68,7 @@ public function generateClassAttributes(Class_ $class): array */ public function generatePropertyAttributes(Property $property, string $className): array { - if (null === $property->range || null === $property->rangeName) { + if (null === $property->type && null === $property->reference) { return []; } @@ -77,19 +77,16 @@ public function generatePropertyAttributes(Property $property, string $className } $type = null; - $isDataType = $this->phpTypeConverter->isDatatype($property->range); if ($property->isEnum) { $type = $property->isArray ? 'simple_array' : 'string'; - } elseif ($property->isArray && $isDataType) { + } elseif ($property->isArray && $property->type) { $type = 'collection'; - } elseif (!$property->isArray && $isDataType && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { - switch ($property->range->getUri()) { - case 'http://www.w3.org/2001/XMLSchema#time': - case 'https://schema.org/Time': + } elseif (!$property->isArray && $property->type && !$property->reference && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { + switch ($property->type) { + case 'time': $type = 'time'; break; - case 'http://www.w3.org/2001/XMLSchema#dateTime': - case 'https://schema.org/DateTime': + case 'dateTime': $type = 'date'; break; default: @@ -116,17 +113,23 @@ public function generatePropertyAttributes(Property $property, string $className return [new Attribute('MongoDB\Field', ['type' => $type])]; } - if ((CardinalitiesExtractor::CARDINALITY_0_1 === $property->cardinality + if (null === $relationName = $this->getRelationName($property->reference)) { + $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; + + return []; + } + + if (CardinalitiesExtractor::CARDINALITY_0_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_0 === $property->cardinality - || CardinalitiesExtractor::CARDINALITY_N_1 === $property->cardinality) && $property->rangeName) { - return [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true])]; + || CardinalitiesExtractor::CARDINALITY_N_1 === $property->cardinality) { + return [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => $relationName, 'simple' => true])]; } - if ((CardinalitiesExtractor::CARDINALITY_0_N === $property->cardinality + if (CardinalitiesExtractor::CARDINALITY_0_N === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_N === $property->cardinality - || CardinalitiesExtractor::CARDINALITY_N_N === $property->cardinality) && $property->rangeName) { - return [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => $this->getRelationName($property->rangeName), 'simple' => true])]; + || CardinalitiesExtractor::CARDINALITY_N_N === $property->cardinality) { + return [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => $relationName, 'simple' => true])]; } return []; @@ -143,10 +146,13 @@ public function generateUses(Class_ $class): array /** * Gets class or interface name to use in relations. */ - private function getRelationName(string $rangeName): string + private function getRelationName(?Class_ $reference): ?string { - return isset($this->classes[$rangeName]) && $this->classes[$rangeName]->interfaceName() - ? $this->classes[$rangeName]->interfaceName() : $rangeName; + if (!$reference) { + return null; + } + + return $reference->interfaceName() ?: $reference->name(); } /** diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index fda8ca03..e37650da 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -93,7 +93,7 @@ public function generateClassAttributes(Class_ $class): array */ public function generatePropertyAttributes(Property $property, string $className): array { - if (null === $property->range || null === $property->rangeName) { + if (null === $property->type && null === $property->reference) { return []; } @@ -110,20 +110,16 @@ public function generatePropertyAttributes(Property $property, string $className } $type = null; - $isDataType = $this->phpTypeConverter->isDatatype($property->range); if ($property->isEnum) { $type = $property->isArray ? 'simple_array' : 'string'; - } elseif ($property->isArray && $isDataType) { + } elseif ($property->isArray && $property->type) { $type = 'json'; - } elseif (!$property->isArray && $isDataType && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { - switch ($property->range->getUri()) { - // TODO: use more precise types for int (smallint, bigint...) - case 'http://www.w3.org/2001/XMLSchema#time': - case 'https://schema.org/Time': + } elseif (!$property->isArray && $property->type && !$property->reference && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { + switch ($property->type) { + case 'time': $type = 'time'; break; - case 'http://www.w3.org/2001/XMLSchema#dateTime': - case 'https://schema.org/DateTime': + case 'dateTime': $type = 'date'; break; default: @@ -132,6 +128,7 @@ public function generatePropertyAttributes(Property $property, string $className case 'bool': $type = 'boolean'; break; + // TODO: use more precise types for int (smallint, bigint...) case 'int': $type = 'integer'; break; @@ -173,8 +170,8 @@ public function generatePropertyAttributes(Property $property, string $className return [new Attribute('ORM\Column', $args)]; } - if (null === $relationName = $this->getRelationName($property->rangeName)) { - $this->logger->error('The type "{type}" of the property "{property}" from the class "{class}" doesn\'t exist', ['type' => $property->range->getUri(), 'property' => $property->name(), 'class' => $className]); + if (null === $relationName = $this->getRelationName($property->reference)) { + $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; return []; } @@ -279,26 +276,24 @@ private function generateIdAttributes(): array /** * Gets class or interface name to use in relations. */ - private function getRelationName(string $rangeName): ?string + private function getRelationName(?Class_ $reference): ?string { - if (!isset($this->classes[$rangeName])) { + if (!$reference) { return null; } - $class = $this->classes[$rangeName]; - - if (null !== $class->interfaceName()) { - if (isset($this->config['types'][$rangeName]['namespaces']['interface'])) { - return sprintf('%s\\%s', $this->config['types'][$rangeName]['namespaces']['interface'], $class->interfaceName()); + if (null !== $reference->interfaceName()) { + if (isset($this->config['types'][$reference->name()]['namespaces']['interface'])) { + return sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['interface'], $reference->interfaceName()); } - return sprintf('%s\\%s', $this->config['namespaces']['interface'], $class->interfaceName()); + return sprintf('%s\\%s', $this->config['namespaces']['interface'], $reference->interfaceName()); } - if (isset($this->config['types'][$rangeName]['namespaces']['class'])) { - return sprintf('%s\\%s', $this->config['types'][$rangeName]['namespaces']['class'], $class->name()); + if (isset($this->config['types'][$reference->name()]['namespaces']['class'])) { + return sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['class'], $reference->name()); } - return sprintf('%s\\%s', $this->config['namespaces']['entity'], $rangeName); + return sprintf('%s\\%s', $this->config['namespaces']['entity'], $reference->name()); } } diff --git a/src/ClassMutator/AnnotationsAppender.php b/src/ClassMutator/AnnotationsAppender.php index fb8a23d8..2d4c2aff 100644 --- a/src/ClassMutator/AnnotationsAppender.php +++ b/src/ClassMutator/AnnotationsAppender.php @@ -39,21 +39,19 @@ public function __construct(array $classes, array $annotationGenerators, array $ $this->typesToGenerate = $typesToGenerate; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { - $class = $this->generateClassUses($class); - $class = $this->generateClassAnnotations($class); + $this->generateClassUses($class); + $this->generateClassAnnotations($class); if (false === isset($this->typesToGenerate[$class->name()])) { - $class = $this->generateInterfaceAnnotations($class); + $this->generateInterfaceAnnotations($class); } - $class = $this->generateConstantAnnotations($class); - $class = $this->generatePropertiesAnnotations($class); - - return $class; + $this->generateConstantAnnotations($class); + $this->generatePropertiesAnnotations($class); } - private function generateClassUses(Class_ $class): Class_ + private function generateClassUses(Class_ $class): void { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace) { @@ -61,11 +59,11 @@ private function generateClassUses(Class_ $class): Class_ } foreach ($class->properties() as $property) { - if (isset($this->classes[$property->rangeName]) && $this->classes[$property->rangeName]->interfaceName()) { + if ($property->reference && $property->reference->interfaceName()) { $class->addUse(new Use_(sprintf( '%s\\%s', - $this->classes[$property->rangeName]->interfaceNamespace(), - $this->classes[$property->rangeName]->interfaceName() + $property->reference->interfaceNamespace(), + $property->reference->interfaceName() ))); } } @@ -75,22 +73,18 @@ private function generateClassUses(Class_ $class): Class_ $class->addUse($use); } } - - return $class; } - private function generateClassAnnotations(Class_ $class): Class_ + private function generateClassAnnotations(Class_ $class): void { foreach ($this->annotationGenerators as $generator) { foreach ($generator->generateClassAnnotations($class) as $annotation) { $class->addAnnotation($annotation); } } - - return $class; } - private function generateConstantAnnotations(Class_ $class): Class_ + private function generateConstantAnnotations(Class_ $class): void { foreach ($class->constants() as $constant) { foreach ($this->annotationGenerators as $generator) { @@ -99,24 +93,20 @@ private function generateConstantAnnotations(Class_ $class): Class_ } } } - - return $class; } - private function generateInterfaceAnnotations(Class_ $class): Class_ + private function generateInterfaceAnnotations(Class_ $class): void { foreach ($this->annotationGenerators as $generator) { foreach ($generator->generateInterfaceAnnotations($class) as $interfaceAnnotation) { $class->addInterfaceAnnotation($interfaceAnnotation); } } - - return $class; } - private function generatePropertiesAnnotations(Class_ $class): Class_ + private function generatePropertiesAnnotations(Class_ $class): void { - foreach ($class->properties() as $name => &$property) { + foreach ($class->properties() as $property) { foreach ($this->annotationGenerators as $annotationGenerator) { foreach ($annotationGenerator->generatePropertyAnnotations($property, $class->name()) as $propertyAnnotation) { $property->addAnnotation($propertyAnnotation); @@ -141,7 +131,5 @@ private function generatePropertiesAnnotations(Class_ $class): Class_ } } } - - return $class; } } diff --git a/src/ClassMutator/AttributeAppender.php b/src/ClassMutator/AttributeAppender.php index d707658f..0bc7ea62 100644 --- a/src/ClassMutator/AttributeAppender.php +++ b/src/ClassMutator/AttributeAppender.php @@ -34,16 +34,14 @@ public function __construct(array $classes, array $attributeGenerators) $this->classes = $classes; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { - $class = $this->generateClassUses($class); - $class = $this->generateClassAttributes($class); - $class = $this->generatePropertiesAttributes($class); - - return $class; + $this->generateClassUses($class); + $this->generateClassAttributes($class); + $this->generatePropertiesAttributes($class); } - private function generateClassUses(Class_ $class): Class_ + private function generateClassUses(Class_ $class): void { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace) { @@ -51,11 +49,11 @@ private function generateClassUses(Class_ $class): Class_ } foreach ($class->properties() as $property) { - if (isset($this->classes[$property->rangeName]) && $this->classes[$property->rangeName]->interfaceName()) { + if ($property->reference && $property->reference->interfaceName()) { $class->addUse(new Use_(sprintf( '%s\\%s', - $this->classes[$property->rangeName]->interfaceNamespace(), - $this->classes[$property->rangeName]->interfaceName() + $property->reference->interfaceNamespace(), + $property->reference->interfaceName() ))); } } @@ -65,22 +63,18 @@ private function generateClassUses(Class_ $class): Class_ $class->addUse($use); } } - - return $class; } - private function generateClassAttributes(Class_ $class): Class_ + private function generateClassAttributes(Class_ $class): void { foreach ($this->attributeGenerators as $generator) { foreach ($generator->generateClassAttributes($class) as $attribute) { $class->addAttribute($attribute); } } - - return $class; } - private function generatePropertiesAttributes(Class_ $class): Class_ + private function generatePropertiesAttributes(Class_ $class): void { foreach ($class->properties() as $property) { foreach ($this->attributeGenerators as $attributeGenerator) { @@ -89,7 +83,5 @@ private function generatePropertiesAttributes(Class_ $class): Class_ } } } - - return $class; } } diff --git a/src/ClassMutator/ClassIdAppender.php b/src/ClassMutator/ClassIdAppender.php index ea02384f..9510c1d7 100644 --- a/src/ClassMutator/ClassIdAppender.php +++ b/src/ClassMutator/ClassIdAppender.php @@ -14,22 +14,24 @@ namespace ApiPlatform\SchemaGenerator\ClassMutator; use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGenerator; +use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGeneratorInterface; final class ClassIdAppender implements ClassMutatorInterface { + private IdPropertyGeneratorInterface $idPropertyGenerator; /** @var Configuration */ private array $config; /** * @param Configuration $config */ - public function __construct(array $config) + public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator, array $config) { + $this->idPropertyGenerator = $idPropertyGenerator; $this->config = $config; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { if ( $class->isEnum() @@ -37,9 +39,9 @@ public function __invoke(Class_ $class): Class_ || ($class->hasParent() && 'parent' === $this->config['id']['onClass']) || ($class->hasChild && 'child' === $this->config['id']['onClass']) ) { - return $class; + return; } - return $class->addProperty((new IdPropertyGenerator())($this->config['id']['generationStrategy'], $this->config['id']['writable'])); + $class->addProperty(($this->idPropertyGenerator)($this->config['id']['generationStrategy'], $this->config['id']['writable'])); } } diff --git a/src/ClassMutator/ClassInterfaceMutator.php b/src/ClassMutator/ClassInterfaceMutator.php index e1838f47..506bc213 100644 --- a/src/ClassMutator/ClassInterfaceMutator.php +++ b/src/ClassMutator/ClassInterfaceMutator.php @@ -25,10 +25,8 @@ public function __construct(string $desiredNamespace) $this->desiredNamespace = $desiredNamespace; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { $class->interface = new Interface_(sprintf('%sInterface', $class->name()), $this->desiredNamespace); - - return $class; } } diff --git a/src/ClassMutator/ClassMutatorInterface.php b/src/ClassMutator/ClassMutatorInterface.php index d9711c5a..d52f1600 100644 --- a/src/ClassMutator/ClassMutatorInterface.php +++ b/src/ClassMutator/ClassMutatorInterface.php @@ -17,5 +17,5 @@ interface ClassMutatorInterface { - public function __invoke(Class_ $class): Class_; + public function __invoke(Class_ $class): void; } diff --git a/src/ClassMutator/ClassParentMutator.php b/src/ClassMutator/ClassParentMutator.php index 852fe720..52c5d032 100644 --- a/src/ClassMutator/ClassParentMutator.php +++ b/src/ClassMutator/ClassParentMutator.php @@ -16,36 +16,41 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use Psr\Log\LoggerInterface; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use Psr\Log\LoggerAwareTrait; final class ClassParentMutator implements ClassMutatorInterface { + use LoggerAwareTrait; + private PhpTypeConverterInterface $phpTypeConverter; - private LoggerInterface $logger; /** @var Configuration */ private array $config; /** * @param Configuration $config */ - public function __construct(array $config, PhpTypeConverterInterface $phpTypeConverter, LoggerInterface $logger) + public function __construct(array $config, PhpTypeConverterInterface $phpTypeConverter) { $this->phpTypeConverter = $phpTypeConverter; - $this->logger = $logger; $this->config = $config; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { + if (!$class instanceof SchemaClass) { + return; + } + $typeConfig = $this->config['types'][$class->name()] ?? null; $class->withParent($typeConfig['parent'] ?? null); if (null === $class->parent() && $subclassOf = $class->getSubClassOf()) { if (\count($subclassOf) > 1) { - $this->logger->warning(sprintf('The type "%s" has several supertypes. Using the first one.', $class->resourceUri())); + $this->logger ? $this->logger->warning(sprintf('The type "%s" has several supertypes. Using the first one.', $class->rdfType())) : null; } - $class = $class->withParent($this->phpTypeConverter->escapeIdentifier($subclassOf[0]->localName())); + $class->withParent($this->phpTypeConverter->escapeIdentifier($subclassOf[0]->localName())); } if ($class->hasParent() && isset($this->config['types'][$class->parent()]['namespaces']['class'])) { @@ -55,7 +60,5 @@ public function __invoke(Class_ $class): Class_ $class->addUse(new Use_($parentNamespace.'\\'.$class->parent())); } } - - return $class; } } diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 006c6925..4c82693b 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -14,15 +14,17 @@ namespace ApiPlatform\SchemaGenerator\ClassMutator; use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; -use Psr\Log\LoggerInterface; +use Psr\Log\LoggerAwareTrait; final class ClassPropertiesAppender implements ClassMutatorInterface { - private PropertyGenerator $propertyGenerator; - private LoggerInterface $logger; + use LoggerAwareTrait; + + private PropertyGeneratorInterface $propertyGenerator; /** @var array */ private array $propertiesMap; /** @var Configuration */ @@ -42,17 +44,20 @@ final class ClassPropertiesAppender implements ClassMutatorInterface * @param array $propertiesMap * @param RdfGraph[] $graphs */ - public function __construct(PropertyGenerator $propertyGenerator, LoggerInterface $logger, array $config, array $propertiesMap, array $graphs) + public function __construct(PropertyGeneratorInterface $propertyGenerator, array $config, array $propertiesMap, array $graphs) { $this->propertiesMap = $propertiesMap; $this->propertyGenerator = $propertyGenerator; - $this->logger = $logger; $this->config = $config; $this->graphs = $graphs; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { + if (!$class instanceof SchemaClass) { + return; + } + $typeConfig = $this->config['types'][$class->name()] ?? null; if (null !== $typeConfig && !$typeConfig['allProperties']) { @@ -67,26 +72,26 @@ public function __invoke(Class_ $class): Class_ continue; } - $class = $this->generateField($this->config, $class, $class->resource(), $typeConfig, $property); + $this->generateField($this->config, $class, $class->resource(), $typeConfig, $property); continue 3; } } - $class = $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); + $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); } } else { $remainingProperties = $typeConfig['properties'] ?? []; - if (!isset($this->propertiesMap[$class->resourceUri()])) { - $this->logger->warning(sprintf('Properties for "%s" not found in the map.', $class->resourceUri())); + if (!isset($this->propertiesMap[$class->rdfType()])) { + $this->logger ? $this->logger->warning(sprintf('Properties for "%s" not found in the map.', $class->rdfType())) : null; } // All properties - foreach ($this->propertiesMap[$class->resourceUri()] ?? [] as $property) { + foreach ($this->propertiesMap[$class->rdfType()] ?? [] as $property) { unset($remainingProperties[$property->localName()]); if ($property->hasProperty(self::SCHEMA_ORG_SUPERSEDED_BY)) { $supersededBy = $property->get(self::SCHEMA_ORG_SUPERSEDED_BY); - $this->logger->warning(sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())); + $this->logger ? $this->logger->warning(sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())) : null; } else { - $class = $this->generateField($this->config, $class, $class->resource(), $typeConfig, $property); + $this->generateField($this->config, $class, $class->resource(), $typeConfig, $property); } } @@ -94,11 +99,9 @@ public function __invoke(Class_ $class): Class_ if ($remainingProperty['exclude']) { continue; } - $class = $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); + $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); } } - - return $class; } /** @@ -107,13 +110,13 @@ public function __invoke(Class_ $class): Class_ * @param ?TypeConfiguration $typeConfig * @param Configuration $config */ - private function generateCustomField(string $propertyName, RdfResource $type, ?array $typeConfig, Class_ $class, array $config): Class_ + private function generateCustomField(string $propertyName, RdfResource $type, ?array $typeConfig, SchemaClass $class, array $config): void { - $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())); + $this->logger ? $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())) : null; $customResource = new RdfResource('_:'.$propertyName, new RdfGraph()); $customResource->add('rdfs:range', $type); - return $this->generateField($config, $class, $type, $typeConfig, $customResource, true); + $this->generateField($config, $class, $type, $typeConfig, $customResource, true); } /** @@ -122,9 +125,11 @@ private function generateCustomField(string $propertyName, RdfResource $type, ?a * @param Configuration $config * @param ?TypeConfiguration $typeConfig */ - private function generateField(array $config, Class_ $class, RdfResource $type, ?array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ + private function generateField(array $config, SchemaClass $class, RdfResource $type, ?array $typeConfig, RdfResource $typeProperty, bool $isCustom = false): void { - return ($this->propertyGenerator)($config, $class, $type, $typeConfig, $property, $isCustom); + $property = ($this->propertyGenerator)($typeProperty->localName(), $config, $class, ['type' => $type, 'typeConfig' => $typeConfig, 'property' => $typeProperty], $isCustom); + + $class->addProperty($property); } /** diff --git a/src/ClassMutator/ClassPropertiesTypehintMutator.php b/src/ClassMutator/ClassPropertiesTypehintMutator.php index 022a17f2..cc648b4e 100644 --- a/src/ClassMutator/ClassPropertiesTypehintMutator.php +++ b/src/ClassMutator/ClassPropertiesTypehintMutator.php @@ -35,10 +35,10 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $ $this->config = $config; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { foreach ($class->properties() as $property) { - $property->isEnum = isset($this->classes[$property->rangeName]) && ($this->classes[$property->rangeName])->isEnum(); + $property->isEnum = $property->isEnum ?: $property->reference && $property->reference->isEnum(); $property->typeHint = $this->phpTypeConverter->getPhpType( $property, $this->config, @@ -52,7 +52,5 @@ public function __invoke(Class_ $class): Class_ $property->adderRemoverTypeHint = $this->phpTypeConverter->getPhpType($nonArrayForcedProperty, $this->config, $this->classes); } } - - return $class; } } diff --git a/src/ClassMutator/EnumClassMutator.php b/src/ClassMutator/EnumClassMutator.php index 2ed99ead..10e0827a 100644 --- a/src/ClassMutator/EnumClassMutator.php +++ b/src/ClassMutator/EnumClassMutator.php @@ -14,48 +14,30 @@ namespace ApiPlatform\SchemaGenerator\ClassMutator; use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Constant; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use EasyRdf\Graph as RdfGraph; use MyCLabs\Enum\Enum; -final class EnumClassMutator implements ClassMutatorInterface +abstract class EnumClassMutator implements ClassMutatorInterface { - private PhpTypeConverterInterface $phpTypeConverter; - - /** - * @var RdfGraph[] - */ - private array $graphs; + protected PhpTypeConverterInterface $phpTypeConverter; private string $desiredNamespace; - /** - * @param RdfGraph[] $graphs - */ - public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $graphs, string $desiredNamespace) + public function __construct(PhpTypeConverterInterface $phpTypeConverter, string $desiredNamespace) { $this->phpTypeConverter = $phpTypeConverter; - $this->graphs = $graphs; $this->desiredNamespace = $desiredNamespace; } - public function __invoke(Class_ $class): Class_ + public function __invoke(Class_ $class): void { $class->namespace = $this->desiredNamespace; - $class = $class + $class ->withParent('Enum') ->addUse(new Use_(Enum::class)); - foreach ($this->graphs as $graph) { - foreach ($graph->allOfType($class->resourceUri()) as $instance) { - $class->addConstant($instance->localName(), new Constant( - $this->phpTypeConverter->escapeIdentifier(strtoupper(substr(preg_replace('/([A-Z])/', '_$1', $instance->localName()), 1))), - $instance - )); - } - } - - return $class; + $this->addEnumConstants($class); } + + abstract protected function addEnumConstants(Class_ $class): void; } diff --git a/src/Command/DumpConfigurationCommand.php b/src/Command/DumpConfigurationCommand.php index 639ce32f..04b00026 100644 --- a/src/Command/DumpConfigurationCommand.php +++ b/src/Command/DumpConfigurationCommand.php @@ -13,7 +13,7 @@ namespace ApiPlatform\SchemaGenerator\Command; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use Symfony\Component\Config\Definition\Dumper\YamlReferenceDumper; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -41,7 +41,7 @@ protected function configure(): void */ protected function execute(InputInterface $input, OutputInterface $output): int { - $configuration = new TypesGeneratorConfiguration(); + $configuration = new SchemaGeneratorConfiguration(); $dumper = new YamlReferenceDumper(); $output->writeln($dumper->dump($configuration)); diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 2e70f6b9..1e721918 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -15,7 +15,7 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputInterface; @@ -37,8 +37,8 @@ protected function configure(): void $this ->setName('extract-cardinalities') ->setDescription('Extract properties\' cardinality') - ->addOption('vocabulary-file', 's', InputOption::VALUE_REQUIRED, 'The path or URL of the vocabulary RDF file to use.', TypesGeneratorConfiguration::SCHEMA_ORG_URI) - ->addOption('cardinality-file', 'g', InputOption::VALUE_REQUIRED, 'The path or URL of the OWL file containing the cardinality definitions.', TypesGeneratorConfiguration::GOOD_RELATIONS_URI) + ->addOption('vocabulary-file', 's', InputOption::VALUE_REQUIRED, 'The path or URL of the vocabulary RDF file to use.', SchemaGeneratorConfiguration::SCHEMA_ORG_URI) + ->addOption('cardinality-file', 'g', InputOption::VALUE_REQUIRED, 'The path or URL of the OWL file containing the cardinality definitions.', SchemaGeneratorConfiguration::GOOD_RELATIONS_URI) ; } diff --git a/src/Command/GenerateCommand.php b/src/Command/GenerateCommand.php index fb14bdc9..23989e86 100644 --- a/src/Command/GenerateCommand.php +++ b/src/Command/GenerateCommand.php @@ -13,27 +13,18 @@ namespace ApiPlatform\SchemaGenerator\Command; -use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; -use ApiPlatform\SchemaGenerator\GoodRelationsBridge; -use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use ApiPlatform\SchemaGenerator\Printer; -use ApiPlatform\SchemaGenerator\TypesGenerator; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use Doctrine\Inflector\InflectorFactory; -use EasyRdf\Graph as RdfGraph; +use ApiPlatform\SchemaGenerator\OpenApi\Generator as OpenApiGenerator; +use ApiPlatform\SchemaGenerator\Schema\Generator as SchemaGenerator; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; -use Symfony\Component\Console\Logger\ConsoleLogger; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Yaml\Parser; -use Twig\Environment; -use Twig\Extension\DebugExtension; -use Twig\Loader\FilesystemLoader; /** * Generate entities command. @@ -110,6 +101,9 @@ protected function execute(InputInterface $input, OutputInterface $output): int } else { (new Filesystem())->mkdir($outputDir); $outputDir = realpath($outputDir); + if (!$outputDir) { + throw new \InvalidArgumentException(sprintf('The "%s" directory cannot be created.', $outputDir)); + } } if ($configArgument) { @@ -128,83 +122,43 @@ protected function execute(InputInterface $input, OutputInterface $output): int if (false === ($configContent = file_get_contents($configArgument))) { throw new \RuntimeException(sprintf('Cannot read "%s" content.', $configArgument)); } - - $parser = new Parser(); - $config = $parser->parse($configContent); - unset($parser); } elseif (is_readable(self::DEFAULT_CONFIG_FILE)) { - if (false === ($defaultConfigContent = file_get_contents(self::DEFAULT_CONFIG_FILE))) { + if (false === ($configContent = file_get_contents(self::DEFAULT_CONFIG_FILE))) { throw new \RuntimeException(sprintf('Cannot read "%s" content.', self::DEFAULT_CONFIG_FILE)); } - - $parser = new Parser(); - $config = $parser->parse($defaultConfigContent); - unset($parser); } else { if (!$io->askQuestion(new ConfirmationQuestion('Your project has no config file. The entire vocabulary will be imported.'.\PHP_EOL.'Continue?', false))) { return Command::SUCCESS; } - - $config = []; + $configContent = 'allTypes: true'; } - $processor = new Processor(); - $configuration = new TypesGeneratorConfiguration($dir === $defaultOutput ? $this->namespacePrefix : null); - /** @var Configuration */ - $processedConfiguration = $processor->processConfiguration($configuration, [$config]); - $processedConfiguration['output'] = $outputDir; - if (!$processedConfiguration['output']) { - throw new \RuntimeException('The specified output is invalid'); - } - - $graphs = []; - foreach ($processedConfiguration['vocabularies'] as $vocab) { - $graph = new RdfGraph(); - if (0 === strpos($vocab['uri'], 'http://') || 0 === strpos($vocab['uri'], 'https://')) { - $graph->load($vocab['uri'], $vocab['format']); - } else { - $graph->parseFile($vocab['uri'], $vocab['format']); - } - - $graphs[] = $graph; - } - - $relations = []; - foreach ($processedConfiguration['relations'] as $relation) { - $relations[] = new \SimpleXMLElement($relation, 0, true); - } + $configuration = $this->processConfiguration($configContent, $outputDir, $dir === $defaultOutput ? $this->namespacePrefix : null); - $goodRelationsBridge = new GoodRelationsBridge($relations); - $cardinalitiesExtractor = new CardinalitiesExtractor($graphs, $goodRelationsBridge); + (new SchemaGenerator())->generate($configuration, $output, $io); + (new OpenApiGenerator())->generate($configuration, $configArgument ?? self::DEFAULT_CONFIG_FILE, $output, $io); - $templatePaths = $processedConfiguration['generatorTemplates']; - $templatePaths[] = __DIR__.'/../../templates/'; - - $inflector = InflectorFactory::create()->build(); + return Command::SUCCESS; + } - $loader = new FilesystemLoader($templatePaths); - $twig = new Environment($loader, ['autoescape' => false, 'debug' => $processedConfiguration['debug']]); + /** + * @return Configuration + */ + private function processConfiguration(string $configContent, string $outputDir, ?string $defaultNamespacePrefix): array + { + $parser = new Parser(); + $config = $parser->parse($configContent); + unset($parser); - if ($processedConfiguration['debug']) { - $twig->addExtension(new DebugExtension()); + $processor = new Processor(); + $configuration = new SchemaGeneratorConfiguration($defaultNamespacePrefix); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = $processor->processConfiguration($configuration, [$config]); + $processedConfiguration['output'] = $outputDir; + if (!$processedConfiguration['output']) { + throw new \RuntimeException('The specified output is invalid.'); } - $logger = new ConsoleLogger($output); - - $entitiesGenerator = new TypesGenerator( - $inflector, - $twig, - $logger, - $graphs, - new PhpTypeConverter(), - $cardinalitiesExtractor, - $goodRelationsBridge, - new Printer(), - $io - ); - - $entitiesGenerator->generate($processedConfiguration); - - return Command::SUCCESS; + return $processedConfiguration; } } diff --git a/src/FilesGenerator.php b/src/FilesGenerator.php new file mode 100644 index 00000000..a201aa14 --- /dev/null +++ b/src/FilesGenerator.php @@ -0,0 +1,175 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator; + +use ApiPlatform\SchemaGenerator\Model\Class_; +use Nette\InvalidArgumentException as NetteInvalidArgumentException; +use Nette\PhpGenerator\PhpFile; +use PhpCsFixer\Cache\NullCacheManager; +use PhpCsFixer\Differ\NullDiffer; +use PhpCsFixer\Error\ErrorsManager; +use PhpCsFixer\FixerFactory; +use PhpCsFixer\Linter\Linter; +use PhpCsFixer\RuleSet as LegacyRuleSet; +use PhpCsFixer\RuleSet\RuleSet; +use PhpCsFixer\Runner\Runner; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\String\Inflector\InflectorInterface; +use Twig\Environment; + +final class FilesGenerator +{ + use LoggerAwareTrait; + + private InflectorInterface $inflector; + private Printer $printer; + private Environment $twig; + private Filesystem $filesystem; + private SymfonyStyle $io; + + public function __construct(InflectorInterface $inflector, Printer $printer, Environment $twig, SymfonyStyle $io) + { + $this->inflector = $inflector; + $this->printer = $printer; + $this->twig = $twig; + $this->filesystem = new Filesystem(); + $this->io = $io; + } + + /** + * Generates files. + * + * @param Class_[] $classes + * @param Configuration $config + */ + public function generate(array $classes, array $config): void + { + $interfaceMappings = []; + $generatedFiles = []; + + foreach ($classes as $className => $class) { + $classDir = $this->namespaceToDir($class->namespace, $config); + $this->filesystem->mkdir($classDir); + + $path = sprintf('%s%s.php', $classDir, $className); + + $file = null; + if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) { + $confirmation = $this->io->askQuestion(new ConfirmationQuestion(sprintf('File "%s" already exists, use it (if no it will be overwritten)?', $path))); + if ($confirmation) { + $file = PhpFile::fromCode($fileContent); + $this->logger ? $this->logger->info(sprintf('Using "%s" as base file.', $path)) : null; + } + } + + try { + file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector, $file))); + } catch (NetteInvalidArgumentException $exception) { + $this->logger ? $this->logger->warning($exception->getMessage()) : null; + } + + $generatedFiles[] = $path; + + if (null !== $class->interfaceNamespace()) { + $interfaceDir = $this->namespaceToDir($class->interfaceNamespace(), $config); + $this->filesystem->mkdir($interfaceDir); + + $path = sprintf('%s%s.php', $interfaceDir, $class->interfaceName()); + $generatedFiles[] = $path; + file_put_contents($path, $this->printer->printFile($class->interfaceToNetteFile($config['header'] ?? null))); + + if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class->isAbstract) { + $interfaceMappings[$class->interfaceNamespace().'\\'.$class->interfaceName()] = $class->namespace.'\\'.$className; + } + } + } + + if ($config['doctrine']['resolveTargetEntityConfigPath'] && \count($interfaceMappings) > 0) { + $file = $config['output'].'/'.$config['doctrine']['resolveTargetEntityConfigPath']; + $dir = \dirname($file); + $this->filesystem->mkdir($dir); + + $fileType = $config['doctrine']['resolveTargetEntityConfigType']; + + $mappingTemplateFile = 'doctrine.xml.twig'; + if ('yaml' === $fileType) { + $mappingTemplateFile = 'doctrine.yaml.twig'; + } + + file_put_contents( + $file, + $this->twig->render($mappingTemplateFile, ['mappings' => $interfaceMappings]) + ); + + $generatedFiles[] = $file; + } + + $this->fixCs($generatedFiles); + } + + /** + * Converts a namespace to a directory path according to PSR-4. + * + * @param Configuration $config + */ + private function namespaceToDir(string $namespace, array $config): string + { + if (null !== ($prefix = $config['namespaces']['prefix'] ?? null) && 0 === strpos($namespace, $prefix)) { + $namespace = substr($namespace, \strlen($prefix)); + } + + return sprintf('%s/%s/', $config['output'], str_replace('\\', '/', $namespace)); + } + + /** + * Uses PHP CS Fixer to make generated files following PSR and Symfony Coding Standards. + * + * @param string[] $files + */ + private function fixCs(array $files): void + { + $fileInfos = []; + foreach ($files as $file) { + $fileInfos[] = new \SplFileInfo($file); + } + + // to keep compatibility with both versions of php-cs-fixer: 2.x and 3.x + // ruleset object must be created depending on which class is available + $rulesetClass = class_exists(LegacyRuleSet::class) ? LegacyRuleSet::class : Ruleset::class; + $fixers = (new FixerFactory()) + ->registerBuiltInFixers() + ->useRuleSet(new $rulesetClass([ // @phpstan-ignore-line + '@Symfony' => true, + 'array_syntax' => ['syntax' => 'short'], + 'phpdoc_order' => true, + 'declare_strict_types' => true, + ])) + ->getFixers(); + + $runner = new Runner( + new \ArrayIterator($fileInfos), + $fixers, + new NullDiffer(), + null, + new ErrorsManager(), + new Linter(), + false, + new NullCacheManager() + ); + $runner->fix(); + } +} diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index 64ffd87f..32aebcbb 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -105,18 +105,17 @@ public function extractCardinality(string $id) { foreach ($this->relations as $relation) { $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', $this->getPropertyUrl($id))); - if (false === $result) { + if (!$result) { continue; } - if (\count($result)) { - $xmlResult = $result[0]->asXML(); - if (false === $xmlResult) { - continue; - } - preg_match('/\(.\.\..\)/', $xmlResult, $matches); - - return $matches[0]; + + $xmlResult = $result[0]->asXML(); + if (false === $xmlResult) { + continue; } + preg_match('/\(.\.\..\)/', $xmlResult, $matches); + + return $matches[0]; } return false; diff --git a/src/Model/Class_.php b/src/Model/Class_.php index cfe2aa46..e2e0bcaa 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -13,19 +13,18 @@ namespace ApiPlatform\SchemaGenerator\Model; -use Doctrine\Inflector\Inflector; -use EasyRdf\Resource as RdfResource; use MyCLabs\Enum\Enum as MyCLabsEnum; +use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Helpers; use Nette\PhpGenerator\Method; use Nette\PhpGenerator\PhpFile; +use Symfony\Component\String\Inflector\InflectorInterface; -final class Class_ +abstract class Class_ { use ResolveNameTrait; - private string $name; - private RdfResource $resource; + protected string $name; public string $namespace = ''; /** @var false|string|null */ private $parent; @@ -46,18 +45,15 @@ final class Class_ public bool $hasChild = false; public bool $isEmbeddable = false; public ?string $security = null; - /** @var array> */ + /** @var array> */ public array $operations = []; - private const SCHEMA_ORG_ENUMERATION = 'https://schema.org/Enumeration'; - /** * @param false|string|null $parent */ - public function __construct(string $name, RdfResource $resource, $parent = null) + public function __construct(string $name, $parent = null) { $this->name = $name; - $this->resource = $resource; $this->parent = $parent; } @@ -66,25 +62,11 @@ public function name(): string return $this->name; } - public function resource(): RdfResource - { - return $this->resource; - } + abstract public function description(): ?string; - public function resourceUri(): string - { - return $this->resource->getUri(); - } + abstract public function rdfType(): ?string; - public function resourceComment(): ?string - { - return (string) $this->resource->get('rdfs:comment'); - } - - public function resourceLocalName(): string - { - return $this->resource->localName(); - } + abstract public function shortName(): string; public function isInNamespace(string $namespace): bool { @@ -225,20 +207,7 @@ public function constants(): array return $this->constants; } - /** - * @return RdfResource[] - */ - public function getSubClassOf(): array - { - return array_filter($this->resource->all('rdfs:subClassOf', 'resource'), static fn (RdfResource $resource) => !$resource->isBNode()); - } - - public function isEnum(): bool - { - $subClassOf = $this->resource->get('rdfs:subClassOf'); - - return $subClassOf && self::SCHEMA_ORG_ENUMERATION === $subClassOf->getUri(); - } + abstract public function isEnum(): bool; public function isParentEnum(): bool { @@ -252,7 +221,7 @@ public function isParentEnum(): bool /** * @param Configuration $config */ - public function toNetteFile(array $config, Inflector $inflector, ?PhpFile $file = null): PhpFile + public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFile $file = null): PhpFile { $useDoctrineCollections = $config['doctrine']['useCollection']; $useAccessors = $config['accessorMethods']; @@ -275,6 +244,7 @@ public function toNetteFile(array $config, Inflector $inflector, ?PhpFile $file $namespace->addUse($use->name(), $use->alias()); } + /** @var ?ClassType $class */ $class = $namespace->getClasses()[$this->name] ?? null; if (!$class) { $class = $namespace->addClass($this->name); @@ -369,7 +339,7 @@ public function toNetteFile(array $config, Inflector $inflector, ?PhpFile $file $methods = []; foreach ($sortedProperties as $property) { foreach ($property->generateNetteMethods(static function ($string) use ($inflector) { - return $inflector->singularize($string); + return $inflector->singularize($string)[0]; }, $namespace, $useDoctrineCollections, $useFluentMutators) as $method) { $methods[] = $method; } diff --git a/src/Model/Constant.php b/src/Model/Constant.php index 92521a45..41833e78 100644 --- a/src/Model/Constant.php +++ b/src/Model/Constant.php @@ -13,21 +13,18 @@ namespace ApiPlatform\SchemaGenerator\Model; -use EasyRdf\Resource as RdfResource; use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Constant as NetteConstant; -final class Constant +abstract class Constant { private string $name; - private RdfResource $resource; /** @var array */ private array $annotations = []; - public function __construct(string $name, RdfResource $resource) + public function __construct(string $name) { $this->name = $name; - $this->resource = $resource; } public function name(): string @@ -35,10 +32,9 @@ public function name(): string return $this->name; } - public function comment(): string - { - return (string) $this->resource->get('rdfs:comment'); - } + abstract public function value(): string; + + abstract public function comment(): string; public function addAnnotation(string $annotation): self { @@ -52,7 +48,7 @@ public function addAnnotation(string $annotation): self public function toNetteConstant(): NetteConstant { $constant = (new NetteConstant($this->name)) - ->setValue($this->resource->getUri()) + ->setValue($this->value()) ->setVisibility(ClassType::VISIBILITY_PUBLIC); foreach ($this->annotations as $annotation) { diff --git a/src/Model/Property.php b/src/Model/Property.php index d4769d68..dad3071a 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -13,26 +13,29 @@ namespace ApiPlatform\SchemaGenerator\Model; -use EasyRdf\Resource as RdfResource; use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Method; use Nette\PhpGenerator\PhpNamespace; use Nette\PhpGenerator\Property as NetteProperty; -final class Property +abstract class Property { use ResolveNameTrait; private string $name; - public ?RdfResource $resource = null; public string $cardinality; - public ?RdfResource $range = null; - public ?string $rangeName = null; + /** @var ?string the data type (array and object are not one) */ + public ?string $type = null; + /** @var ?string the array data type (object is not one) */ + public ?string $arrayType = null; + /** @var bool can be true and array type false if the property is an array of references */ + public bool $isArray = false; + public ?Class_ $reference = null; /** @var array */ public ?array $ormColumn = null; - public bool $isArray = false; public bool $isReadable = true; public bool $isWritable = true; + public bool $isRequired = false; public bool $isNullable = true; public bool $isUnique = false; public bool $isCustom = false; @@ -72,6 +75,10 @@ public function name(): string return $this->name; } + abstract public function description(): ?string; + + abstract public function rdfType(): ?string; + public function addAttribute(Attribute $attribute): self { if (!\in_array($attribute, $this->attributes, true)) { @@ -134,11 +141,6 @@ public function addRemoverAnnotation(string $annotation): self return $this; } - public function resourceUri(): ?string - { - return $this->resource ? $this->resource->getUri() : null; - } - public function markAsCustom(): self { $this->isCustom = true; diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php new file mode 100644 index 00000000..876a48e6 --- /dev/null +++ b/src/OpenApi/ClassGenerator.php @@ -0,0 +1,282 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\ClassMutator\AnnotationsAppender; +use ApiPlatform\SchemaGenerator\ClassMutator\AttributeAppender; +use ApiPlatform\SchemaGenerator\ClassMutator\ClassIdAppender; +use ApiPlatform\SchemaGenerator\ClassMutator\ClassInterfaceMutator; +use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesTypehintMutator; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Use_; +use ApiPlatform\SchemaGenerator\OpenApi\ClassMutator\EnumClassMutator as OpenApiEnumClassMutator; +use ApiPlatform\SchemaGenerator\OpenApi\Model\Class_ as OpenApiClass; +use ApiPlatform\SchemaGenerator\OpenApi\PropertyGenerator\IdPropertyGenerator; +use ApiPlatform\SchemaGenerator\OpenApi\PropertyGenerator\PropertyGenerator; +use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; +use cebe\openapi\spec\OpenApi; +use cebe\openapi\spec\RequestBody; +use cebe\openapi\spec\Schema; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; +use Psr\Log\LoggerAwareTrait; +use Symfony\Component\String\Inflector\InflectorInterface; +use function Symfony\Component\String\u; + +final class ClassGenerator +{ + use LoggerAwareTrait; + + private InflectorInterface $inflector; + private PhpTypeConverterInterface $phpTypeConverter; + private PropertyGeneratorInterface $propertyGenerator; + + public function __construct(InflectorInterface $inflector, PhpTypeConverterInterface $phpTypeConverter) + { + $this->inflector = $inflector; + $this->phpTypeConverter = $phpTypeConverter; + $this->propertyGenerator = new PropertyGenerator(); + } + + /** + * @param Configuration $config + * + * @return Class_[] + */ + public function generate(OpenApi $openApi, array $config): array + { + /** @var OpenApiClass[] $classes */ + $classes = []; + + foreach ($openApi->paths as $path => $pathItem) { + // Matches only paths like /books/{id}. + // Subresources and collection-only resources are not handled yet. + if (!preg_match('@^[^{}]+/{[^{}]+}/?$@', $path)) { + continue; + } + + $explodedPath = explode('/', rtrim($path, '/')); + $pathResourceName = $explodedPath[\count($explodedPath) - 2]; + $collectionResourceName = $this->inflector->pluralize($this->inflector->singularize($pathResourceName)[0])[0]; + $name = $this->inflector->singularize(u($pathResourceName)->camel()->title()->toString())[0]; + + $showOperation = $pathItem->get; + $editOperation = $pathItem->put ?? $pathItem->patch; + if (null === $showOperation && null === $editOperation) { + $this->logger ? $this->logger->warning(sprintf('No get, put or patch operation found for path "%s"', $path)) : null; + continue; + } + + $showSchema = null; + if ($showOperation && $showOperation->responses && null !== $responseSchema = ($showOperation->responses[200]->content['application/json']->schema ?? null)) { + $this->logger ? $this->logger->info(sprintf('Using show schema from get operation response for "%s" resource.', $name)) : null; + $showSchema = $responseSchema; + } + if (!$showSchema && $openApi->components && isset($openApi->components->schemas[$name])) { + $this->logger ? $this->logger->info(sprintf('Using "%s" show schema from components.', $name)) : null; + $showSchema = $openApi->components->schemas[$name]; + } + $editSchema = null; + if ($editOperation && $editOperation->requestBody instanceof RequestBody && null !== $requestBodySchema = ($editOperation->requestBody->content['application/json']->schema ?? null)) { + $this->logger ? $this->logger->info(sprintf('Using edit schema from put operation request body for "%s" resource.', $name)) : null; + $editSchema = $requestBodySchema; + } + if (null === $showSchema && null === $editSchema) { + $this->logger ? $this->logger->warning(sprintf('No schema found for path "%s"', $path)) : null; + continue; + } + + $showClass = null; + if ($showSchema instanceof Schema) { + $showClass = $this->buildClassFromSchema($showSchema, $name, $config); + $classes = array_merge($this->buildEnumClasses($showSchema, $showClass, $config), $classes); + } + $editClass = null; + if ($editSchema instanceof Schema) { + $editClass = $this->buildClassFromSchema($editSchema, $name, $config); + $classes = array_merge($this->buildEnumClasses($editSchema, $editClass, $config), $classes); + } + $class = $showClass ?? $editClass; + if (!$class) { + continue; + } + if ($showClass && $editClass) { + $class = $this->mergeClasses($showClass, $editClass); + } + + $putOperation = $pathItem->put; + $patchOperation = $pathItem->patch; + $deleteOperation = $pathItem->delete; + $pathCollection = $openApi->paths->getPath(sprintf('/%s', $collectionResourceName)); + $listOperation = $pathCollection->get ?? null; + $createOperation = $pathCollection->post ?? null; + $class->operations = [ + 'item' => array_merge( + $showOperation ? ['get' => null] : [], + $putOperation ? ['put' => null] : [], + $patchOperation ? ['patch' => null] : [], + $deleteOperation ? ['delete' => null] : [], + ), + 'collection' => array_merge( + $listOperation ? ['get' => null] : [], + $createOperation ? ['post' => null] : [], + ), + ]; + + $classes[$name] = $class; + } + + // Second pass + foreach ($classes as $class) { + if ($config['useInterface']) { + (new ClassInterfaceMutator($config['namespaces']['interface']))($class); + } + + if ($config['id']['generate']) { + (new ClassIdAppender(new IdPropertyGenerator(), $config))($class); + } + + // Try to guess the references from the property names. + foreach ($class->properties() as $property) { + if ($reference = $classes[preg_replace('/Ids?$/', '', $this->inflector->singularize(u($property->name())->title()->toString())[0])] ?? null) { + $property->reference = $reference; + $property->cardinality = $property->isNullable ? CardinalitiesExtractor::CARDINALITY_0_1 : CardinalitiesExtractor::CARDINALITY_1_1; + if ($property->isArray) { + $property->cardinality = $property->isNullable ? CardinalitiesExtractor::CARDINALITY_0_N : CardinalitiesExtractor::CARDINALITY_1_N; + } + } + } + } + + // Third pass + foreach ($classes as $class) { + (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class); + + // Try to guess the mapped by from the references + foreach ($class->properties() as $property) { + if ($property->reference && $property->isArray) { + $mappedByName = strtolower($class->name()); + foreach ($property->reference->properties() as $referenceProperty) { + if ($mappedByName === $referenceProperty->name()) { + $property->mappedBy = $mappedByName; + } + } + } + } + } + + // Initialize annotation generators + $annotationGenerators = []; + foreach ($config['annotationGenerators'] as $annotationGenerator) { + $generator = new $annotationGenerator($this->phpTypeConverter, $this->inflector, $config, $classes); + if (method_exists($generator, 'setLogger')) { + $generator->setLogger($this->logger); + } + + $annotationGenerators[] = $generator; + } + + // Initialize attribute generators + $attributeGenerators = []; + foreach ($config['attributeGenerators'] as $attributeGenerator) { + $generator = new $attributeGenerator($this->phpTypeConverter, $this->inflector, $config, $classes); + if (method_exists($generator, 'setLogger')) { + $generator->setLogger($this->logger); + } + + $attributeGenerators[] = $generator; + } + + foreach ($classes as $class) { + (new AnnotationsAppender($classes, $annotationGenerators, []))($class); + (new AttributeAppender($classes, $attributeGenerators))($class); + } + + return $classes; + } + + /** + * @param Configuration $config + */ + private function buildClassFromSchema(Schema $schema, string $name, array $config): OpenApiClass + { + $class = new OpenApiClass($name); + + $class->namespace = $config['namespaces']['entity']; + + if ($schema->description) { + $class->setDescription($schema->description); + } + if ($schema->externalDocs) { + $class->setRdfType($schema->externalDocs->url); + } + + foreach ($schema->properties as $propertyName => $schemaProperty) { + \assert($schemaProperty instanceof Schema); + $property = ($this->propertyGenerator)($propertyName, $config, $class, ['schema' => $schema, 'property' => $schemaProperty]); + $class->addProperty($property); + } + + if ($config['doctrine']['useCollection']) { + $class->addUse(new Use_(ArrayCollection::class)); + $class->addUse(new Use_(Collection::class)); + } + + return $class; + } + + /** + * @param Configuration $config + * + * @return OpenApiClass[] + */ + private function buildEnumClasses(Schema $schema, OpenApiClass $class, array $config): array + { + $enumClasses = []; + + foreach ($schema->properties as $propertyName => $schemaProperty) { + \assert($schemaProperty instanceof Schema); + if ($schemaProperty->enum) { + $name = $class->name().u($propertyName)->camel()->title()->toString(); + + $enumClass = new OpenApiClass($name); + (new OpenApiEnumClassMutator( + $this->phpTypeConverter, + $config['namespaces']['enum'], + $schemaProperty->enum + ))($enumClass); + $enumClasses[$name] = $enumClass; + + if ($classProperty = $class->getPropertyByName($propertyName)) { + $classProperty->reference = $enumClass; + } + } + } + + return $enumClasses; + } + + private function mergeClasses(OpenApiClass $classA, OpenApiClass $classB): OpenApiClass + { + foreach ($classB->properties() as $propertyB) { + if (!$classA->getPropertyByName($propertyB->name())) { + $classA->addProperty($propertyB); + } + } + + return $classA; + } +} diff --git a/src/OpenApi/ClassMutator/EnumClassMutator.php b/src/OpenApi/ClassMutator/EnumClassMutator.php new file mode 100644 index 00000000..b862dff3 --- /dev/null +++ b/src/OpenApi/ClassMutator/EnumClassMutator.php @@ -0,0 +1,46 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\ClassMutator; + +use ApiPlatform\SchemaGenerator\ClassMutator\EnumClassMutator as BaseEnumClassMutator; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\OpenApi\Model\Constant as OpenApiConstant; +use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; +use function Symfony\Component\String\u; + +final class EnumClassMutator extends BaseEnumClassMutator +{ + /** @var string[] */ + private array $values; + + /** + * @param string[] $values + */ + public function __construct(PhpTypeConverterInterface $phpTypeConverter, string $desiredNamespace, array $values) + { + parent::__construct($phpTypeConverter, $desiredNamespace); + + $this->values = $values; + } + + protected function addEnumConstants(Class_ $class): void + { + foreach ($this->values as $value) { + $class->addConstant($value, new OpenApiConstant( + $this->phpTypeConverter->escapeIdentifier(u($value)->snake()->upper()->toString()), + $value + )); + } + } +} diff --git a/src/OpenApi/Generator.php b/src/OpenApi/Generator.php new file mode 100644 index 00000000..68cc7614 --- /dev/null +++ b/src/OpenApi/Generator.php @@ -0,0 +1,62 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi; + +use ApiPlatform\SchemaGenerator\FilesGenerator; +use ApiPlatform\SchemaGenerator\Printer; +use ApiPlatform\SchemaGenerator\TwigBuilder; +use cebe\openapi\Reader as OpenApiReader; +use Symfony\Component\Console\Logger\ConsoleLogger; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Filesystem\Path; +use Symfony\Component\String\Inflector\EnglishInflector; + +final class Generator +{ + /** + * @param Configuration $configuration + */ + public function generate(array $configuration, string $configurationPath, OutputInterface $output, SymfonyStyle $io): void + { + if (!$openApiFile = $configuration['openApi']['file']) { + return; + } + $configurationDirectory = Path::getDirectory($configurationPath); + $openApiFilePath = Path::join($configurationDirectory, $openApiFile); + if (!$openApiFileRealPath = realpath($openApiFilePath)) { + throw new \InvalidArgumentException(sprintf('The file "%s" isn\'t readable.', $openApiFilePath)); + } + $extension = Path::getExtension($openApiFileRealPath); + if ('json' === $extension) { + $openApi = OpenApiReader::readFromJsonFile($openApiFileRealPath); + } else { + $openApi = OpenApiReader::readFromYamlFile($openApiFileRealPath); + } + + $inflector = new EnglishInflector(); + + $logger = new ConsoleLogger($output); + + $classGenerator = new ClassGenerator($inflector, new PhpTypeConverter()); + $classGenerator->setLogger($logger); + $classes = $classGenerator->generate($openApi, $configuration); + + $twig = (new TwigBuilder())->build($configuration); + + $filesGenerator = new FilesGenerator($inflector, new Printer(), $twig, $io); + $filesGenerator->setLogger($logger); + $filesGenerator->generate($classes, $configuration); + } +} diff --git a/src/OpenApi/Model/Class_.php b/src/OpenApi/Model/Class_.php new file mode 100644 index 00000000..9f3e1a90 --- /dev/null +++ b/src/OpenApi/Model/Class_.php @@ -0,0 +1,53 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\Model; + +use ApiPlatform\SchemaGenerator\Model\Class_ as BaseClass_; + +final class Class_ extends BaseClass_ +{ + private ?string $description = null; + + private ?string $rdfType = null; + + public function description(): ?string + { + return $this->description; + } + + public function setDescription(string $description): void + { + $this->description = $description; + } + + public function rdfType(): ?string + { + return $this->rdfType; + } + + public function setRdfType(string $rdfType): void + { + $this->rdfType = $rdfType; + } + + public function shortName(): string + { + return $this->name; + } + + public function isEnum(): bool + { + return false; + } +} diff --git a/src/OpenApi/Model/Constant.php b/src/OpenApi/Model/Constant.php new file mode 100644 index 00000000..0996d6ae --- /dev/null +++ b/src/OpenApi/Model/Constant.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\Model; + +use ApiPlatform\SchemaGenerator\Model\Constant as BaseConstant; + +final class Constant extends BaseConstant +{ + private ?string $comment = null; + private string $value; + + public function __construct(string $name, string $value) + { + parent::__construct($name); + + $this->value = $value; + } + + public function value(): string + { + return $this->value; + } + + public function comment(): string + { + return (string) $this->comment; + } +} diff --git a/src/OpenApi/Model/Property.php b/src/OpenApi/Model/Property.php new file mode 100644 index 00000000..0af182c1 --- /dev/null +++ b/src/OpenApi/Model/Property.php @@ -0,0 +1,43 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\Model; + +use ApiPlatform\SchemaGenerator\Model\Property as BaseProperty; + +final class Property extends BaseProperty +{ + private ?string $description = null; + + private ?string $rdfType = null; + + public function description(): ?string + { + return $this->description; + } + + public function setDescription(string $description): void + { + $this->description = $description; + } + + public function rdfType(): ?string + { + return $this->rdfType; + } + + public function setRdfType(string $rdfType): void + { + $this->rdfType = $rdfType; + } +} diff --git a/src/OpenApi/PhpTypeConverter.php b/src/OpenApi/PhpTypeConverter.php new file mode 100644 index 00000000..07f5b208 --- /dev/null +++ b/src/OpenApi/PhpTypeConverter.php @@ -0,0 +1,68 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi; + +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; +use EasyRdf\Resource as RdfResource; + +final class PhpTypeConverter implements PhpTypeConverterInterface +{ + public function isDatatype(RdfResource $range): bool + { + return true; + } + + public function getPhpType(Property $property, array $config = [], array $classes = []): ?string + { + if ($property->reference && $property->isArray) { + return ($config['doctrine']['useCollection'] ?? false) ? 'Collection' : 'array'; + } + + if ($property->reference && !$property->isArray) { + return $property->reference->name(); + } + + if ($property->isArray) { + return 'array'; + } + + /* @see https://swagger.io/specification/#data-types */ + switch ($property->type) { + case 'integer': + return 'int'; + case 'boolean': + return 'bool'; + case 'float': + case 'double': + return 'float'; + case 'date': + case 'dateTime': + return '\\'.\DateTimeInterface::class; + default: + return 'string'; + } + } + + public function escapeIdentifier(string $identifier): string + { + foreach (self::RESERVED_KEYWORDS as $keyword) { + if (0 === strcasecmp($keyword, $identifier)) { + return $identifier.'_'; + } + } + + return $identifier; + } +} diff --git a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php new file mode 100644 index 00000000..73d7ee94 --- /dev/null +++ b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\PropertyGenerator; + +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\OpenApi\Model\Property as OpenApiProperty; +use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGenerator as CommonIdPropertyGenerator; +use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGeneratorInterface; + +final class IdPropertyGenerator implements IdPropertyGeneratorInterface +{ + private IdPropertyGeneratorInterface $idPropertyGenerator; + + public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = null) + { + $this->idPropertyGenerator = $idPropertyGenerator ?? new CommonIdPropertyGenerator(); + } + + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property + { + return ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new OpenApiProperty('id')); + } +} diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php new file mode 100644 index 00000000..bd40d5ac --- /dev/null +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -0,0 +1,90 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\PropertyGenerator; + +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\OpenApi\Model\Property as OpenApiProperty; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator as CommonPropertyGenerator; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; +use cebe\openapi\spec\Schema; +use function Symfony\Component\String\u; + +final class PropertyGenerator implements PropertyGeneratorInterface +{ + private PropertyGeneratorInterface $propertyGenerator; + + public function __construct(?PropertyGeneratorInterface $propertyGenerator = null) + { + $this->propertyGenerator = $propertyGenerator ?? new CommonPropertyGenerator(); + } + + /** + * @param Configuration $config + * @param array{schema: Schema, property: Schema} $context + */ + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property + { + $schema = $context['schema']; + $schemaProperty = $context['property']; + + $openApiProperty = new OpenApiProperty($name); + $openApiProperty->isArray = 'array' === $schemaProperty->type; + + $openApiProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $openApiProperty); + + if (!$openApiProperty instanceof OpenApiProperty) { + throw new \LogicException(sprintf('Property has to be an instance of "%s".', OpenApiProperty::class)); + } + + $requiredFields = $schema->required ?? []; + + $openApiProperty->type = $this->getType($schemaProperty->type, $schemaProperty->format); + $openApiProperty->arrayType = $openApiProperty->isArray && $schemaProperty->items instanceof Schema + ? $this->getType($schemaProperty->items->type, $schemaProperty->items->format) + : null; + if ($schemaProperty->description) { + $openApiProperty->setDescription($schemaProperty->description); + } + if ($schemaProperty->externalDocs) { + $openApiProperty->setRdfType($schemaProperty->externalDocs->url); + } + $openApiProperty->isNullable = $schemaProperty->nullable ?? false; + $openApiProperty->isRequired = \in_array($name, $requiredFields, true); + $openApiProperty->isReadable = !$schemaProperty->writeOnly; + $openApiProperty->isWritable = !$schemaProperty->readOnly; + $openApiProperty->isEnum = (bool) $schemaProperty->enum; + + return $openApiProperty; + } + + private function getType(string $type, ?string $format): ?string + { + if ($format) { + switch ($format) { + case 'int32': + case 'int64': + return 'integer'; + default: + return u(str_replace('-', '_', $format))->camel()->toString(); + } + } + + if (\in_array($type, ['array', 'object'], true)) { + return null; + } + + return $type; + } +} diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index c0bd8026..7ac6e714 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -15,6 +15,8 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\Schema\TypeConverter; use EasyRdf\Resource as RdfResource; final class PhpTypeConverter implements PhpTypeConverterInterface @@ -24,11 +26,15 @@ final class PhpTypeConverter implements PhpTypeConverterInterface */ public function isDatatype(RdfResource $range): bool { - return isset(PhpTypeConverterInterface::BASE_MAPPING[$this->getUri($range)]) || $this->isLangString($range); + return isset(TypeConverter::RANGE_MAPPING[$this->getUri($range)]) || $this->isLangString($range); } public function getPhpType(Property $property, array $config = [], array $classes = []): ?string { + if (!$property instanceof SchemaProperty) { + throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); + } + if ($property->isArray && $property->range) { return ($config['doctrine']['useCollection'] ?? false) && !$this->isDatatype($property->range) ? 'Collection' : 'array'; } @@ -50,7 +56,7 @@ public function escapeIdentifier(string $identifier): string /** * @param Class_[] $classes */ - private function getNonArrayType(Property $property, array $classes): ?string + private function getNonArrayType(SchemaProperty $property, array $classes): ?string { if ($property->isEnum) { return 'string'; @@ -60,9 +66,32 @@ private function getNonArrayType(Property $property, array $classes): ?string return null; } - $rangeUri = $this->getUri($property->range); - if (isset(PhpTypeConverterInterface::BASE_MAPPING[$rangeUri])) { - return PhpTypeConverterInterface::BASE_MAPPING[$rangeUri]; + if ($property->type) { + switch ($property->type) { + case 'integer': + case 'negativeInteger': + case 'nonNegativeInteger': + case 'positiveInteger': + case 'nonPositiveInteger': + case 'byte': + return 'int'; + case 'boolean': + return 'bool'; + case 'float': + case 'double': + case 'decimal': + return 'float'; + case 'date': + case 'dateTime': + case 'time': + return '\\'.\DateTimeInterface::class; + case 'duration': + return '\\'.\DateInterval::class; + case 'mixed': + return null; + default: + return 'string'; + } } $typeName = $property->rangeName; diff --git a/src/PhpTypeConverterInterface.php b/src/PhpTypeConverterInterface.php index 50ea0581..d588849f 100644 --- a/src/PhpTypeConverterInterface.php +++ b/src/PhpTypeConverterInterface.php @@ -19,69 +19,6 @@ interface PhpTypeConverterInterface { - public const BASE_MAPPING = [ - // bool - 'http://www.w3.org/2001/XMLSchema#boolean' => 'bool', - 'https://schema.org/Boolean' => 'bool', - // float - 'http://www.w3.org/2001/XMLSchema#float' => 'float', - 'http://www.w3.org/2001/XMLSchema#double' => 'float', - 'https://schema.org/Float' => 'float', - // int - 'https://schema.org/Integer' => 'int', - 'http://www.w3.org/2001/XMLSchema#integer' => 'int', - 'http://www.w3.org/2001/XMLSchema#nonPositiveInteger' => 'int', - 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger' => 'int', - 'http://www.w3.org/2001/XMLSchema#long' => 'int', - 'http://www.w3.org/2001/XMLSchema#int' => 'int', - 'http://www.w3.org/2001/XMLSchema#short' => 'int', - 'http://www.w3.org/2001/XMLSchema#byte' => 'int', - 'http://www.w3.org/2001/XMLSchema#unsignedLong' => 'int', - 'http://www.w3.org/2001/XMLSchema#positiveInteger' => 'int', - 'http://www.w3.org/2001/XMLSchema#unsignedInt' => 'int', - 'http://www.w3.org/2001/XMLSchema#unsignedShort' => 'int', - 'http://www.w3.org/2001/XMLSchema#unsignedByte' => 'int', - // string - 'http://www.w3.org/2001/XMLSchema#string' => 'string', - 'http://www.w3.org/2001/XMLSchema#hexBinary' => 'string', - 'http://www.w3.org/2001/XMLSchema#base64Binary' => 'string', - 'http://www.w3.org/2001/XMLSchema#anyURI' => 'string', - 'http://www.w3.org/2001/XMLSchema#QName' => 'string', - 'http://www.w3.org/2001/XMLSchema#NOTATION' => 'string', - 'http://www.w3.org/2001/XMLSchema#decimal' => 'string', - 'http://www.w3.org/2001/XMLSchema#normalizedString' => 'string', - 'http://www.w3.org/2001/XMLSchema#token' => 'string', - 'http://www.w3.org/2001/XMLSchema#language' => 'string', - 'http://www.w3.org/2001/XMLSchema#NMTOKEN' => 'string', - 'http://www.w3.org/2001/XMLSchema#NMTOKENS' => 'string', - 'http://www.w3.org/2001/XMLSchema#Name' => 'string', - 'http://www.w3.org/2001/XMLSchema#NCName' => 'string', - 'http://www.w3.org/2001/XMLSchema#ID' => 'string', - 'http://www.w3.org/2001/XMLSchema#IDREF' => 'string', - 'http://www.w3.org/2001/XMLSchema#IDREFS' => 'string', - 'http://www.w3.org/2001/XMLSchema#ENTITY' => 'string', - 'http://www.w3.org/2001/XMLSchema#ENTITIES' => 'string', - 'https://schema.org/Text' => 'string', - 'https://schema.org/URL' => 'string', - 'https://schema.org/Number' => 'string', - // DateTimeInterface - 'http://www.w3.org/2001/XMLSchema#dateTime' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#time' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#date' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#gYearMonth' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#gYear' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#gMonthDay' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#gDay' => '\\'.\DateTimeInterface::class, - 'http://www.w3.org/2001/XMLSchema#gMonth' => '\\'.\DateTimeInterface::class, - 'https://schema.org/Date' => '\\'.\DateTimeInterface::class, - 'https://schema.org/DateTime' => '\\'.\DateTimeInterface::class, - 'https://schema.org/Time' => '\\'.\DateTimeInterface::class, - // DateInterval - 'http://www.w3.org/2001/XMLSchema#duration' => '\\'.\DateInterval::class, - // mixed - 'https://schema.org/DataType' => null, - ]; - /** * @internal */ diff --git a/src/PropertyGenerator/IdPropertyGenerator.php b/src/PropertyGenerator/IdPropertyGenerator.php index ceefcf1c..98aafcbb 100644 --- a/src/PropertyGenerator/IdPropertyGenerator.php +++ b/src/PropertyGenerator/IdPropertyGenerator.php @@ -15,42 +15,42 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Property; -use EasyRdf\Resource as RdfResource; -final class IdPropertyGenerator +final class IdPropertyGenerator implements IdPropertyGeneratorInterface { - public function __invoke(string $generationStrategy, bool $supportsWritableId): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property { + if (!$property) { + throw new \LogicException('A property must be given.'); + } + switch ($generationStrategy) { case 'auto': - $uri = 'https://schema.org/Integer'; + $type = 'integer'; $typeHint = 'int'; $writable = false; $nullable = true; break; case 'uuid': - $uri = 'https://schema.org/Text'; + $type = 'string'; $typeHint = 'string'; $writable = $supportsWritableId; $nullable = !$writable; break; case 'mongoid': - $uri = 'https://schema.org/Text'; + $type = 'string'; $typeHint = 'string'; $writable = false; $nullable = true; break; default: - $uri = 'https://schema.org/Text'; + $type = 'string'; $typeHint = 'string'; $writable = true; $nullable = false; break; } - $property = new Property('id'); - $property->rangeName = 'Text'; - $property->range = new RdfResource($uri); $property->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $property->ormColumn = null; $property->isWritable = $writable; @@ -58,6 +58,7 @@ public function __invoke(string $generationStrategy, bool $supportsWritableId): $property->isUnique = false; $property->isCustom = true; $property->isId = true; + $property->type = $type; $property->typeHint = $typeHint; return $property; diff --git a/src/PropertyGenerator/IdPropertyGeneratorInterface.php b/src/PropertyGenerator/IdPropertyGeneratorInterface.php new file mode 100644 index 00000000..77b16ca8 --- /dev/null +++ b/src/PropertyGenerator/IdPropertyGeneratorInterface.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\PropertyGenerator; + +use ApiPlatform\SchemaGenerator\Model\Property; + +interface IdPropertyGeneratorInterface +{ + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property; +} diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index e810f3de..fbdbc146 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -13,189 +13,27 @@ namespace ApiPlatform\SchemaGenerator\PropertyGenerator; -use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; -use ApiPlatform\SchemaGenerator\GoodRelationsBridge; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; -use ApiPlatform\SchemaGenerator\Model\Use_; -use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use Doctrine\Common\Collections\ArrayCollection; -use Doctrine\Common\Collections\Collection; -use EasyRdf\Resource as RdfResource; -use Psr\Log\LoggerInterface; -final class PropertyGenerator +final class PropertyGenerator implements PropertyGeneratorInterface { - /** @var string[] */ - private static array $rangeProperties = [ - 'schema:rangeIncludes', - 'rdfs:range', - ]; - - private GoodRelationsBridge $goodRelationsBridge; - private LoggerInterface $logger; - private PhpTypeConverterInterface $phpTypeConverter; - /** @var array */ - private array $cardinalities; - /** - * @param array $cardinalities - */ - public function __construct(GoodRelationsBridge $goodRelationsBridge, PhpTypeConverterInterface $phpTypeConverter, $cardinalities, LoggerInterface $logger) - { - $this->goodRelationsBridge = $goodRelationsBridge; - $this->phpTypeConverter = $phpTypeConverter; - $this->cardinalities = $cardinalities; - $this->logger = $logger; - } - - /** - * @param Configuration $config - * @param ?TypeConfiguration $typeConfig + * @param Configuration $config + * @param array{} $context */ - public function __invoke(array $config, Class_ $class, RdfResource $type, ?array $typeConfig, RdfResource $property, bool $isCustom = false): Class_ + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property { - $typeUri = $type->getUri(); - $propertyName = $property->localName(); - $propertyUri = $property->getUri(); - - // Warn when property are not part of GoodRelations - if ($config['checkIsGoodRelations'] && !$this->goodRelationsBridge->exists($propertyName)) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyUri, $typeUri)); - } - - // Warn when properties are legacy - if (preg_match('/legacy spelling/', (string) $property->get('rdfs:comment'))) { - $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyUri, $typeUri)); + if (!$property) { + throw new \LogicException('A property must be given.'); } - $propertyConfig = $typeConfig['properties'][$propertyName] ?? []; - - $ranges = []; - foreach (self::$rangeProperties as $rangePropertyType) { - /** @var RdfResource $range */ - foreach ($property->all($rangePropertyType, 'resource') as $range) { - $ranges[] = $this->getRanges($range, $propertyConfig, $config); - } - } - $ranges = array_merge(...$ranges); - - if (!$ranges) { - if (isset($propertyConfig['range'])) { - $ranges[] = new RdfResource($propertyConfig['range'], $type->getGraph()); - } else { - $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyUri, $typeUri)); - } - } - - if (\count($ranges) > 1) { - $this->logger->warning(sprintf('The property "%s" (type "%s") has several types. Using the first one ("%s"). Other possible options: "%s".', $propertyUri, $typeUri, $ranges[0]->getUri(), implode('", "', array_map(static fn (RdfResource $range) => $range->getUri(), $ranges)))); - } - - $rangeName = null; - $range = null; - if (isset($ranges[0])) { - $range = $ranges[0]; - if (!isset($propertyConfig['range']) && $mappedUri = ($config['rangeMapping'][$ranges[0]->getUri()] ?? false)) { - $range = new RdfResource($mappedUri); - } - - $rangeName = $this->phpTypeConverter->escapeIdentifier($range->localName()); - } - - if (!$ranges) { - return $class; - } + $property->isCustom = $isCustom; - $cardinality = $propertyConfig['cardinality'] ?? false; - if (!$cardinality || CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { - $cardinality = $this->cardinalities[$propertyUri] ?? CardinalitiesExtractor::CARDINALITY_1_1; - } - - $isArray = \in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_0_N, - CardinalitiesExtractor::CARDINALITY_1_N, - CardinalitiesExtractor::CARDINALITY_N_N, - ], true); - - $isNullable = (bool) ($propertyConfig['nullable'] ?? !\in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_1_1, - CardinalitiesExtractor::CARDINALITY_1_N, - ], true)); - - $columnPrefix = false; - $isEmbedded = $propertyConfig['embedded'] ?? false; - - if (true === $isEmbedded) { - $columnPrefix = $propertyConfig['columnPrefix'] ?? false; - } - - $schemaGeneratorProperty = new Property($propertyName); - $schemaGeneratorProperty->resource = $property; - $schemaGeneratorProperty->rangeName = $rangeName; - $schemaGeneratorProperty->range = $range; - $schemaGeneratorProperty->cardinality = $cardinality; - $schemaGeneratorProperty->ormColumn = $propertyConfig['ormColumn'] ?? null; - $schemaGeneratorProperty->isArray = $isArray; - $schemaGeneratorProperty->isReadable = $propertyConfig['readable'] ?? true; - $schemaGeneratorProperty->isWritable = $propertyConfig['writable'] ?? true; - $schemaGeneratorProperty->isNullable = $isNullable; - $schemaGeneratorProperty->isUnique = $propertyConfig['unique'] ?? false; - $schemaGeneratorProperty->isCustom = $isCustom; - $schemaGeneratorProperty->isEmbedded = $isEmbedded; - $schemaGeneratorProperty->columnPrefix = $columnPrefix; - $schemaGeneratorProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; - $schemaGeneratorProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; - $schemaGeneratorProperty->groups = $propertyConfig['groups'] ?? []; - $schemaGeneratorProperty->security = $propertyConfig['security'] ?? null; - $schemaGeneratorProperty->isId = false; - $class->addProperty($schemaGeneratorProperty); - - if ($isArray) { + if ($property->isArray) { $class->hasConstructor = true; - - if ($config['doctrine']['useCollection']) { - $class->addUse(new Use_(ArrayCollection::class)); - $class->addUse(new Use_(Collection::class)); - } - } - - return $class; - } - - /** - * @param PropertyConfiguration|array{} $propertyConfig - * @param Configuration $config - * - * @return RdfResource[] - */ - private function getRanges(RdfResource $range, array $propertyConfig, array $config): array - { - $localName = $range->localName(); - $dataType = $this->phpTypeConverter->isDatatype($range); - $ranges = []; - if (!$dataType && $range->isBNode()) { - if (null !== ($unionOf = $range->get('owl:unionOf'))) { - return $this->getRanges($unionOf, $propertyConfig, $config); - } - - if (null !== ($rdfFirst = $range->get('rdf:first'))) { - $ranges = $this->getRanges($rdfFirst, $propertyConfig, $config); - if (null !== ($rdfRest = $range->get('rdf:rest'))) { - $ranges = array_merge($ranges, $this->getRanges($rdfRest, $propertyConfig, $config)); - } - } - - return $ranges; - } - - if ( - (!isset($propertyConfig['range']) || $propertyConfig['range'] === $localName) && - (empty($config['types']) || isset($config['types'][$localName]) || $dataType) - ) { - return [$range]; } - return []; + return $property; } } diff --git a/src/PropertyGenerator/PropertyGeneratorInterface.php b/src/PropertyGenerator/PropertyGeneratorInterface.php new file mode 100644 index 00000000..a2e80811 --- /dev/null +++ b/src/PropertyGenerator/PropertyGeneratorInterface.php @@ -0,0 +1,33 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\PropertyGenerator; + +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; + +interface PropertyGeneratorInterface +{ + /** + * @param Configuration $config + */ + // @phpstan-ignore-next-line + public function __invoke( + string $name, + array $config, + Class_ $class, + array $context, + bool $isCustom = false, + ?Property $property = null + ): Property; +} diff --git a/src/Schema/ClassMutator/EnumClassMutator.php b/src/Schema/ClassMutator/EnumClassMutator.php new file mode 100644 index 00000000..eb0ef2df --- /dev/null +++ b/src/Schema/ClassMutator/EnumClassMutator.php @@ -0,0 +1,54 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\ClassMutator; + +use ApiPlatform\SchemaGenerator\ClassMutator\EnumClassMutator as BaseEnumClassMutator; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; +use ApiPlatform\SchemaGenerator\Schema\Model\Constant as SchemaConstant; +use EasyRdf\Graph as RdfGraph; + +final class EnumClassMutator extends BaseEnumClassMutator +{ + /** + * @var RdfGraph[] + */ + private array $graphs; + + /** + * @param RdfGraph[] $graphs + */ + public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $graphs, string $desiredNamespace) + { + parent::__construct($phpTypeConverter, $desiredNamespace); + + $this->graphs = $graphs; + } + + protected function addEnumConstants(Class_ $class): void + { + if (!$class->rdfType()) { + return; + } + + foreach ($this->graphs as $graph) { + foreach ($graph->allOfType($class->rdfType()) as $instance) { + $class->addConstant($instance->localName(), new SchemaConstant( + $this->phpTypeConverter->escapeIdentifier(strtoupper(substr(preg_replace('/([A-Z])/', '_$1', $instance->localName()), 1))), + $instance + )); + } + } + } +} diff --git a/src/Schema/Generator.php b/src/Schema/Generator.php new file mode 100644 index 00000000..e5400bb6 --- /dev/null +++ b/src/Schema/Generator.php @@ -0,0 +1,77 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\FilesGenerator; +use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Printer; +use ApiPlatform\SchemaGenerator\TwigBuilder; +use ApiPlatform\SchemaGenerator\TypesGenerator; +use EasyRdf\Graph as RdfGraph; +use Symfony\Component\Console\Logger\ConsoleLogger; +use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\String\Inflector\EnglishInflector; + +final class Generator +{ + /** + * @param Configuration $configuration + */ + public function generate(array $configuration, OutputInterface $output, SymfonyStyle $io): void + { + $graphs = []; + foreach ($configuration['vocabularies'] as $vocab) { + $graph = new RdfGraph(); + if (0 === strpos($vocab['uri'], 'http://') || 0 === strpos($vocab['uri'], 'https://')) { + $graph->load($vocab['uri'], $vocab['format']); + } else { + $graph->parseFile($vocab['uri'], $vocab['format']); + } + + $graphs[] = $graph; + } + + $relations = []; + foreach ($configuration['relations'] as $relation) { + $relations[] = new \SimpleXMLElement($relation, 0, true); + } + + $goodRelationsBridge = new GoodRelationsBridge($relations); + $cardinalitiesExtractor = new CardinalitiesExtractor($graphs, $goodRelationsBridge); + + $inflector = new EnglishInflector(); + + $logger = new ConsoleLogger($output); + + $entitiesGenerator = new TypesGenerator( + $inflector, + $graphs, + new PhpTypeConverter(), + $cardinalitiesExtractor, + $goodRelationsBridge + ); + $entitiesGenerator->setLogger($logger); + + $classes = $entitiesGenerator->generate($configuration); + + $twig = (new TwigBuilder())->build($configuration); + + $filesGenerator = new FilesGenerator($inflector, new Printer(), $twig, $io); + $filesGenerator->setLogger($logger); + $filesGenerator->generate($classes, $configuration); + } +} diff --git a/src/Schema/Model/Class_.php b/src/Schema/Model/Class_.php new file mode 100644 index 00000000..2d4a1d5d --- /dev/null +++ b/src/Schema/Model/Class_.php @@ -0,0 +1,71 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\Model; + +use ApiPlatform\SchemaGenerator\Model\Class_ as BaseClass_; +use EasyRdf\Resource as RdfResource; + +final class Class_ extends BaseClass_ +{ + private RdfResource $resource; + + private const SCHEMA_ORG_ENUMERATION = 'https://schema.org/Enumeration'; + + /** + * @param false|string|null $parent + */ + public function __construct(string $name, RdfResource $resource, $parent = null) + { + parent::__construct($name, $parent); + + $this->resource = $resource; + } + + public function resource(): RdfResource + { + return $this->resource; + } + + public function rdfType(): string + { + return $this->resource->getUri(); + } + + public function description(): ?string + { + $comment = $this->resource->get('rdfs:comment'); + + return $comment ? (string) $comment : null; + } + + public function shortName(): string + { + return $this->resource->localName(); + } + + /** + * @return RdfResource[] + */ + public function getSubClassOf(): array + { + return array_filter($this->resource->all('rdfs:subClassOf', 'resource'), static fn (RdfResource $resource) => !$resource->isBNode()); + } + + public function isEnum(): bool + { + $subClassOf = $this->resource->get('rdfs:subClassOf'); + + return $subClassOf && self::SCHEMA_ORG_ENUMERATION === $subClassOf->getUri(); + } +} diff --git a/src/Schema/Model/Constant.php b/src/Schema/Model/Constant.php new file mode 100644 index 00000000..f173157b --- /dev/null +++ b/src/Schema/Model/Constant.php @@ -0,0 +1,39 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\Model; + +use ApiPlatform\SchemaGenerator\Model\Constant as BaseConstant; +use EasyRdf\Resource as RdfResource; + +final class Constant extends BaseConstant +{ + private RdfResource $resource; + + public function __construct(string $name, RdfResource $resource) + { + parent::__construct($name); + + $this->resource = $resource; + } + + public function comment(): string + { + return (string) $this->resource->get('rdfs:comment'); + } + + public function value(): string + { + return $this->resource->getUri(); + } +} diff --git a/src/Schema/Model/Property.php b/src/Schema/Model/Property.php new file mode 100644 index 00000000..4c9a49f4 --- /dev/null +++ b/src/Schema/Model/Property.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\Model; + +use ApiPlatform\SchemaGenerator\Model\Property as BaseProperty; +use EasyRdf\Resource as RdfResource; + +final class Property extends BaseProperty +{ + public ?RdfResource $resource = null; + + public ?RdfResource $range = null; + + public ?string $rangeName = null; + + public function description(): ?string + { + if ($this->resource && $comment = $this->resource->get('rdfs:comment')) { + return (string) $comment; + } + + return null; + } + + public function rdfType(): ?string + { + if ($this->resource) { + return $this->resource->getUri(); + } + + return null; + } +} diff --git a/src/Schema/PropertyGenerator/IdPropertyGenerator.php b/src/Schema/PropertyGenerator/IdPropertyGenerator.php new file mode 100644 index 00000000..e78e6816 --- /dev/null +++ b/src/Schema/PropertyGenerator/IdPropertyGenerator.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\PropertyGenerator; + +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGenerator as CommonIdPropertyGenerator; +use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGeneratorInterface; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use EasyRdf\Resource as RdfResource; + +final class IdPropertyGenerator implements IdPropertyGeneratorInterface +{ + private IdPropertyGeneratorInterface $idPropertyGenerator; + + public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = null) + { + $this->idPropertyGenerator = $idPropertyGenerator ?? new CommonIdPropertyGenerator(); + } + + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property + { + $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new SchemaProperty('id')); + + if (!$idProperty instanceof SchemaProperty) { + throw new \LogicException(sprintf('ID property has to be an instance of "%s".', SchemaProperty::class)); + } + + $rangeName = 'Text'; + $uri = 'https://schema.org/Text'; + if ('auto' === $generationStrategy) { + $rangeName = 'Integer'; + $uri = 'https://schema.org/Integer'; + } + $idProperty->rangeName = $rangeName; + $idProperty->range = new RdfResource($uri); + + return $idProperty; + } +} diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php new file mode 100644 index 00000000..fb930980 --- /dev/null +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -0,0 +1,210 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\PropertyGenerator; + +use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator as CommonPropertyGenerator; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\Schema\TypeConverter; +use EasyRdf\Resource as RdfResource; +use Psr\Log\LoggerAwareTrait; + +final class PropertyGenerator implements PropertyGeneratorInterface +{ + use LoggerAwareTrait; + + /** @var string[] */ + private static array $rangeProperties = [ + 'schema:rangeIncludes', + 'rdfs:range', + ]; + + private GoodRelationsBridge $goodRelationsBridge; + private PhpTypeConverterInterface $phpTypeConverter; + /** @var array */ + private array $cardinalities; + private TypeConverter $typeConverter; + private PropertyGeneratorInterface $propertyGenerator; + + /** + * @param array $cardinalities + */ + public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, array $cardinalities, ?PropertyGeneratorInterface $propertyGenerator = null) + { + $this->goodRelationsBridge = $goodRelationsBridge; + $this->typeConverter = $typeConverter; + $this->phpTypeConverter = $phpTypeConverter; + $this->cardinalities = $cardinalities; + $this->propertyGenerator = $propertyGenerator ?? new CommonPropertyGenerator(); + } + + /** + * @param Configuration $config + * @param array{ + * type: RdfResource, + * typeConfig: ?TypeConfiguration, + * property: RdfResource + * } $context + */ + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property + { + $type = $context['type']; + $typeConfig = $context['typeConfig']; + $typeProperty = $context['property']; + + $typeUri = $type->getUri(); + $propertyUri = $typeProperty->getUri(); + + $propertyConfig = $typeConfig['properties'][$name] ?? null; + + $cardinality = $propertyConfig['cardinality'] ?? false; + if (!$cardinality || CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { + $cardinality = $this->cardinalities[$propertyUri] ?? CardinalitiesExtractor::CARDINALITY_1_1; + } + + $isArray = \in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_0_N, + CardinalitiesExtractor::CARDINALITY_1_N, + CardinalitiesExtractor::CARDINALITY_N_N, + ], true); + + $schemaProperty = new SchemaProperty($name); + $schemaProperty->isArray = $isArray; + + $schemaProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $schemaProperty); + + if (!$schemaProperty instanceof SchemaProperty) { + throw new \LogicException(sprintf('Property has to be an instance of "%s".', SchemaProperty::class)); + } + + // Warn when property are not part of GoodRelations + if ($config['checkIsGoodRelations'] && !$this->goodRelationsBridge->exists($name)) { + $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyUri, $typeUri)) : null; + } + + // Warn when properties are legacy + if (preg_match('/legacy spelling/', (string) $typeProperty->get('rdfs:comment'))) { + $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyUri, $typeUri)) : null; + } + + $ranges = []; + foreach (self::$rangeProperties as $rangePropertyType) { + /** @var RdfResource $range */ + foreach ($typeProperty->all($rangePropertyType, 'resource') as $range) { + $ranges[] = $this->getRanges($range, $propertyConfig, $config); + } + } + $ranges = array_merge(...$ranges); + + if (!$ranges) { + if (isset($propertyConfig['range'])) { + $ranges[] = new RdfResource($propertyConfig['range'], $type->getGraph()); + } else { + $this->logger ? $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyUri, $typeUri)) : null; + } + } + + if (\count($ranges) > 1) { + $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") has several types. Using the first one ("%s"). Other possible options: "%s".', $propertyUri, $typeUri, $ranges[0]->getUri(), implode('", "', array_map(static fn (RdfResource $range) => $range->getUri(), $ranges)))) : null; + } + + $rangeName = null; + $range = null; + if (isset($ranges[0])) { + $range = $ranges[0]; + if (!isset($propertyConfig['range']) && $mappedUri = ($config['rangeMapping'][$ranges[0]->getUri()] ?? false)) { + $range = new RdfResource($mappedUri); + } + + $rangeName = $this->phpTypeConverter->escapeIdentifier($range->localName()); + } + + if (!$ranges) { + return $schemaProperty; + } + + $isNullable = (bool) ($propertyConfig['nullable'] ?? !\in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_1_1, + CardinalitiesExtractor::CARDINALITY_1_N, + ], true)); + + $columnPrefix = false; + $isEmbedded = $propertyConfig['embedded'] ?? false; + + if (true === $isEmbedded) { + $columnPrefix = $propertyConfig['columnPrefix'] ?? false; + } + + $schemaProperty->resource = $typeProperty; + $schemaProperty->range = $range; + $schemaProperty->rangeName = $rangeName; + $schemaProperty->type = $this->typeConverter->getType($range); + $schemaProperty->cardinality = $cardinality; + $schemaProperty->ormColumn = $propertyConfig['ormColumn'] ?? null; + $schemaProperty->isReadable = $propertyConfig['readable'] ?? true; + $schemaProperty->isWritable = $propertyConfig['writable'] ?? true; + $schemaProperty->isNullable = $isNullable; + $schemaProperty->isRequired = $propertyConfig['required'] ?? false; + $schemaProperty->isUnique = $propertyConfig['unique'] ?? false; + $schemaProperty->isEmbedded = $isEmbedded; + $schemaProperty->columnPrefix = $columnPrefix; + $schemaProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; + $schemaProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; + $schemaProperty->groups = $propertyConfig['groups'] ?? []; + $schemaProperty->security = $propertyConfig['security'] ?? null; + + return $schemaProperty; + } + + /** + * @param ?PropertyConfiguration $propertyConfig + * @param Configuration $config + * + * @return RdfResource[] + */ + private function getRanges(RdfResource $range, ?array $propertyConfig, array $config): array + { + $localName = $range->localName(); + $dataType = $this->phpTypeConverter->isDatatype($range); + $ranges = []; + if (!$dataType && $range->isBNode()) { + if (null !== ($unionOf = $range->get('owl:unionOf'))) { + return $this->getRanges($unionOf, $propertyConfig, $config); + } + + if (null !== ($rdfFirst = $range->get('rdf:first'))) { + $ranges = $this->getRanges($rdfFirst, $propertyConfig, $config); + if (null !== ($rdfRest = $range->get('rdf:rest'))) { + $ranges = array_merge($ranges, $this->getRanges($rdfRest, $propertyConfig, $config)); + } + } + + return $ranges; + } + + if ( + (!isset($propertyConfig['range']) || $propertyConfig['range'] === $localName) && + (empty($config['types']) || isset($config['types'][$localName]) || $dataType) + ) { + return [$range]; + } + + return []; + } +} diff --git a/src/Schema/TypeConverter.php b/src/Schema/TypeConverter.php new file mode 100644 index 00000000..fc789818 --- /dev/null +++ b/src/Schema/TypeConverter.php @@ -0,0 +1,112 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema; + +use EasyRdf\Resource as RdfResource; + +final class TypeConverter +{ + public const RANGE_MAPPING = [ + 'https://schema.org/URL' => 'url', + + 'https://schema.org/Boolean' => 'boolean', + 'http://www.w3.org/2001/XMLSchema#boolean' => 'boolean', + + 'https://schema.org/Float' => 'float', + 'http://www.w3.org/2001/XMLSchema#float' => 'float', + + 'http://www.w3.org/2001/XMLSchema#double' => 'double', + + 'https://schema.org/Integer' => 'integer', + 'http://www.w3.org/2001/XMLSchema#integer' => 'integer', + 'http://www.w3.org/2001/XMLSchema#int' => 'integer', + 'http://www.w3.org/2001/XMLSchema#long' => 'integer', + 'http://www.w3.org/2001/XMLSchema#short' => 'integer', + + 'http://www.w3.org/2001/XMLSchema#negativeInteger' => 'negativeInteger', + + 'http://www.w3.org/2001/XMLSchema#nonNegativeInteger' => 'nonNegativeInteger', + 'http://www.w3.org/2001/XMLSchema#unsignedInt' => 'nonNegativeInteger', + 'http://www.w3.org/2001/XMLSchema#unsignedShort' => 'nonNegativeInteger', + 'http://www.w3.org/2001/XMLSchema#unsignedLong' => 'nonNegativeInteger', + + 'http://www.w3.org/2001/XMLSchema#positiveInteger' => 'positiveInteger', + + 'http://www.w3.org/2001/XMLSchema#nonPositiveInteger' => 'nonPositiveInteger', + + 'http://www.w3.org/2001/XMLSchema#decimal' => 'decimal', + + 'https://schema.org/Date' => 'date', + 'http://www.w3.org/2001/XMLSchema#date' => 'date', + 'http://www.w3.org/2001/XMLSchema#gYearMonth' => 'date', + 'http://www.w3.org/2001/XMLSchema#gYear' => 'date', + 'http://www.w3.org/2001/XMLSchema#gMonthDay' => 'date', + 'http://www.w3.org/2001/XMLSchema#gDay' => 'date', + 'http://www.w3.org/2001/XMLSchema#gMonth' => 'date', + + 'https://schema.org/DateTime' => 'dateTime', + 'http://www.w3.org/2001/XMLSchema#dateTime' => 'dateTime', + + 'http://www.w3.org/2001/XMLSchema#duration' => 'duration', + + 'https://schema.org/Time' => 'time', + 'http://www.w3.org/2001/XMLSchema#time' => 'time', + + 'http://www.w3.org/2001/XMLSchema#byte' => 'byte', + 'http://www.w3.org/2001/XMLSchema#unsignedByte' => 'byte', + + 'http://www.w3.org/2001/XMLSchema#hexBinary' => 'hexBinary', + + 'http://www.w3.org/2001/XMLSchema#base64Binary' => 'base64Binary', + + 'https://schema.org/Text' => 'string', + 'https://schema.org/Number' => 'string', + 'http://www.w3.org/2001/XMLSchema#string' => 'string', + 'http://www.w3.org/2001/XMLSchema#anyURI' => 'string', + 'http://www.w3.org/2001/XMLSchema#QName' => 'string', + 'http://www.w3.org/2001/XMLSchema#NOTATION' => 'string', + 'http://www.w3.org/2001/XMLSchema#normalizedString' => 'string', + 'http://www.w3.org/2001/XMLSchema#token' => 'string', + 'http://www.w3.org/2001/XMLSchema#language' => 'string', + 'http://www.w3.org/2001/XMLSchema#NMTOKEN' => 'string', + 'http://www.w3.org/2001/XMLSchema#NMTOKENS' => 'string', + 'http://www.w3.org/2001/XMLSchema#Name' => 'string', + 'http://www.w3.org/2001/XMLSchema#NCName' => 'string', + 'http://www.w3.org/2001/XMLSchema#ID' => 'string', + 'http://www.w3.org/2001/XMLSchema#IDREF' => 'string', + 'http://www.w3.org/2001/XMLSchema#IDREFS' => 'string', + 'http://www.w3.org/2001/XMLSchema#ENTITY' => 'string', + 'http://www.w3.org/2001/XMLSchema#ENTITIES' => 'string', + + 'https://schema.org/DataType' => 'mixed', + ]; + + public function getType(?RdfResource $range): ?string + { + if (!$range) { + return null; + } + + return self::RANGE_MAPPING[$this->getUri($range)] ?? null; + } + + private function getUri(RdfResource $range): string + { + if ($range->isBNode() && $onDatatype = $range->get('owl:onDatatype')) { + return $onDatatype->getUri(); + } + + return $range->getUri(); + } +} diff --git a/src/TypesGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php similarity index 96% rename from src/TypesGeneratorConfiguration.php rename to src/SchemaGeneratorConfiguration.php index 992c9451..321dc8f5 100644 --- a/src/TypesGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -22,11 +22,11 @@ use Symfony\Component\Config\Definition\ConfigurationInterface; /** - * Types Generator Configuration. + * Schema Generator Configuration. * * @author Kévin Dunglas */ -final class TypesGeneratorConfiguration implements ConfigurationInterface +final class SchemaGeneratorConfiguration implements ConfigurationInterface { public const SCHEMA_ORG_URI = 'https://schema.org/version/latest/schemaorg-current-https.rdf'; public const GOOD_RELATIONS_URI = 'https://archive.org/services/purl/goodrelations/v1.owl'; @@ -51,6 +51,12 @@ public function getConfigTreeBuilder(): TreeBuilder $treeBuilder ->getRootNode() ->children() + ->arrayNode('openApi') + ->addDefaultsIfNotSet() + ->children() + ->scalarNode('file')->defaultNull()->end() + ->end() + ->end() ->arrayNode('vocabularies') ->info('RDF vocabularies') ->defaultValue([['uri' => self::SCHEMA_ORG_URI, 'format' => 'rdfxml']]) @@ -59,7 +65,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->then(static function (array $v) { return array_map( static function ($rdf) { - return is_scalar($rdf) ? ['uri' => $rdf, 'format' => null] : $rdf; + return \is_scalar($rdf) ? ['uri' => $rdf, 'format' => null] : $rdf; }, $v ); @@ -210,6 +216,7 @@ static function ($rdf) { ->booleanNode('readable')->defaultTrue()->info('Is the property readable?')->end() ->booleanNode('writable')->defaultTrue()->info('Is the property writable?')->end() ->booleanNode('nullable')->defaultTrue()->info('Is the property nullable?')->end() + ->booleanNode('required')->defaultTrue()->info('Is the property required?')->end() ->booleanNode('unique')->defaultFalse()->info('The property unique')->end() ->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end() ->scalarNode('columnPrefix')->defaultFalse()->info('The property columnPrefix')->end() diff --git a/src/TwigBuilder.php b/src/TwigBuilder.php new file mode 100644 index 00000000..c066b3a2 --- /dev/null +++ b/src/TwigBuilder.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator; + +use Twig\Environment; +use Twig\Extension\DebugExtension; +use Twig\Loader\FilesystemLoader; + +final class TwigBuilder +{ + /** + * @param Configuration $config + */ + public function build(array $config): Environment + { + $templatePaths = $config['generatorTemplates']; + $templatePaths[] = __DIR__.'/../templates/'; + $loader = new FilesystemLoader($templatePaths); + + $twig = new Environment($loader, ['autoescape' => false, 'debug' => $config['debug']]); + if ($config['debug']) { + $twig->addExtension(new DebugExtension()); + } + + return $twig; + } +} diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 68ff3c84..3614941d 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -20,28 +20,23 @@ use ApiPlatform\SchemaGenerator\ClassMutator\ClassParentMutator; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesAppender; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesTypehintMutator; -use ApiPlatform\SchemaGenerator\ClassMutator\EnumClassMutator; use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator; -use Doctrine\Inflector\Inflector; +use ApiPlatform\SchemaGenerator\Model\Use_; +use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; +use ApiPlatform\SchemaGenerator\Schema\ClassMutator\EnumClassMutator as SchemaEnumClassMutator; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\Schema\PropertyGenerator\IdPropertyGenerator; +use ApiPlatform\SchemaGenerator\Schema\PropertyGenerator\PropertyGenerator; +use ApiPlatform\SchemaGenerator\Schema\TypeConverter; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; use EasyRdf\Graph as RdfGraph; use EasyRdf\RdfNamespace; use EasyRdf\Resource as RdfResource; -use Nette\InvalidArgumentException as NetteInvalidArgumentException; -use Nette\PhpGenerator\PhpFile; -use PhpCsFixer\Cache\NullCacheManager; -use PhpCsFixer\Differ\NullDiffer; -use PhpCsFixer\Error\ErrorsManager; -use PhpCsFixer\FixerFactory; -use PhpCsFixer\Linter\Linter; -use PhpCsFixer\RuleSet as LegacyRuleSet; -use PhpCsFixer\RuleSet\RuleSet; -use PhpCsFixer\Runner\Runner; +use Psr\Log\LoggerAwareTrait; use Psr\Log\LoggerInterface; -use Symfony\Component\Console\Question\ConfirmationQuestion; -use Symfony\Component\Console\Style\SymfonyStyle; -use Symfony\Component\Filesystem\Filesystem; -use Twig\Environment; +use Symfony\Component\String\Inflector\InflectorInterface; /** * Generates entity files. @@ -50,6 +45,8 @@ */ class TypesGenerator { + use LoggerAwareTrait; + /** * @var string * @@ -82,40 +79,28 @@ class TypesGenerator 'rdfs:domain', ]; - private Environment $twig; - private LoggerInterface $logger; /** @var RdfGraph[] */ private array $graphs; private PhpTypeConverterInterface $phpTypeConverter; - private GoodRelationsBridge $goodRelationsBridge; /** @var array */ private array $cardinalities; - private Inflector $inflector; - private Filesystem $filesystem; - private PropertyGenerator $propertyGenerator; - private Printer $printer; - private SymfonyStyle $io; + private InflectorInterface $inflector; + private PropertyGeneratorInterface $propertyGenerator; /** * @param RdfGraph[] $graphs */ - public function __construct(Inflector $inflector, Environment $twig, LoggerInterface $logger, array $graphs, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge, Printer $printer, SymfonyStyle $io) + public function __construct(InflectorInterface $inflector, array $graphs, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge) { if (!$graphs) { throw new \InvalidArgumentException('At least one graph must be injected.'); } $this->inflector = $inflector; - $this->twig = $twig; - $this->logger = $logger; $this->graphs = $graphs; $this->phpTypeConverter = $phpTypeConverter; - $this->goodRelationsBridge = $goodRelationsBridge; - $this->filesystem = new Filesystem(); $this->cardinalities = $cardinalitiesExtractor->extract(); - $this->propertyGenerator = new PropertyGenerator($this->goodRelationsBridge, $this->phpTypeConverter, $this->cardinalities, $this->logger); - $this->printer = $printer; - $this->io = $io; + $this->propertyGenerator = new PropertyGenerator($goodRelationsBridge, new TypeConverter(), $phpTypeConverter, $this->cardinalities); RdfNamespace::set('schema', 'https://schema.org/'); } @@ -124,8 +109,10 @@ public function __construct(Inflector $inflector, Environment $twig, LoggerInter * Generates files. * * @param Configuration $config + * + * @return Class_[] */ - public function generate(array $config): void + public function generate(array $config): array { $typesToGenerate = $this->defineTypesToGenerate($config); @@ -144,17 +131,17 @@ public function generate(array $config): void continue; } - $this->logger->warning('The type "{type}" is deprecated', ['type' => $type->getUri()]); + $this->logger ? $this->logger->warning('The type "{type}" is deprecated', ['type' => $type->getUri()]) : null; } $typeConfig = $config['types'][$typeName] ?? null; $parent = $typeConfig['parent'] ?? null; - $class = new Class_($typeName, $type, $parent); + $class = new SchemaClass($typeName, $type, $parent); $class->operations = $typeConfig['operations'] ?? []; $class->security = $typeConfig['security'] ?? null; if ($class->isEnum()) { - $class = (new EnumClassMutator( + (new SchemaEnumClassMutator( $this->phpTypeConverter, $this->graphs, $config['namespaces']['enum'] @@ -165,37 +152,60 @@ public function generate(array $config): void // Interfaces if ($config['useInterface']) { $interfaceNamespace = isset($typeConfig['namespaces']['interface']) && $typeConfig['namespaces']['interface'] ? $typeConfig['namespaces']['interface'] : $config['namespaces']['interface']; - $class = (new ClassInterfaceMutator($interfaceNamespace))($class); + (new ClassInterfaceMutator($interfaceNamespace))($class); } - $class = (new ClassParentMutator($config, $this->phpTypeConverter, $this->logger))($class); + $classParentMutator = new ClassParentMutator($config, $this->phpTypeConverter); + if ($this->logger) { + $classParentMutator->setLogger($this->logger); + } + ($classParentMutator)($class); } - $class = (new ClassPropertiesAppender($this->propertyGenerator, $this->logger, $config, $propertiesMap, $this->graphs))($class); + $classPropertiesAppender = new ClassPropertiesAppender($this->propertyGenerator, $config, $propertiesMap, $this->graphs); + if ($this->logger) { + $classPropertiesAppender->setLogger($this->logger); + } + ($classPropertiesAppender)($class); $class->isEmbeddable = $typeConfig['embeddable'] ?? false; + if ($config['doctrine']['useCollection']) { + $class->addUse(new Use_(ArrayCollection::class)); + $class->addUse(new Use_(Collection::class)); + } + $classes[$typeName] = $class; } // Second pass - foreach ($classes as &$class) { - /** @var $class Class_ */ + foreach ($classes as $class) { + /** @var $class SchemaClass */ if ($class->hasParent() && !$class->isParentEnum()) { $parentClass = $classes[$class->parent()] ?? null; if (isset($parentClass)) { $parentClass->hasChild = true; $class->parentHasConstructor = $parentClass->hasConstructor; } else { - $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class->parent(), $class->resourceUri())); + $this->logger ? $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class->parent(), $class->rdfType())) : null; + } + } + + foreach ($class->properties() as $property) { + if (!$property instanceof SchemaProperty) { + throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); + } + $typeName = $property->rangeName; + if (isset($classes[$typeName])) { + $property->reference = $classes[$typeName]; } } - $class = (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class); + (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class); } // Third pass - foreach ($classes as &$class) { - /* @var $class Class_ */ + foreach ($classes as $class) { + /* @var $class SchemaClass */ $class->isAbstract = $config['types'][$class->name()]['abstract'] ?? $class->hasChild; // When including all properties, ignore properties already set on parent @@ -208,11 +218,11 @@ public function generate(array $config): void } $parentConfig = $config['types'][$class->parent()] ?? null; - /** @var Class_|null $parentClass */ + /** @var SchemaClass|null $parentClass */ $parentClass = $classes[$class->parent()]; while ($parentClass) { - if (\array_key_exists($propertyName, $parentConfig['properties'] ?? []) || \in_array($property, $propertiesMap[$parentClass->resourceUri()], true)) { + if (\array_key_exists($propertyName, $parentConfig['properties'] ?? []) || \in_array($property, $propertiesMap[$parentClass->rdfType()], true)) { $class->removePropertyByName($propertyName); continue 2; } @@ -226,15 +236,18 @@ public function generate(array $config): void // Generate ID if ($config['id']['generate']) { - foreach ($classes as &$class) { - $class = (new ClassIdAppender($config))($class); + foreach ($classes as $class) { + (new ClassIdAppender(new IdPropertyGenerator(), $config))($class); } } // Initialize annotation generators $annotationGenerators = []; foreach ($config['annotationGenerators'] as $annotationGenerator) { - $generator = new $annotationGenerator($this->phpTypeConverter, $this->logger, $this->inflector, $this->graphs, $this->cardinalities, $config, $classes); + $generator = new $annotationGenerator($this->phpTypeConverter, $this->inflector, $config, $classes); + if (method_exists($generator, 'setLogger')) { + $generator->setLogger($this->logger); + } $annotationGenerators[] = $generator; } @@ -242,75 +255,20 @@ public function generate(array $config): void // Initialize attribute generators $attributeGenerators = []; foreach ($config['attributeGenerators'] as $attributeGenerator) { - $generator = new $attributeGenerator($this->phpTypeConverter, $this->logger, $this->inflector, $this->graphs, $this->cardinalities, $config, $classes); - - $attributeGenerators[] = $generator; - } - - $interfaceMappings = []; - $generatedFiles = []; - - foreach ($classes as $className => &$class) { - $class = (new AnnotationsAppender($classes, $annotationGenerators, $typesToGenerate))($class); - $class = (new AttributeAppender($classes, $attributeGenerators))($class); - - $classDir = $this->namespaceToDir($config, $class->namespace); - $this->filesystem->mkdir($classDir); - - $path = sprintf('%s%s.php', $classDir, $className); - - $file = null; - if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) { - $confirmation = $this->io->askQuestion(new ConfirmationQuestion(sprintf('File "%s" already exists, use it (if no it will be overwritten)?', $path))); - if ($confirmation) { - $file = PhpFile::fromCode($fileContent); - $this->logger->info(sprintf('Using "%s" as base file.', $path)); - } + $generator = new $attributeGenerator($this->phpTypeConverter, $this->inflector, $config, $classes); + if (method_exists($generator, 'setLogger')) { + $generator->setLogger($this->logger); } - try { - file_put_contents($path, $this->printer->printFile($class->toNetteFile($config, $this->inflector, $file))); - } catch (NetteInvalidArgumentException $exception) { - $this->logger->warning($exception->getMessage()); - } - - $generatedFiles[] = $path; - - if (null !== $class->interfaceNamespace()) { - $interfaceDir = $this->namespaceToDir($config, $class->interfaceNamespace()); - $this->filesystem->mkdir($interfaceDir); - - $path = sprintf('%s%s.php', $interfaceDir, $class->interfaceName()); - $generatedFiles[] = $path; - file_put_contents($path, $this->printer->printFile($class->interfaceToNetteFile($config['header'] ?? null))); - - if ($config['doctrine']['resolveTargetEntityConfigPath'] && !$class->isAbstract) { - $interfaceMappings[$class->interfaceNamespace().'\\'.$class->interfaceName()] = $class->namespace.'\\'.$className; - } - } + $attributeGenerators[] = $generator; } - if ($config['doctrine']['resolveTargetEntityConfigPath'] && \count($interfaceMappings) > 0) { - $file = $config['output'].'/'.$config['doctrine']['resolveTargetEntityConfigPath']; - $dir = \dirname($file); - $this->filesystem->mkdir($dir); - - $fileType = $config['doctrine']['resolveTargetEntityConfigType']; - - $mappingTemplateFile = 'doctrine.xml.twig'; - if ('yaml' === $fileType) { - $mappingTemplateFile = 'doctrine.yaml.twig'; - } - - file_put_contents( - $file, - $this->twig->render($mappingTemplateFile, ['mappings' => $interfaceMappings]) - ); - - $generatedFiles[] = $file; + foreach ($classes as $class) { + (new AnnotationsAppender($classes, $annotationGenerators, $typesToGenerate))($class); + (new AttributeAppender($classes, $attributeGenerators))($class); } - $this->fixCs($generatedFiles); + return $classes; } /** @@ -434,7 +392,7 @@ private function addPropertyToMap(RdfResource $property, RdfResource $domain, ar continue; } - $this->logger->warning('The property "{property}" of the type "{type}" is deprecated', ['property' => $property->getUri(), 'type' => $typeUri]); + $this->logger ? $this->logger->warning('The property "{property}" of the type "{type}" is deprecated', ['property' => $property->getUri(), 'type' => $typeUri]) : null; } $map[$typeUri][] = $property; @@ -450,7 +408,7 @@ private function addPropertyToMap(RdfResource $property, RdfResource $domain, ar private function defineTypesToGenerate(array $config): array { $typesToGenerate = []; - if ($config['allTypes'] || !$config['types']) { + if ($config['allTypes']) { foreach ($this->graphs as $graph) { foreach (self::$classTypes as $classType) { foreach ($graph->allOfType($classType) as $type) { @@ -478,7 +436,7 @@ private function defineTypesToGenerate(array $config): array if ($resource) { $typesToGenerate[$typeName] = $resource; } else { - $this->logger->warning('Type "{typeName}" cannot be found. Using "{guessFrom}" type to generate entity.', ['typeName' => $typeName, 'guessFrom' => $typeConfig['guessFrom']]); + $this->logger ? $this->logger->warning('Type "{typeName}" cannot be found. Using "{guessFrom}" type to generate entity.', ['typeName' => $typeName, 'guessFrom' => $typeConfig['guessFrom']]) : null; if (isset($graph)) { $type = $graph->resource($vocabularyNamespace.$typeConfig['guessFrom']); $typesToGenerate[$typeName] = $type; @@ -490,55 +448,11 @@ private function defineTypesToGenerate(array $config): array return $typesToGenerate; } - /** - * Converts a namespace to a directory path according to PSR-4. - * - * @param Configuration $config - */ - private function namespaceToDir(array $config, string $namespace): string - { - if (null !== ($prefix = $config['namespaces']['prefix'] ?? null) && 0 === strpos($namespace, $prefix)) { - $namespace = substr($namespace, \strlen($prefix)); - } - - return sprintf('%s/%s/', $config['output'], str_replace('\\', '/', $namespace)); - } - - /** - * Uses PHP CS Fixer to make generated files following PSR and Symfony Coding Standards. - * - * @param string[] $files - */ - private function fixCs(array $files): void + public function setLogger(LoggerInterface $logger): void { - $fileInfos = []; - foreach ($files as $file) { - $fileInfos[] = new \SplFileInfo($file); + $this->logger = $logger; + if (method_exists($this->propertyGenerator, 'setLogger')) { + $this->propertyGenerator->setLogger($logger); } - - // to keep compatibility with both versions of php-cs-fixer: 2.x and 3.x - // ruleset object must be created depending on which class is available - $rulesetClass = class_exists(LegacyRuleSet::class) ? LegacyRuleSet::class : Ruleset::class; - $fixers = (new FixerFactory()) - ->registerBuiltInFixers() - ->useRuleSet(new $rulesetClass([ // @phpstan-ignore-line - '@Symfony' => true, - 'array_syntax' => ['syntax' => 'short'], - 'phpdoc_order' => true, - 'declare_strict_types' => true, - ])) - ->getFixers(); - - $runner = new Runner( - new \ArrayIterator($fileInfos), - $fixers, - new NullDiffer(), - null, - new ErrorsManager(), - new Linter(), - false, - new NullCacheManager() - ); - $runner->fix(); } } diff --git a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php index b796000f..6d85ee22 100644 --- a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php @@ -17,11 +17,11 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Interface_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use Doctrine\Inflector\InflectorFactory; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; +use Symfony\Component\String\Inflector\EnglishInflector; class PhpDocAnnotationGeneratorTest extends TestCase { @@ -31,10 +31,7 @@ protected function setUp(): void { $this->generator = new PhpDocAnnotationGenerator( new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], + new EnglishInflector(), ['author' => 'Bill'], [], ); @@ -50,11 +47,11 @@ public function testGenerateClassAnnotations(Class_ $class, array $annotations): public function provideGenerateClassAnnotationsCases(): \Generator { - $class = new Class_('Res', new RdfResource('https://schema.org/Res')); + $class = new SchemaClass('Res', new RdfResource('https://schema.org/Res')); $class->interface = new Interface_('Interface', '/foo'); yield 'with interface' => [$class, ['{@inheritdoc}', '', '@author Bill']]; $graph = new RdfGraph(); - yield 'with resource' => [new Class_('Res', new RdfResource('https://schema.org/Res', $graph)), ['', '', '@see https://schema.org/Res', '@author Bill']]; + yield 'with resource' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', $graph)), ['@see https://schema.org/Res', '@author Bill']]; } } diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index c99682df..85856cf4 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -17,16 +17,15 @@ use ApiPlatform\Core\Annotation\ApiResource; use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; use ApiPlatform\SchemaGenerator\TypesGenerator; -use Doctrine\Inflector\InflectorFactory; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; +use Symfony\Component\String\Inflector\EnglishInflector; /** * @author Kévin Dunglas @@ -39,10 +38,7 @@ protected function setUp(): void { $this->generator = new ApiPlatformCoreAttributeGenerator( new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], + new EnglishInflector(), [], [], ); @@ -51,34 +47,34 @@ protected function setUp(): void /** * @dataProvider provideGenerateClassAttributesCases */ - public function testGenerateClassAttributes(Class_ $class, array $attributes): void + public function testGenerateClassAttributes(SchemaClass $class, array $attributes): void { $this->assertEquals($attributes, $this->generator->generateClassAttributes($class)); } public function provideGenerateClassAttributesCases(): \Generator { - yield 'classical' => [new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])]]; + yield 'classical' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])]]; - $class = new Class_('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); + $class = new SchemaClass('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); $class->operations = [ 'item' => ['get' => ['route_name' => 'api_about_get']], 'collection' => [], ]; yield 'with operations' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []])]]; - $class = new Class_('Abstract', new RdfResource('https://schema.org/Abstract')); + $class = new SchemaClass('Abstract', new RdfResource('https://schema.org/Abstract')); $class->isAbstract = true; yield 'abstract' => [$class, []]; $resource = new RdfResource('https://schema.org/MyEnum', new RdfGraph()); $resource->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - $class = new Class_('Enum', $resource); + $class = new SchemaClass('Enum', $resource); yield 'enum' => [$class, []]; - yield 'with short name' => [(new Class_('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; + yield 'with short name' => [(new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; - $class = new Class_('WithSecurity', new RdfResource('https://schema.org/WithSecurity', new RdfGraph())); + $class = new SchemaClass('WithSecurity', new RdfResource('https://schema.org/WithSecurity', new RdfGraph())); $class->security = "is_granted('ROLE_USER')"; yield 'with security' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"])]]; } @@ -110,6 +106,6 @@ public function testGenerateCustomPropertyAttributes(): void public function testGenerateUses(): void { - $this->assertEquals([new Use_(ApiResource::class), new Use_(ApiProperty::class)], $this->generator->generateUses(new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); + $this->assertEquals([new Use_(ApiResource::class), new Use_(ApiProperty::class)], $this->generator->generateUses(new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); } } diff --git a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php index 31820df6..03f1df0a 100644 --- a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php @@ -15,18 +15,17 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; use ApiPlatform\SchemaGenerator\TypesGenerator; -use Doctrine\Inflector\InflectorFactory; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use Nette\PhpGenerator\Literal; use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; +use Symfony\Component\String\Inflector\EnglishInflector; class ConstraintAttributeGeneratorTest extends TestCase { @@ -36,10 +35,7 @@ protected function setUp(): void { $this->generator = new ConstraintAttributeGenerator( new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], + new EnglishInflector(), ['id' => ['generationStrategy' => 'uuid']], [], ); @@ -48,7 +44,7 @@ protected function setUp(): void /** * @dataProvider provideGenerateClassAttributesCases */ - public function testGenerateClassAttributes(Class_ $class, array $attributes): void + public function testGenerateClassAttributes(SchemaClass $class, array $attributes): void { $this->assertEquals($attributes, $this->generator->generateClassAttributes($class)); } @@ -59,10 +55,10 @@ public function provideGenerateClassAttributesCases(): \Generator $resource = new RdfResource('https://schema.org/Enum', $graph); $resource->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - yield 'enum' => [new Class_('Enum', $resource), []]; + yield 'enum' => [new SchemaClass('Enum', $resource), []]; $graph = new RdfGraph(); - $class = new Class_('Foo', new RdfResource('https://schema.org/Foo', $graph)); + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', $graph)); $uniqueProperty = new Property('bar'); $uniqueProperty->isUnique = true; $class->addProperty($uniqueProperty); @@ -70,7 +66,7 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'one unique property' => [$class, [new Attribute('UniqueEntity', ['bar'])]]; $graph = new RdfGraph(); - $class = new Class_('Foo', new RdfResource('https://schema.org/Foo', $graph)); + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', $graph)); $uniqueProperty = new Property('bar'); $uniqueProperty->isUnique = true; $class->addProperty($uniqueProperty); @@ -96,14 +92,13 @@ public function provideGeneratePropertyAttributesCases(): \Generator yield 'uuid' => [$property, [new Attribute('Assert\Uuid')]]; $property = new Property('prop'); - $property->range = new RdfResource('https://schema.org/email'); $property->resource = new RdfResource('https://schema.org/email'); + $property->type = 'string'; $property->isNullable = false; yield 'email' => [$property, [new Attribute('Assert\Email'), new Attribute('Assert\NotNull')]]; $property = new Property('prop'); - $property->range = new RdfResource('https://schema.org/Enum'); - $property->rangeName = 'Enum'; + $property->reference = new SchemaClass('Enum', new RdfResource('https://schema.org/Enum', new RdfGraph())); $property->isEnum = true; $property->isArray = true; yield 'enum' => [$property, [new Attribute('Assert\Choice', ['callback' => [new Literal('Enum::class'), 'toArray'], 'multiple' => true])]]; @@ -111,7 +106,7 @@ public function provideGeneratePropertyAttributesCases(): \Generator public function testGenerateUses(): void { - $this->assertEquals([new Use_('Symfony\Component\Validator\Constraints', 'Assert'), new Use_(UniqueEntity::class)], $this->generator->generateUses(new Class_('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); + $this->assertEquals([new Use_('Symfony\Component\Validator\Constraints', 'Assert'), new Use_(UniqueEntity::class)], $this->generator->generateUses(new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); } public function testGenerateNoUsesForEnum(): void @@ -119,6 +114,6 @@ public function testGenerateNoUsesForEnum(): void $graph = new RdfGraph(); $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - $this->assertSame([], $this->generator->generateUses(new Class_('MyEnum', $myEnum))); + $this->assertSame([], $this->generator->generateUses(new SchemaClass('MyEnum', $myEnum))); } } diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 1915b2c3..2018480f 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -16,17 +16,16 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineMongoDBAttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use ApiPlatform\SchemaGenerator\TypesGenerator; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use Doctrine\Inflector\InflectorFactory; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\String\Inflector\EnglishInflector; class DoctrineMongoDBAttributeGeneratorTest extends TestCase { @@ -38,39 +37,45 @@ protected function setUp(): void { $graph = new RdfGraph(); - $product = new Class_('Product', new RdfResource('https://schema.org/Product', $graph)); + $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph)); $product->isAbstract = true; $this->classMap[$product->name()] = $product; - $vehicle = new Class_('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); + $vehicle = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; $idProperty->range = new RdfResource('https://schema.org/identifier'); + $idProperty->type = 'string'; $idProperty->isId = true; $vehicle->addProperty($idProperty); $enumProperty = new Property('enum'); $enumProperty->rangeName = 'Thing'; $enumProperty->range = new RdfResource('https://schema.org/Thing'); + $enumProperty->reference = new SchemaClass('Thing', new RdfResource('htts://schema.org/Thing', $graph)); $enumProperty->isEnum = true; $enumProperty->isArray = true; $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); $collectionProperty->rangeName = 'string'; $collectionProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#string'); + $collectionProperty->type = 'string'; $collectionProperty->isArray = true; $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); $weightProperty->rangeName = 'nonPositiveInteger'; $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); + $weightProperty->type = 'nonPositiveInteger'; $vehicle->addProperty($weightProperty); $relationProperty = new Property('relation'); $relationProperty->rangeName = 'Person'; $relationProperty->range = new RdfResource('https://schema.org/Person'); + $relationProperty->reference = new SchemaClass('Person', new RdfResource('htts://schema.org/Person', $graph)); $relationProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $vehicle->addProperty($relationProperty); $relationsProperty = new Property('relations'); $relationsProperty->rangeName = 'Person'; $relationsProperty->range = new RdfResource('https://schema.org/Person'); + $relationsProperty->reference = new SchemaClass('Person', new RdfResource('htts://schema.org/Person', $graph)); $relationsProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; $relationsProperty->isArray = true; $vehicle->addProperty($relationsProperty); @@ -79,14 +84,14 @@ protected function setUp(): void $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - $myEnumClass = new Class_('MyEnum', $myEnum); + $myEnumClass = new SchemaClass('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; $customAttributes = new RdfResource('https://schema.org/CustomAttributes', $graph); - $customAttributesClass = new Class_('CustomAttributes', $customAttributes); + $customAttributesClass = new SchemaClass('CustomAttributes', $customAttributes); $this->classMap[$customAttributesClass->name()] = $customAttributesClass; - $configuration = new TypesGeneratorConfiguration(); + $configuration = new SchemaGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'id' => ['generationStrategy' => 'auto', 'writable' => true], @@ -99,10 +104,7 @@ protected function setUp(): void $this->generator = new DoctrineMongoDBAttributeGenerator( new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], + new EnglishInflector(), $processedConfiguration, $this->classMap ); diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index 97879b4b..ca4c0f77 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -16,17 +16,16 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use ApiPlatform\SchemaGenerator\TypesGenerator; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use Doctrine\Inflector\InflectorFactory; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\String\Inflector\EnglishInflector; /** * @author Erik Saunier @@ -41,14 +40,15 @@ protected function setUp(): void { $graph = new RdfGraph(); - $product = new Class_('Product', new RdfResource('https://schema.org/Product', $graph)); + $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph)); $product->isAbstract = true; $this->classMap[$product->name()] = $product; - $vehicle = new Class_('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); + $vehicle = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; $idProperty->range = new RdfResource('https://schema.org/identifier'); + $idProperty->type = 'string'; $idProperty->isId = true; $vehicle->addProperty($idProperty); $enumProperty = new Property('enum'); @@ -56,77 +56,88 @@ protected function setUp(): void $enumProperty->range = new RdfResource('https://schema.org/Thing'); $enumProperty->isEnum = true; $enumProperty->isArray = true; + $enumProperty->reference = new SchemaClass('Thing', new RdfResource('htts://schema.org/Thing', $graph)); $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); $collectionProperty->rangeName = 'string'; $collectionProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#string'); + $collectionProperty->type = 'string'; $collectionProperty->isArray = true; $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); $weightProperty->rangeName = 'nonPositiveInteger'; $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); + $weightProperty->type = 'nonPositiveInteger'; $vehicle->addProperty($weightProperty); $prefixedWeightProperty = new Property('prefixedWeight'); $prefixedWeightProperty->columnPrefix = 'weight_'; $prefixedWeightProperty->isEmbedded = true; $prefixedWeightProperty->rangeName = 'QuantitativeValue'; $prefixedWeightProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); + $prefixedWeightProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $vehicle->addProperty($prefixedWeightProperty); $relation01Property = new Property('relation0_1'); $relation01Property->rangeName = 'QuantitativeValue'; $relation01Property->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relation01Property->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relation01Property->cardinality = CardinalitiesExtractor::CARDINALITY_0_1; $vehicle->addProperty($relation01Property); $relation11Property = new Property('relation1_1'); $relation11Property->rangeName = 'QuantitativeValue'; $relation11Property->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relation11Property->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relation11Property->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $vehicle->addProperty($relation11Property); $relationN0Property = new Property('relationN_0'); $relationN0Property->rangeName = 'QuantitativeValue'; $relationN0Property->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relationN0Property->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relationN0Property->cardinality = CardinalitiesExtractor::CARDINALITY_N_0; $vehicle->addProperty($relationN0Property); $relationN1Property = new Property('relationN_1'); $relationN1Property->rangeName = 'QuantitativeValue'; $relationN1Property->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relationN1Property->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relationN1Property->cardinality = CardinalitiesExtractor::CARDINALITY_N_1; $vehicle->addProperty($relationN1Property); $relation0NProperty = new Property('relation0_N'); $relation0NProperty->rangeName = 'QuantitativeValue'; $relation0NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relation0NProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relation0NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_0_N; $relation0NProperty->isArray = true; $vehicle->addProperty($relation0NProperty); $relation1NProperty = new Property('relation1_N'); $relation1NProperty->rangeName = 'QuantitativeValue'; $relation1NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relation1NProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relation1NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; $relation1NProperty->isArray = true; $vehicle->addProperty($relation1NProperty); $relationNNProperty = new Property('relationN_N'); $relationNNProperty->rangeName = 'QuantitativeValue'; $relationNNProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); + $relationNNProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relationNNProperty->cardinality = CardinalitiesExtractor::CARDINALITY_N_N; $relationNNProperty->isArray = true; $vehicle->addProperty($relationNNProperty); $this->classMap[$vehicle->name()] = $vehicle; - $quantitativeValue = new Class_('QuantitativeValue', new RdfResource('https://schema.org/QuantitativeValue', $graph)); + $quantitativeValue = new SchemaClass('QuantitativeValue', new RdfResource('https://schema.org/QuantitativeValue', $graph)); $quantitativeValue->isEmbeddable = true; $this->classMap[$quantitativeValue->name()] = $quantitativeValue; $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); - $myEnumClass = new Class_('MyEnum', $myEnum); + $myEnumClass = new SchemaClass('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; $customAttributes = new RdfResource('https://schema.org/CustomAttributes', $graph); - $customAttributesClass = new Class_('CustomAttributes', $customAttributes); + $customAttributesClass = new SchemaClass('CustomAttributes', $customAttributes); $this->classMap[$customAttributesClass->name()] = $customAttributesClass; - $configuration = new TypesGeneratorConfiguration(); + $configuration = new SchemaGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'id' => ['generationStrategy' => 'auto', 'writable' => true], @@ -139,10 +150,7 @@ protected function setUp(): void $this->generator = new DoctrineOrmAttributeGenerator( new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], + new EnglishInflector(), $processedConfiguration, $this->classMap ); diff --git a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php index 762591d2..9e527b10 100644 --- a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php @@ -15,11 +15,10 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use Doctrine\Inflector\InflectorFactory; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; use PHPUnit\Framework\TestCase; -use Psr\Log\NullLogger; +use Symfony\Component\String\Inflector\EnglishInflector; class SerializerGroupAttributeGeneratorTest extends TestCase { @@ -29,10 +28,7 @@ protected function setUp(): void { $this->generator = new SerializerGroupsAttributeGenerator( new PhpTypeConverter(), - new NullLogger(), - InflectorFactory::create()->build(), - [], - [], + new EnglishInflector(), [], [], ); @@ -40,7 +36,7 @@ protected function setUp(): void public function testGeneratePropertyAttributes(): void { - $property = new Property('prop'); + $property = new SchemaProperty('prop'); $property->isId = false; $property->groups = ['group']; diff --git a/tests/ClassMutator/ClassParentMutatorTest.php b/tests/ClassMutator/ClassParentMutatorTest.php index 76f18774..77c2adfa 100644 --- a/tests/ClassMutator/ClassParentMutatorTest.php +++ b/tests/ClassMutator/ClassParentMutatorTest.php @@ -14,10 +14,10 @@ namespace ApiPlatform\SchemaGenerator\Tests\ClassMutator; use ApiPlatform\SchemaGenerator\ClassMutator\ClassParentMutator; -use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; @@ -37,7 +37,7 @@ protected function setUp(): void { $this->loggerProphecy = $this->prophesize(LoggerInterface::class); - $configuration = new TypesGeneratorConfiguration(); + $configuration = new SchemaGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'types' => [ @@ -46,43 +46,46 @@ protected function setUp(): void ], ]]); - $this->classParentMutator = new ClassParentMutator($processedConfiguration, new PhpTypeConverter(), $this->loggerProphecy->reveal()); + $this->classParentMutator = new ClassParentMutator($processedConfiguration, new PhpTypeConverter()); + $this->classParentMutator->setLogger($this->loggerProphecy->reveal()); } /** * @dataProvider provideInvokeTestCases */ - public function testInvoke(Class_ $class, Class_ $expectedClass, ?string $loggerMessage = null): void + public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?string $loggerMessage = null): void { if ($loggerMessage) { $this->loggerProphecy->warning($loggerMessage)->shouldBeCalled(); } - $this->assertEquals($expectedClass, ($this->classParentMutator)($class)); + ($this->classParentMutator)($class); + + $this->assertEquals($expectedClass, $class); } /** - * @return \Generator + * @return \Generator */ public function provideInvokeTestCases(): \Generator { $graph = new RdfGraph(); - $product = new Class_('Product', new RdfResource('https://schema.org/Product', $graph)); + $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph)); yield 'no parent' => [clone $product, clone $product]; $graph = new RdfGraph(); $graph->addResource('https://schema.org/CreativeWork', 'rdfs:subClassOf', 'https://schema.org/Thing'); - $creativeWork = new Class_('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph)); + $creativeWork = new SchemaClass('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph)); yield 'with subclass' => [clone $creativeWork, (clone $creativeWork)->withParent('Thing')]; $graph = new RdfGraph(); $graph->addResource('https://schema.org/CreativeWork', 'rdfs:subClassOf', 'https://schema.org/Work'); $graph->addResource('https://schema.org/CreativeWork', 'rdfs:subClassOf', 'https://schema.org/Thing'); - $creativeWork = new Class_('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph)); + $creativeWork = new SchemaClass('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph)); yield 'with multiple subclasses' => [clone $creativeWork, (clone $creativeWork)->withParent('Work'), 'The type "https://schema.org/CreativeWork" has several supertypes. Using the first one.']; $graph = new RdfGraph(); - $blogPosting = new Class_('BlogPosting', new RdfResource('https://schema.org/BlogPosting', $graph)); + $blogPosting = new SchemaClass('BlogPosting', new RdfResource('https://schema.org/BlogPosting', $graph)); yield 'with parent' => [clone $blogPosting, (clone $blogPosting)->withParent('SocialMediaPosting')->addUse(new Use_('socialMediaNamespace\SocialMediaPosting'))]; } } diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index 2b4b5d6e..dd5fd812 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -16,18 +16,18 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesAppender; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\Schema\PropertyGenerator\PropertyGenerator as SchemaPropertyGenerator; +use ApiPlatform\SchemaGenerator\Schema\TypeConverter; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; use Psr\Log\LoggerInterface; -use Psr\Log\NullLogger; use Symfony\Component\Config\Definition\Processor; class ClassPropertiesAppenderTest extends TestCase @@ -42,10 +42,9 @@ protected function setUp(): void { $this->loggerProphecy = $this->prophesize(LoggerInterface::class); - $propertyGenerator = new PropertyGenerator(new GoodRelationsBridge([]), new PhpTypeConverter(), [], new NullLogger()); + $propertyGenerator = new SchemaPropertyGenerator(new GoodRelationsBridge([]), new TypeConverter(), new PhpTypeConverter(), []); - $configuration = new TypesGeneratorConfiguration(); - /** @var Configuration $processedConfiguration */ + $configuration = new SchemaGeneratorConfiguration(); $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'types' => [ 'Person' => ['properties' => ['givenName' => []]], @@ -68,13 +67,14 @@ protected function setUp(): void 'https://schema.org/Person' => [new RdfResource('https://schema.org/givenName', $this->graph)], ]; - $this->classPropertiesAppender = new ClassPropertiesAppender($propertyGenerator, $this->loggerProphecy->reveal(), $processedConfiguration, $propertiesMap, []); + $this->classPropertiesAppender = new ClassPropertiesAppender($propertyGenerator, $processedConfiguration, $propertiesMap, []); + $this->classPropertiesAppender->setLogger($this->loggerProphecy->reveal()); } /** * @dataProvider provideInvokeTestCases */ - public function testInvoke(Class_ $class, Class_ $expectedClass, RdfGraph &$graph = null, ?string $loggerMessage = null): void + public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, RdfGraph &$graph = null, ?string $loggerMessage = null): void { if ($graph) { $this->graph = $graph; @@ -85,41 +85,47 @@ public function testInvoke(Class_ $class, Class_ $expectedClass, RdfGraph &$grap $this->loggerProphecy->warning($loggerMessage)->shouldBeCalled(); } - $this->assertEquals($expectedClass, ($this->classPropertiesAppender)($class)); + ($this->classPropertiesAppender)($class); + + $this->assertEquals($expectedClass, $class); } /** - * @return \Generator + * @return \Generator */ public function provideInvokeTestCases(): \Generator { - $product = new Class_('Product', new RdfResource('https://schema.org/Product')); + $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product')); yield 'no configuration no properties in map' => [clone $product, clone $product, null, 'Properties for "https://schema.org/Product" not found in the map.']; - $article = new Class_('Article', new RdfResource('https://schema.org/Article')); + $article = new SchemaClass('Article', new RdfResource('https://schema.org/Article')); $graph = new RdfGraph(); $expectedArticleBodyProperty = new Property('articleBody'); $expectedArticleBodyProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $expectedArticleBodyProperty->resource = new RdfResource('https://schema.org/articleBody', $graph); $expectedArticleBodyProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedArticleBodyProperty->rangeName = 'Text'; + $expectedArticleBodyProperty->type = 'string'; $expectedArticleBodyProperty->isNullable = false; $expectedArticleSectionProperty = new Property('articleSection'); $expectedArticleSectionProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $expectedArticleSectionProperty->resource = new RdfResource('https://schema.org/articleSection', $graph); $expectedArticleSectionProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedArticleSectionProperty->rangeName = 'Text'; + $expectedArticleSectionProperty->type = 'string'; $expectedArticleSectionProperty->isNullable = false; yield 'no configuration' => [clone $article, (clone $article)->addProperty($expectedArticleBodyProperty)->addProperty($expectedArticleSectionProperty), $graph]; $graph = new RdfGraph(); - $person = new Class_('Person', new RdfResource('https://schema.org/Person', $graph)); + $person = new SchemaClass('Person', new RdfResource('https://schema.org/Person', $graph)); $expectedGivenNameProperty = new Property('givenName'); $expectedGivenNameProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; $expectedGivenNameProperty->resource = new RdfResource('https://schema.org/givenName', $graph); $expectedGivenNameProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedGivenNameProperty->rangeName = 'Text'; + $expectedGivenNameProperty->type = 'string'; $expectedGivenNameProperty->isNullable = true; + $expectedGivenNameProperty->isRequired = true; $expectedGivenNameProperty->ormColumn = []; yield 'with configuration' => [clone $person, (clone $person)->addProperty($expectedGivenNameProperty), $graph]; } diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 8f60a6f4..d552092c 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -28,6 +28,8 @@ public function testDumpConfiguration(): void $this->assertEquals(0, $commandTester->execute([])); $this->assertEquals(<<<'YAML' config: + openApi: + file: null # RDF vocabularies vocabularies: @@ -218,6 +220,9 @@ interface: null # Is the property nullable? nullable: true + # Is the property required? + required: true + # The property unique unique: false diff --git a/tests/Model/InterfaceTest.php b/tests/Model/InterfaceTest.php index 260b66e8..71dbb9a0 100644 --- a/tests/Model/InterfaceTest.php +++ b/tests/Model/InterfaceTest.php @@ -18,7 +18,7 @@ class InterfaceTest extends TestCase { - public function testInterface() + public function testInterface(): void { $interface = new Interface_('Printable', "App\Entity"); $interface->addAnnotation('@see description'); diff --git a/tests/Model/ClassTest.php b/tests/Schema/Model/ClassTest.php similarity index 78% rename from tests/Model/ClassTest.php rename to tests/Schema/Model/ClassTest.php index 7bfd9b73..1cbcb963 100644 --- a/tests/Model/ClassTest.php +++ b/tests/Schema/Model/ClassTest.php @@ -11,36 +11,35 @@ declare(strict_types=1); -namespace ApiPlatform\SchemaGenerator\Tests\Model; +namespace ApiPlatform\SchemaGenerator\Tests\Schema\Model; -use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Interface_; -use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use Doctrine\Inflector\InflectorFactory; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\String\Inflector\EnglishInflector; class ClassTest extends TestCase { public function testClass(): void { - $inflector = InflectorFactory::create()->build(); + $inflector = new EnglishInflector(); - $property = new Property('author'); + $property = new SchemaProperty('author'); $property->typeHint = "App\Entity\Author"; $property->addAnnotation('@see https://schema.org/Author'); - $class = new Class_('Book', new RdfResource('http//schema.org/Book', new RdfGraph())); + $class = new SchemaClass('Book', new RdfResource('http//schema.org/Book', new RdfGraph())); $class->namespace = 'App\Entity'; $class->interface = new Interface_('Printable', 'OtherApp\Interfaces'); $class->addUse(new Use_('OtherApp\Interfaces\Printable')); $class->addProperty($property); - $configuration = new TypesGeneratorConfiguration(); - /** @var Configuration $processedConfiguration */ + $configuration = new SchemaGeneratorConfiguration(); $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'doctrine' => ['useCollection' => false], 'fluentMutatorMethods' => true, @@ -63,8 +62,8 @@ public function testClass(): void $this->assertFalse($class->isEnum()); $this->assertFalse($class->isAbstract); $this->assertTrue($class->isInNamespace('App\Entity')); - $this->assertEquals('Book', $class->resourceLocalName()); - $this->assertEquals('http//schema.org/Book', $class->resourceUri()); + $this->assertEquals('Book', $class->shortName()); + $this->assertEquals('http//schema.org/Book', $class->rdfType()); $this->assertEquals([], $class->constants()); $this->assertEquals('Book', $class->name()); $this->assertTrue($class->hasProperty('author')); diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 777e7bae..ec895196 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -14,21 +14,21 @@ namespace ApiPlatform\SchemaGenerator\Tests; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; +use ApiPlatform\SchemaGenerator\FilesGenerator; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Printer; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use ApiPlatform\SchemaGenerator\TypesGenerator; -use ApiPlatform\SchemaGenerator\TypesGeneratorConfiguration; -use Doctrine\Inflector\InflectorFactory; use EasyRdf\Graph as RdfGraph; use EasyRdf\RdfNamespace; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; -use Psr\Log\NullLogger; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\String\Inflector\EnglishInflector; use Twig\Environment; /** @@ -56,24 +56,30 @@ public function testGenerate(): void $goodRelationsBridgeProphecy = $this->prophesize(GoodRelationsBridge::class); $goodRelationsBridge = $goodRelationsBridgeProphecy->reveal(); + $inflector = new EnglishInflector(); + $typesGenerator = new TypesGenerator( - InflectorFactory::create()->build(), - $twig, - new NullLogger(), + $inflector, $this->getGraphs(), new PhpTypeConverter(), $cardinalitiesExtractor, - $goodRelationsBridge, + $goodRelationsBridge + ); + + $filesGenerator = new FilesGenerator( + $inflector, new Printer(), + $twig, new SymfonyStyle(new ArrayInput([]), new NullOutput()) ); $outputDir = 'build/type-generator-test'; - $configuration = new TypesGeneratorConfiguration(); + $configuration = new SchemaGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ $processedConfiguration = (new Processor())->processConfiguration($configuration, [$this->getConfig()]); $processedConfiguration['output'] = $outputDir; - $typesGenerator->generate($processedConfiguration); + $classes = $typesGenerator->generate($processedConfiguration); + $filesGenerator->generate($classes, $processedConfiguration); $article = file_get_contents("$outputDir/App/Entity/Article.php"); $this->assertStringContainsString('abstract class Article extends CreativeWork', $article); diff --git a/tests/e2e/original/App/Entity/Brand.php b/tests/e2e/customized/App/Schema/Entity/Brand.php similarity index 97% rename from tests/e2e/original/App/Entity/Brand.php rename to tests/e2e/customized/App/Schema/Entity/Brand.php index a4093a2a..02d9ee4f 100644 --- a/tests/e2e/original/App/Entity/Brand.php +++ b/tests/e2e/customized/App/Schema/Entity/Brand.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; diff --git a/tests/e2e/customized/App/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php similarity index 95% rename from tests/e2e/customized/App/Entity/Person.php rename to tests/e2e/customized/App/Schema/Entity/Person.php index 99e5e15b..02e85d8d 100644 --- a/tests/e2e/customized/App/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -2,14 +2,14 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; use App\Attribute\MyCustomAttribute; -use App\Enum\GenderType; use App\Model\MyCustomClass; use App\Model\MyCustomInterface; +use App\Schema\Enum\GenderType; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -86,7 +86,7 @@ class Person extends MyCustomClass implements MyCustomInterface * * @see https://schema.org/address */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\PostalAddress')] + #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] #[ApiProperty(iri: 'https://schema.org/address')] private ?PostalAddress $address = null; @@ -130,11 +130,11 @@ class Person extends MyCustomClass implements MyCustomInterface private ?string $url = null; /** - * A sibling of the person. + * @var Collection|null a sibling of the person * * @see https://schema.org/siblings */ - #[ORM\ManyToMany(targetEntity: 'App\Entity\Person')] + #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\InverseJoinColumn(unique: true)] #[ApiProperty(iri: 'https://schema.org/siblings')] private ?Collection $siblings = null; @@ -258,6 +258,9 @@ public function removeSibling(Person $sibling): void $this->siblings->removeElement($sibling); } + /** + * @return Collection|null + */ public function getSiblings(): Collection { return $this->siblings; diff --git a/tests/e2e/original/App/Entity/PostalAddress.php b/tests/e2e/customized/App/Schema/Entity/PostalAddress.php similarity index 99% rename from tests/e2e/original/App/Entity/PostalAddress.php rename to tests/e2e/customized/App/Schema/Entity/PostalAddress.php index f17cf43e..d28b672d 100644 --- a/tests/e2e/original/App/Entity/PostalAddress.php +++ b/tests/e2e/customized/App/Schema/Entity/PostalAddress.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; diff --git a/tests/e2e/customized/App/Entity/Thing.php b/tests/e2e/customized/App/Schema/Entity/Thing.php similarity index 95% rename from tests/e2e/customized/App/Entity/Thing.php rename to tests/e2e/customized/App/Schema/Entity/Thing.php index e8405b00..8c1926a7 100644 --- a/tests/e2e/customized/App/Entity/Thing.php +++ b/tests/e2e/customized/App/Schema/Entity/Thing.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use Doctrine\ORM\Mapping as ORM; diff --git a/tests/e2e/customized/App/Enum/GenderType.php b/tests/e2e/customized/App/Schema/Enum/GenderType.php similarity index 93% rename from tests/e2e/customized/App/Enum/GenderType.php rename to tests/e2e/customized/App/Schema/Enum/GenderType.php index bb68634a..f2a24993 100644 --- a/tests/e2e/customized/App/Enum/GenderType.php +++ b/tests/e2e/customized/App/Schema/Enum/GenderType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Enum; +namespace App\Schema\Enum; use MyCLabs\Enum\Enum; diff --git a/tests/e2e/openapi.yml b/tests/e2e/openapi.yml new file mode 100644 index 00000000..3bbd4542 --- /dev/null +++ b/tests/e2e/openapi.yml @@ -0,0 +1,2757 @@ +openapi: 3.0.3 +info: + title: API Platform's demo + description: |- + This is a demo application of the [API Platform](https://api-platform.com) framework. + [Its source code](https://github.com/api-platform/demo) includes various examples, check it out! + You may also be interested by [the GraphQL entrypoint](/graphql). + [A PWA](/) and [an admin](/admin) are consuming this API. + version: 1.0.0 +servers: + - url: / + description: '' +paths: + /books: + get: + operationId: getBookCollection + tags: + - Book + responses: + '200': + description: Book collection + content: + application/ld+json: + schema: + type: object + properties: + hydra:member: + type: array + items: + $ref: '#/components/schemas/Book.jsonld-book.read' + hydra:totalItems: + type: integer + minimum: 0 + hydra:view: + type: object + properties: + '@id': + type: string + format: iri-reference + '@type': + type: string + hydra:first: + type: string + format: iri-reference + hydra:last: + type: string + format: iri-reference + hydra:previous: + type: string + format: iri-reference + hydra:next: + type: string + format: iri-reference + hydra:search: + type: object + properties: + '@type': + type: string + hydra:template: + type: string + hydra:variableRepresentation: + type: string + hydra:mapping: + type: array + items: + type: object + properties: + '@type': + type: string + variable: + type: string + property: + type: string + nullable: true + required: + type: boolean + required: + - hydra:member + application/hal+json: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + application/vnd.api+json: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + text/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + application/x-yaml: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + text/csv: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + text/html: + schema: + type: array + items: + $ref: '#/components/schemas/Book-book.read' + summary: Retrieves the collection of Book resources. + description: Retrieves the collection of Book resources. + parameters: + - name: page + in: query + description: The collection page number + required: false + deprecated: false + allowEmptyValue: true + schema: + type: integer + default: 1 + style: form + explode: false + allowReserved: false + - name: archived + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: boolean + style: form + explode: false + allowReserved: false + - name: order[id] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: order[title] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: order[author] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: order[isbn] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: order[publicationDate] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: properties[] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: array + items: + type: string + style: form + explode: true + allowReserved: false + - name: title + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + style: form + explode: false + allowReserved: false + - name: author + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + style: form + explode: false + allowReserved: false + deprecated: false + post: + operationId: postBookCollection + tags: + - Book + responses: + '201': + description: Book resource created + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld-book.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/csv: + schema: + $ref: '#/components/schemas/Book-book.read' + text/html: + schema: + $ref: '#/components/schemas/Book-book.read' + links: + GetBookItem: + operationId: getBookItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /books/{id}`. + '400': + description: Invalid input + '422': + description: Unprocessable entity + summary: Creates a Book resource. + description: Creates a Book resource. + parameters: [] + requestBody: + description: The new Book resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Book' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book' + application/json: + schema: + $ref: '#/components/schemas/Book' + application/xml: + schema: + $ref: '#/components/schemas/Book' + text/xml: + schema: + $ref: '#/components/schemas/Book' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book' + text/csv: + schema: + $ref: '#/components/schemas/Book' + text/html: + schema: + $ref: '#/components/schemas/Book' + required: true + deprecated: false + parameters: [] + /books/{id}: + get: + operationId: getBookItem + tags: + - Book + responses: + '200': + description: Book resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld-book.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/csv: + schema: + $ref: '#/components/schemas/Book-book.read' + text/html: + schema: + $ref: '#/components/schemas/Book-book.read' + '404': + description: Resource not found + summary: Retrieves a Book resource. + description: Retrieves a Book resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: false + put: + operationId: putBookItem + tags: + - Book + responses: + '200': + description: Book resource updated + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld-book.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/csv: + schema: + $ref: '#/components/schemas/Book-book.read' + text/html: + schema: + $ref: '#/components/schemas/Book-book.read' + links: + GetBookItem: + operationId: getBookItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /books/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Replaces the Book resource. + description: Replaces the Book resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Book resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Book' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book' + application/json: + schema: + $ref: '#/components/schemas/Book' + application/xml: + schema: + $ref: '#/components/schemas/Book' + text/xml: + schema: + $ref: '#/components/schemas/Book' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book' + text/csv: + schema: + $ref: '#/components/schemas/Book' + text/html: + schema: + $ref: '#/components/schemas/Book' + required: true + deprecated: false + delete: + operationId: deleteBookItem + tags: + - Book + responses: + '204': + description: Book resource deleted + '404': + description: Resource not found + summary: Removes the Book resource. + description: Removes the Book resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: false + patch: + operationId: patchBookItem + tags: + - Book + responses: + '200': + description: Book resource updated + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld-book.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/json: + schema: + $ref: '#/components/schemas/Book-book.read' + application/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/xml: + schema: + $ref: '#/components/schemas/Book-book.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book-book.read' + text/csv: + schema: + $ref: '#/components/schemas/Book-book.read' + text/html: + schema: + $ref: '#/components/schemas/Book-book.read' + links: + GetBookItem: + operationId: getBookItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /books/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Updates the Book resource. + description: Updates the Book resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Book resource + content: + application/merge-patch+json: + schema: + $ref: '#/components/schemas/Book' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book' + required: true + deprecated: false + parameters: [] + /books/{id}/generate-cover: + put: + operationId: generate_coverBookItem + tags: + - Book + responses: + '204': + description: Book resource updated + content: + application/ld+json: + schema: {} + application/hal+json: + schema: {} + application/vnd.api+json: + schema: {} + application/json: + schema: {} + application/xml: + schema: {} + text/xml: + schema: {} + application/x-yaml: + schema: {} + text/csv: + schema: {} + text/html: + schema: {} + links: + GetBookItem: + operationId: getBookItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /books/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Replaces the Book resource. + description: Replaces the Book resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Book resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Book.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Book' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Book' + application/json: + schema: + $ref: '#/components/schemas/Book' + application/xml: + schema: + $ref: '#/components/schemas/Book' + text/xml: + schema: + $ref: '#/components/schemas/Book' + application/x-yaml: + schema: + $ref: '#/components/schemas/Book' + text/csv: + schema: + $ref: '#/components/schemas/Book' + text/html: + schema: + $ref: '#/components/schemas/Book' + required: true + deprecated: false + parameters: [] + /books/{id}/reviews: + get: + operationId: api_books_reviews_get_subresourceBookSubresource + tags: + - Review + - Book + responses: + '200': + description: Book resource + content: + application/ld+json: + schema: + type: object + properties: + hydra:member: + type: array + items: + $ref: '#/components/schemas/Review.jsonld-review.read' + hydra:totalItems: + type: integer + minimum: 0 + hydra:view: + type: object + properties: + '@id': + type: string + format: iri-reference + '@type': + type: string + hydra:first: + type: string + format: iri-reference + hydra:last: + type: string + format: iri-reference + hydra:previous: + type: string + format: iri-reference + hydra:next: + type: string + format: iri-reference + hydra:search: + type: object + properties: + '@type': + type: string + hydra:template: + type: string + hydra:variableRepresentation: + type: string + hydra:mapping: + type: array + items: + type: object + properties: + '@type': + type: string + variable: + type: string + property: + type: string + nullable: true + required: + type: boolean + required: + - hydra:member + application/hal+json: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/vnd.api+json: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + text/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/x-yaml: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + text/csv: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + text/html: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + summary: Retrieves a Book resource. + description: Retrieves a Book resource. + parameters: + - name: id + in: path + description: Book identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + - name: page + in: query + description: The collection page number + required: false + deprecated: false + allowEmptyValue: true + schema: + type: integer + default: 1 + style: form + explode: false + allowReserved: false + - name: order[id] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: order[publicationDate] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: book + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + style: form + explode: false + allowReserved: false + - name: book[] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: array + items: + type: string + style: form + explode: true + allowReserved: false + deprecated: false + parameters: [] + /parchments: + get: + operationId: getParchmentCollection + tags: + - Parchment + responses: + '200': + description: Parchment collection + content: + application/ld+json: + schema: + type: object + properties: + hydra:member: + type: array + items: + $ref: '#/components/schemas/Parchment.jsonld' + hydra:totalItems: + type: integer + minimum: 0 + hydra:view: + type: object + properties: + '@id': + type: string + format: iri-reference + '@type': + type: string + hydra:first: + type: string + format: iri-reference + hydra:last: + type: string + format: iri-reference + hydra:previous: + type: string + format: iri-reference + hydra:next: + type: string + format: iri-reference + hydra:search: + type: object + properties: + '@type': + type: string + hydra:template: + type: string + hydra:variableRepresentation: + type: string + hydra:mapping: + type: array + items: + type: object + properties: + '@type': + type: string + variable: + type: string + property: + type: string + nullable: true + required: + type: boolean + required: + - hydra:member + application/hal+json: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + type: array + items: + $ref: '#/components/schemas/Parchment' + summary: Retrieves the collection of Parchment resources. + description: Retrieves the collection of Parchment resources. + parameters: + - name: page + in: query + description: The collection page number + required: false + deprecated: false + allowEmptyValue: true + schema: + type: integer + default: 1 + style: form + explode: false + allowReserved: false + deprecated: true + post: + operationId: postParchmentCollection + tags: + - Parchment + responses: + '201': + description: Parchment resource created + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Parchment.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + $ref: '#/components/schemas/Parchment' + links: + GetParchmentItem: + operationId: getParchmentItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /parchments/{id}`. + '400': + description: Invalid input + '422': + description: Unprocessable entity + summary: Creates a Parchment resource. + description: Creates a Parchment resource. + parameters: [] + requestBody: + description: The new Parchment resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Parchment.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + $ref: '#/components/schemas/Parchment' + required: true + deprecated: true + parameters: [] + /parchments/{id}: + get: + operationId: getParchmentItem + tags: + - Parchment + responses: + '200': + description: Parchment resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Parchment.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + $ref: '#/components/schemas/Parchment' + '404': + description: Resource not found + summary: Retrieves a Parchment resource. + description: Retrieves a Parchment resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: true + put: + operationId: putParchmentItem + tags: + - Parchment + responses: + '200': + description: Parchment resource updated + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Parchment.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + $ref: '#/components/schemas/Parchment' + links: + GetParchmentItem: + operationId: getParchmentItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /parchments/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Replaces the Parchment resource. + description: Replaces the Parchment resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Parchment resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Parchment.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + $ref: '#/components/schemas/Parchment' + required: true + deprecated: true + delete: + operationId: deleteParchmentItem + tags: + - Parchment + responses: + '204': + description: Parchment resource deleted + '404': + description: Resource not found + summary: Removes the Parchment resource. + description: Removes the Parchment resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: true + patch: + operationId: patchParchmentItem + tags: + - Parchment + responses: + '200': + description: Parchment resource updated + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Parchment.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + application/json: + schema: + $ref: '#/components/schemas/Parchment' + application/xml: + schema: + $ref: '#/components/schemas/Parchment' + text/xml: + schema: + $ref: '#/components/schemas/Parchment' + application/x-yaml: + schema: + $ref: '#/components/schemas/Parchment' + text/csv: + schema: + $ref: '#/components/schemas/Parchment' + text/html: + schema: + $ref: '#/components/schemas/Parchment' + links: + GetParchmentItem: + operationId: getParchmentItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /parchments/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Updates the Parchment resource. + description: Updates the Parchment resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Parchment resource + content: + application/merge-patch+json: + schema: + $ref: '#/components/schemas/Parchment' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Parchment' + required: true + deprecated: true + parameters: [] + /reviews: + get: + operationId: getReviewCollection + tags: + - Review + responses: + '200': + description: Review collection + content: + application/ld+json: + schema: + type: object + properties: + hydra:member: + type: array + items: + $ref: '#/components/schemas/Review.jsonld-review.read' + hydra:totalItems: + type: integer + minimum: 0 + hydra:view: + type: object + properties: + '@id': + type: string + format: iri-reference + '@type': + type: string + hydra:first: + type: string + format: iri-reference + hydra:last: + type: string + format: iri-reference + hydra:previous: + type: string + format: iri-reference + hydra:next: + type: string + format: iri-reference + hydra:search: + type: object + properties: + '@type': + type: string + hydra:template: + type: string + hydra:variableRepresentation: + type: string + hydra:mapping: + type: array + items: + type: object + properties: + '@type': + type: string + variable: + type: string + property: + type: string + nullable: true + required: + type: boolean + required: + - hydra:member + application/hal+json: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/vnd.api+json: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + text/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + application/x-yaml: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + text/csv: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + text/html: + schema: + type: array + items: + $ref: '#/components/schemas/Review-review.read' + summary: Retrieves the collection of Review resources. + description: Retrieves the collection of Review resources. + parameters: + - name: page + in: query + description: The collection page number + required: false + deprecated: false + allowEmptyValue: true + schema: + type: integer + default: 1 + style: form + explode: false + allowReserved: false + - name: order[id] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: order[publicationDate] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + enum: + - asc + - desc + style: form + explode: false + allowReserved: false + - name: book + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: string + style: form + explode: false + allowReserved: false + - name: book[] + in: query + description: '' + required: false + deprecated: false + allowEmptyValue: true + schema: + type: array + items: + type: string + style: form + explode: true + allowReserved: false + deprecated: false + post: + operationId: postReviewCollection + tags: + - Review + responses: + '201': + description: Review resource created + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Review.jsonld-review.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/csv: + schema: + $ref: '#/components/schemas/Review-review.read' + text/html: + schema: + $ref: '#/components/schemas/Review-review.read' + links: + GetReviewItem: + operationId: getReviewItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /reviews/{id}`. + '400': + description: Invalid input + '422': + description: Unprocessable entity + summary: Creates a Review resource. + description: Creates a Review resource. + parameters: [] + requestBody: + description: The new Review resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Review.jsonld-review.write' + application/hal+json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/xml: + schema: + $ref: '#/components/schemas/Review-review.write' + text/xml: + schema: + $ref: '#/components/schemas/Review-review.write' + application/x-yaml: + schema: + $ref: '#/components/schemas/Review-review.write' + text/csv: + schema: + $ref: '#/components/schemas/Review-review.write' + text/html: + schema: + $ref: '#/components/schemas/Review-review.write' + required: true + deprecated: false + parameters: [] + /reviews/{id}: + get: + operationId: getReviewItem + tags: + - Review + responses: + '200': + description: Review resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Review.jsonld-review.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/csv: + schema: + $ref: '#/components/schemas/Review-review.read' + text/html: + schema: + $ref: '#/components/schemas/Review-review.read' + '404': + description: Resource not found + summary: Retrieves a Review resource. + description: Retrieves a Review resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: false + put: + operationId: putReviewItem + tags: + - Review + responses: + '200': + description: Review resource updated + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Review.jsonld-review.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/csv: + schema: + $ref: '#/components/schemas/Review-review.read' + text/html: + schema: + $ref: '#/components/schemas/Review-review.read' + links: + GetReviewItem: + operationId: getReviewItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /reviews/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Replaces the Review resource. + description: Replaces the Review resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Review resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Review.jsonld-review.write' + application/hal+json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/xml: + schema: + $ref: '#/components/schemas/Review-review.write' + text/xml: + schema: + $ref: '#/components/schemas/Review-review.write' + application/x-yaml: + schema: + $ref: '#/components/schemas/Review-review.write' + text/csv: + schema: + $ref: '#/components/schemas/Review-review.write' + text/html: + schema: + $ref: '#/components/schemas/Review-review.write' + required: true + deprecated: false + delete: + operationId: deleteReviewItem + tags: + - Review + responses: + '204': + description: Review resource deleted + '404': + description: Resource not found + summary: Removes the Review resource. + description: Removes the Review resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: false + patch: + operationId: patchReviewItem + tags: + - Review + responses: + '200': + description: Review resource updated + content: + application/ld+json: + schema: + $ref: '#/components/schemas/Review.jsonld-review.read' + application/hal+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/json: + schema: + $ref: '#/components/schemas/Review-review.read' + application/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/xml: + schema: + $ref: '#/components/schemas/Review-review.read' + application/x-yaml: + schema: + $ref: '#/components/schemas/Review-review.read' + text/csv: + schema: + $ref: '#/components/schemas/Review-review.read' + text/html: + schema: + $ref: '#/components/schemas/Review-review.read' + links: + GetReviewItem: + operationId: getReviewItem + parameters: + id: $response.body#/id + description: The `id` value returned in the response can be used as the `id` parameter in `GET /reviews/{id}`. + '400': + description: Invalid input + '404': + description: Resource not found + '422': + description: Unprocessable entity + summary: Updates the Review resource. + description: Updates the Review resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + requestBody: + description: The updated Review resource + content: + application/merge-patch+json: + schema: + $ref: '#/components/schemas/Review-review.write' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/Review-review.write' + required: true + deprecated: false + parameters: [] + /stats: + get: + operationId: get + tags: + - Stats + responses: + '200': + content: + application/json: + schema: + type: object + properties: + books_count: + type: integer + example: 997 + topbooks_count: + type: integer + example: 101 + summary: Retrieves the number of books and top books (legacy endpoint). + description: '' + parameters: [] + deprecated: false + parameters: [] + /top_books: + get: + operationId: getTopBookCollection + tags: + - TopBook + responses: + '200': + description: TopBook collection + content: + application/ld+json: + schema: + type: object + properties: + hydra:member: + type: array + items: + $ref: '#/components/schemas/TopBook.jsonld' + hydra:totalItems: + type: integer + minimum: 0 + hydra:view: + type: object + properties: + '@id': + type: string + format: iri-reference + '@type': + type: string + hydra:first: + type: string + format: iri-reference + hydra:last: + type: string + format: iri-reference + hydra:previous: + type: string + format: iri-reference + hydra:next: + type: string + format: iri-reference + hydra:search: + type: object + properties: + '@type': + type: string + hydra:template: + type: string + hydra:variableRepresentation: + type: string + hydra:mapping: + type: array + items: + type: object + properties: + '@type': + type: string + variable: + type: string + property: + type: string + nullable: true + required: + type: boolean + required: + - hydra:member + application/hal+json: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + application/vnd.api+json: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + text/xml: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + application/x-yaml: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + text/csv: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + text/html: + schema: + type: array + items: + $ref: '#/components/schemas/TopBook' + summary: Retrieves the collection of TopBook resources. + description: Retrieves the collection of TopBook resources. + parameters: + - name: page + in: query + description: The collection page number + required: false + deprecated: false + allowEmptyValue: true + schema: + type: integer + default: 1 + style: form + explode: false + allowReserved: false + deprecated: false + parameters: [] + /top_books/{id}: + get: + operationId: getTopBookItem + tags: + - TopBook + responses: + '200': + description: TopBook resource + content: + application/ld+json: + schema: + $ref: '#/components/schemas/TopBook.jsonld' + application/hal+json: + schema: + $ref: '#/components/schemas/TopBook' + application/vnd.api+json: + schema: + $ref: '#/components/schemas/TopBook' + application/json: + schema: + $ref: '#/components/schemas/TopBook' + application/xml: + schema: + $ref: '#/components/schemas/TopBook' + text/xml: + schema: + $ref: '#/components/schemas/TopBook' + application/x-yaml: + schema: + $ref: '#/components/schemas/TopBook' + text/csv: + schema: + $ref: '#/components/schemas/TopBook' + text/html: + schema: + $ref: '#/components/schemas/TopBook' + '404': + description: Resource not found + summary: Retrieves a TopBook resource. + description: Retrieves a TopBook resource. + parameters: + - name: id + in: path + description: Resource identifier + required: true + deprecated: false + allowEmptyValue: false + schema: + type: string + style: simple + explode: false + allowReserved: false + deprecated: false + parameters: [] +components: + schemas: + Book: + type: object + description: '' + externalDocs: + url: https://schema.org/Book + properties: + isbn: + description: The ISBN of the book. + externalDocs: + url: https://schema.org/isbn + type: string + nullable: true + title: + description: The title of the book. + externalDocs: + url: https://schema.org/name + type: string + description: + description: A description of the item. + externalDocs: + url: https://schema.org/description + type: string + author: + description: The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably. + externalDocs: + url: https://schema.org/author + type: string + publicationDate: + description: The date on which the CreativeWork was created or the item was added to a DataFeed. + externalDocs: + url: https://schema.org/dateCreated + type: string + format: date-time + reviews: + description: The book's reviews. + externalDocs: + url: https://schema.org/reviews + type: array + items: + $ref: '#/components/schemas/Review' + cover: + writeOnly: true + description: The book's cover base64 encoded. + type: string + nullable: true + archivedAt: + writeOnly: true + type: string + format: date-time + nullable: true + required: + - title + - description + - author + - publicationDate + Book-book.read: + type: object + description: '' + externalDocs: + url: https://schema.org/Book + properties: + isbn: + description: The ISBN of the book. + externalDocs: + url: https://schema.org/isbn + type: string + nullable: true + title: + description: The title of the book. + externalDocs: + url: https://schema.org/name + type: string + description: + description: A description of the item. + externalDocs: + url: https://schema.org/description + type: string + author: + description: The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably. + externalDocs: + url: https://schema.org/author + type: string + publicationDate: + description: The date on which the CreativeWork was created or the item was added to a DataFeed. + externalDocs: + url: https://schema.org/dateCreated + type: string + format: date-time + reviews: + description: The book's reviews. + externalDocs: + url: https://schema.org/reviews + type: array + items: + $ref: '#/components/schemas/Review-book.read' + required: + - title + - description + - author + - publicationDate + Book-review.read: + type: object + description: '' + externalDocs: + url: https://schema.org/Book + required: + - title + properties: + title: + description: The title of the book. + externalDocs: + url: https://schema.org/name + type: string + Book.jsonld: + type: object + description: '' + externalDocs: + url: https://schema.org/Book + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + isbn: + description: The ISBN of the book. + externalDocs: + url: https://schema.org/isbn + type: string + nullable: true + title: + description: The title of the book. + externalDocs: + url: https://schema.org/name + type: string + description: + description: A description of the item. + externalDocs: + url: https://schema.org/description + type: string + author: + description: The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably. + externalDocs: + url: https://schema.org/author + type: string + publicationDate: + description: The date on which the CreativeWork was created or the item was added to a DataFeed. + externalDocs: + url: https://schema.org/dateCreated + type: string + format: date-time + reviews: + description: The book's reviews. + externalDocs: + url: https://schema.org/reviews + type: array + items: + $ref: '#/components/schemas/Review.jsonld' + cover: + writeOnly: true + description: The book's cover base64 encoded. + type: string + nullable: true + archivedAt: + writeOnly: true + type: string + format: date-time + nullable: true + required: + - title + - description + - author + - publicationDate + Book.jsonld-book.read: + type: object + description: '' + externalDocs: + url: https://schema.org/Book + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + isbn: + description: The ISBN of the book. + externalDocs: + url: https://schema.org/isbn + type: string + nullable: true + title: + description: The title of the book. + externalDocs: + url: https://schema.org/name + type: string + description: + description: A description of the item. + externalDocs: + url: https://schema.org/description + type: string + author: + description: The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably. + externalDocs: + url: https://schema.org/author + type: string + publicationDate: + description: The date on which the CreativeWork was created or the item was added to a DataFeed. + externalDocs: + url: https://schema.org/dateCreated + type: string + format: date-time + reviews: + description: The book's reviews. + externalDocs: + url: https://schema.org/reviews + type: array + items: + $ref: '#/components/schemas/Review.jsonld-book.read' + required: + - title + - description + - author + - publicationDate + Book.jsonld-review.read: + type: object + description: '' + externalDocs: + url: https://schema.org/Book + required: + - title + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + title: + description: The title of the book. + externalDocs: + url: https://schema.org/name + type: string + Parchment: + type: object + deprecated: true + properties: + id: + readOnly: true + type: string + format: uuid + nullable: true + title: + description: The title of the book. + type: string + description: + description: A description of the item. + type: string + required: + - title + - description + Parchment.jsonld: + type: object + deprecated: true + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + id: + readOnly: true + type: string + format: uuid + nullable: true + title: + description: The title of the book. + type: string + description: + description: A description of the item. + type: string + required: + - title + - description + Review: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + - rating + - book + properties: + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + rating: + description: A rating. + type: integer + letter: + description: 'DEPRECATED (use rating now): A letter to rate the book.' + deprecated: true + type: string + nullable: true + book: + description: The item that is being reviewed/rated. + externalDocs: + url: http://schema.org/itemReviewed + $ref: '#/components/schemas/Book' + author: + description: The author of the review. + externalDocs: + url: http://schema.org/author + type: string + nullable: true + publicationDate: + description: Publication date of the review. + type: string + format: date-time + nullable: true + Review-book.read: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + properties: + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + Review-review.read: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + - rating + - book + properties: + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + rating: + description: A rating. + type: integer + letter: + description: 'DEPRECATED (use rating now): A letter to rate the book.' + deprecated: true + type: string + nullable: true + book: + description: The item that is being reviewed/rated. + externalDocs: + url: http://schema.org/itemReviewed + $ref: '#/components/schemas/Book-review.read' + author: + description: The author of the review. + externalDocs: + url: http://schema.org/author + type: string + nullable: true + publicationDate: + description: Publication date of the review. + type: string + format: date-time + nullable: true + Review-review.write: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + - rating + - book + properties: + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + rating: + description: A rating. + type: integer + letter: + description: 'DEPRECATED (use rating now): A letter to rate the book.' + deprecated: true + type: string + nullable: true + book: + description: The item that is being reviewed/rated. + externalDocs: + url: http://schema.org/itemReviewed + type: string + format: iri-reference + author: + description: The author of the review. + externalDocs: + url: http://schema.org/author + type: string + nullable: true + publicationDate: + description: Publication date of the review. + type: string + format: date-time + nullable: true + Review.jsonld: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + - rating + - book + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + rating: + description: A rating. + type: integer + letter: + description: 'DEPRECATED (use rating now): A letter to rate the book.' + deprecated: true + type: string + nullable: true + book: + description: The item that is being reviewed/rated. + externalDocs: + url: http://schema.org/itemReviewed + $ref: '#/components/schemas/Book.jsonld' + author: + description: The author of the review. + externalDocs: + url: http://schema.org/author + type: string + nullable: true + publicationDate: + description: Publication date of the review. + type: string + format: date-time + nullable: true + Review.jsonld-book.read: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + Review.jsonld-review.read: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + - rating + - book + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + rating: + description: A rating. + type: integer + letter: + description: 'DEPRECATED (use rating now): A letter to rate the book.' + deprecated: true + type: string + nullable: true + book: + description: The item that is being reviewed/rated. + externalDocs: + url: http://schema.org/itemReviewed + $ref: '#/components/schemas/Book.jsonld-review.read' + author: + description: The author of the review. + externalDocs: + url: http://schema.org/author + type: string + nullable: true + publicationDate: + description: Publication date of the review. + type: string + format: date-time + nullable: true + Review.jsonld-review.write: + type: object + description: A review of an item - for example, of a restaurant, movie, or store. + externalDocs: + url: http://schema.org/Review + required: + - body + - rating + - book + properties: + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + body: + description: The actual body of the review. + externalDocs: + url: http://schema.org/reviewBody + type: string + rating: + description: A rating. + type: integer + letter: + description: 'DEPRECATED (use rating now): A letter to rate the book.' + deprecated: true + type: string + nullable: true + book: + description: The item that is being reviewed/rated. + externalDocs: + url: http://schema.org/itemReviewed + type: string + format: iri-reference + author: + description: The author of the review. + externalDocs: + url: http://schema.org/author + type: string + nullable: true + publicationDate: + description: Publication date of the review. + type: string + format: date-time + nullable: true + TopBook: + type: object + description: This entity represents a "most borrowed book" in a given a given French library. + properties: + id: + type: integer + title: + type: string + author: + type: string + part: + type: string + place: + type: string + borrowCount: + type: integer + TopBook.jsonld: + type: object + description: This entity represents a "most borrowed book" in a given a given French library. + properties: + '@id': + readOnly: true + type: string + '@type': + readOnly: true + type: string + '@context': + readOnly: true + oneOf: + - type: string + - type: object + properties: + '@vocab': + type: string + hydra: + type: string + enum: + - http://www.w3.org/ns/hydra/core# + required: + - '@vocab' + - hydra + additionalProperties: true + id: + type: integer + title: + type: string + author: + type: string + part: + type: string + place: + type: string + borrowCount: + type: integer + responses: {} + parameters: {} + examples: {} + requestBodies: {} + headers: {} + securitySchemes: + apiKey: + type: apiKey + description: Value for the Authorization header parameter. + name: Authorization + in: header +security: + - apiKey: [] +tags: [] diff --git a/tests/e2e/openapi_ref.yml b/tests/e2e/openapi_ref.yml new file mode 100644 index 00000000..915c4a4c --- /dev/null +++ b/tests/e2e/openapi_ref.yml @@ -0,0 +1,800 @@ +openapi: 3.0.2 +info: + title: Swagger Petstore - OpenAPI 3.0 + description: |- + This is a sample Pet Store Server based on the OpenAPI 3.0 specification. You can find out more about + Swagger at [http://swagger.io](http://swagger.io). In the third iteration of the pet store, we've switched to the design first approach! + You can now help us improve the API whether it's by making changes to the definition itself or to the code. + That way, with time, we can improve the API in general, and expose some of the new features in OAS3. + + Some useful links: + - [The Pet Store repository](https://github.com/swagger-api/swagger-petstore) + - [The source API definition for the Pet Store](https://github.com/swagger-api/swagger-petstore/blob/master/src/main/resources/openapi.yaml) + termsOfService: http://swagger.io/terms/ + contact: + email: apiteam@swagger.io + license: + name: Apache 2.0 + url: http://www.apache.org/licenses/LICENSE-2.0.html + version: 1.0.11 +externalDocs: + description: Find out more about Swagger + url: http://swagger.io +servers: + - url: /api/v3 +tags: + - name: pet + description: Everything about your Pets + externalDocs: + description: Find out more + url: http://swagger.io + - name: store + description: Access to Petstore orders + externalDocs: + description: Find out more about our store + url: http://swagger.io + - name: user + description: Operations about user +paths: + /pet: + put: + tags: + - pet + summary: Update an existing pet + description: Update an existing pet by Id + operationId: updatePet + requestBody: + description: Update an existent pet in the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + '405': + description: Validation exception + security: + - petstore_auth: + - write:pets + - read:pets + post: + tags: + - pet + summary: Add a new pet to the store + description: Add a new pet to the store + operationId: addPet + requestBody: + description: Create a new pet in the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Pet' + required: true + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '405': + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + /pet/findByStatus: + get: + tags: + - pet + summary: Finds Pets by status + description: Multiple status values can be provided with comma separated strings + operationId: findPetsByStatus + parameters: + - name: status + in: query + description: Status values that need to be considered for filter + required: false + explode: true + schema: + type: string + default: available + enum: + - available + - pending + - sold + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid status value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/findByTags: + get: + tags: + - pet + summary: Finds Pets by tags + description: Multiple tags can be provided with comma separated strings. Use tag1, tag2, tag3 for testing. + operationId: findPetsByTags + parameters: + - name: tags + in: query + description: Tags to filter by + required: false + explode: true + schema: + type: array + items: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid tag value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/{petId}: + get: + tags: + - pet + summary: Find pet by ID + description: Returns a single pet + operationId: getPetById + parameters: + - name: petId + in: path + description: ID of pet to return + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Pet' + application/json: + schema: + $ref: '#/components/schemas/Pet' + '400': + description: Invalid ID supplied + '404': + description: Pet not found + security: + - api_key: [] + - petstore_auth: + - write:pets + - read:pets + post: + tags: + - pet + summary: Updates a pet in the store with form data + description: '' + operationId: updatePetWithForm + parameters: + - name: petId + in: path + description: ID of pet that needs to be updated + required: true + schema: + type: integer + format: int64 + - name: name + in: query + description: Name of pet that needs to be updated + schema: + type: string + - name: status + in: query + description: Status of pet that needs to be updated + schema: + type: string + responses: + '405': + description: Invalid input + security: + - petstore_auth: + - write:pets + - read:pets + delete: + tags: + - pet + summary: Deletes a pet + description: '' + operationId: deletePet + parameters: + - name: api_key + in: header + description: '' + required: false + schema: + type: string + - name: petId + in: path + description: Pet id to delete + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid pet value + security: + - petstore_auth: + - write:pets + - read:pets + /pet/{petId}/uploadImage: + post: + tags: + - pet + summary: uploads an image + description: '' + operationId: uploadFile + parameters: + - name: petId + in: path + description: ID of pet to update + required: true + schema: + type: integer + format: int64 + - name: additionalMetadata + in: query + description: Additional Metadata + required: false + schema: + type: string + requestBody: + content: + application/octet-stream: + schema: + type: string + format: binary + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/ApiResponse' + security: + - petstore_auth: + - write:pets + - read:pets + /store/inventory: + get: + tags: + - store + summary: Returns pet inventories by status + description: Returns a map of status codes to quantities + operationId: getInventory + responses: + '200': + description: successful operation + content: + application/json: + schema: + type: object + additionalProperties: + type: integer + format: int32 + security: + - api_key: [] + /store/order: + post: + tags: + - store + summary: Place an order for a pet + description: Place a new order in the store + operationId: placeOrder + requestBody: + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/Order' + responses: + '200': + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/Order' + '405': + description: Invalid input + /store/order/{orderId}: + get: + tags: + - store + summary: Find purchase order by ID + description: For valid response try integer IDs with value <= 5 or > 10. Other values will generate exceptions. + operationId: getOrderById + parameters: + - name: orderId + in: path + description: ID of order that needs to be fetched + required: true + schema: + type: integer + format: int64 + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/Order' + application/json: + schema: + $ref: '#/components/schemas/Order' + '400': + description: Invalid ID supplied + '404': + description: Order not found + delete: + tags: + - store + summary: Delete purchase order by ID + description: For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors + operationId: deleteOrder + parameters: + - name: orderId + in: path + description: ID of the order that needs to be deleted + required: true + schema: + type: integer + format: int64 + responses: + '400': + description: Invalid ID supplied + '404': + description: Order not found + /user: + post: + tags: + - user + summary: Create user + description: This can only be done by the logged in user. + operationId: createUser + requestBody: + description: Created user object + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/User' + responses: + default: + description: successful operation + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + /user/createWithList: + post: + tags: + - user + summary: Creates list of users with given input array + description: Creates list of users with given input array + operationId: createUsersWithListInput + requestBody: + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + responses: + '200': + description: Successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + default: + description: successful operation + /user/login: + get: + tags: + - user + summary: Logs user into the system + description: '' + operationId: loginUser + parameters: + - name: username + in: query + description: The user name for login + required: false + schema: + type: string + - name: password + in: query + description: The password for login in clear text + required: false + schema: + type: string + responses: + '200': + description: successful operation + headers: + X-Rate-Limit: + description: calls per hour allowed by the user + schema: + type: integer + format: int32 + X-Expires-After: + description: date in UTC when token expires + schema: + type: string + format: date-time + content: + application/xml: + schema: + type: string + application/json: + schema: + type: string + '400': + description: Invalid username/password supplied + /user/logout: + get: + tags: + - user + summary: Logs out current logged in user session + description: '' + operationId: logoutUser + parameters: [] + responses: + default: + description: successful operation + /user/{username}: + get: + tags: + - user + summary: Get user by user name + description: '' + operationId: getUserByName + parameters: + - name: username + in: path + description: 'The name that needs to be fetched. Use user1 for testing. ' + required: true + schema: + type: string + responses: + '200': + description: successful operation + content: + application/xml: + schema: + $ref: '#/components/schemas/User' + application/json: + schema: + $ref: '#/components/schemas/User' + '400': + description: Invalid username supplied + '404': + description: User not found + put: + tags: + - user + summary: Update user + description: This can only be done by the logged in user. + operationId: updateUser + parameters: + - name: username + in: path + description: name that need to be deleted + required: true + schema: + type: string + requestBody: + description: Update an existent user in the store + content: + application/json: + schema: + $ref: '#/components/schemas/User' + application/xml: + schema: + $ref: '#/components/schemas/User' + application/x-www-form-urlencoded: + schema: + $ref: '#/components/schemas/User' + responses: + default: + description: successful operation + delete: + tags: + - user + summary: Delete user + description: This can only be done by the logged in user. + operationId: deleteUser + parameters: + - name: username + in: path + description: The name that needs to be deleted + required: true + schema: + type: string + responses: + '400': + description: Invalid username supplied + '404': + description: User not found +components: + schemas: + Order: + type: object + properties: + id: + type: integer + format: int64 + example: 10 + petId: + type: integer + format: int64 + example: 198772 + quantity: + type: integer + format: int32 + example: 7 + shipDate: + type: string + format: date-time + status: + type: string + description: Order Status + example: approved + enum: + - placed + - approved + - delivered + complete: + type: boolean + xml: + name: order + Customer: + type: object + properties: + id: + type: integer + format: int64 + example: 100000 + username: + type: string + example: fehguy + address: + type: array + xml: + name: addresses + wrapped: true + items: + $ref: '#/components/schemas/Address' + xml: + name: customer + Address: + type: object + properties: + street: + type: string + example: 437 Lytton + city: + type: string + example: Palo Alto + state: + type: string + example: CA + zip: + type: string + example: '94301' + xml: + name: address + Category: + type: object + properties: + id: + type: integer + format: int64 + example: 1 + name: + type: string + example: Dogs + xml: + name: category + User: + type: object + properties: + id: + type: integer + format: int64 + example: 10 + username: + type: string + example: theUser + firstName: + type: string + example: John + lastName: + type: string + example: James + email: + type: string + example: john@email.com + password: + type: string + example: '12345' + phone: + type: string + example: '12345' + userStatus: + type: integer + description: User Status + format: int32 + example: 1 + xml: + name: user + Tag: + type: object + properties: + id: + type: integer + format: int64 + name: + type: string + xml: + name: tag + Pet: + required: + - name + - photoUrls + type: object + properties: + id: + type: integer + format: int64 + example: 10 + name: + type: string + example: doggie + category: + $ref: '#/components/schemas/Category' + photoUrls: + type: array + xml: + wrapped: true + items: + type: string + xml: + name: photoUrl + tags: + type: array + xml: + wrapped: true + items: + $ref: '#/components/schemas/Tag' + status: + type: string + description: pet status in the store + enum: + - available + - pending + - sold + xml: + name: pet + ApiResponse: + type: object + properties: + code: + type: integer + format: int32 + type: + type: string + message: + type: string + xml: + name: '##default' + requestBodies: + Pet: + description: Pet object that needs to be added to the store + content: + application/json: + schema: + $ref: '#/components/schemas/Pet' + application/xml: + schema: + $ref: '#/components/schemas/Pet' + UserArray: + description: List of user object + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + securitySchemes: + petstore_auth: + type: oauth2 + flows: + implicit: + authorizationUrl: https://petstore3.swagger.io/oauth/authorize + scopes: + write:pets: modify pets in your account + read:pets: read your pets + api_key: + type: apiKey + name: api_key + in: header diff --git a/tests/e2e/original/App/OpenApi/Entity/Book.php b/tests/e2e/original/App/OpenApi/Entity/Book.php new file mode 100644 index 00000000..c420a783 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/Book.php @@ -0,0 +1,190 @@ + [], 'put' => [], 'patch' => [], 'delete' => []], + collectionOperations: ['get' => [], 'post' => []], +)] +class Book +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + /** + * The ISBN of the book. + * + * @see https://schema.org/isbn + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'https://schema.org/isbn')] + private ?string $isbn = null; + + /** + * The title of the book. + * + * @see https://schema.org/name + */ + #[ORM\Column(type: 'text')] + #[ApiProperty(iri: 'https://schema.org/name')] + #[Assert\NotNull] + private string $title; + + /** + * A description of the item. + * + * @see https://schema.org/description + */ + #[ORM\Column(type: 'text')] + #[ApiProperty(iri: 'https://schema.org/description')] + #[Assert\NotNull] + private string $description; + + /** + * The author of this content or rating. Please note that author is special in that HTML 5 provides a special mechanism for indicating authorship via the rel tag. That is equivalent to this and may be used interchangeably. + * + * @see https://schema.org/author + */ + #[ORM\Column(type: 'text')] + #[ApiProperty(iri: 'https://schema.org/author')] + #[Assert\NotNull] + private string $author; + + /** + * The date on which the CreativeWork was created or the item was added to a DataFeed. + * + * @see https://schema.org/dateCreated + */ + #[ORM\Column(type: 'date')] + #[ApiProperty(iri: 'https://schema.org/dateCreated')] + #[Assert\Type(\DateTimeInterface::class)] + #[Assert\NotNull] + private \DateTimeInterface $publicationDate; + + /** + * @var Collection the book's reviews + * + * @see https://schema.org/reviews + */ + #[ORM\OneToMany(targetEntity: 'App\OpenApi\Entity\Review', mappedBy: 'book')] + #[ORM\InverseJoinColumn(nullable: false, unique: true)] + #[ApiProperty(iri: 'https://schema.org/reviews')] + #[Assert\NotNull] + private Collection $reviews; + + /** + * The book's cover base64 encoded. + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty] + private ?string $cover = null; + + #[ORM\Column(type: 'date', nullable: true)] + #[ApiProperty] + #[Assert\Type(\DateTimeInterface::class)] + private ?\DateTimeInterface $archivedAt = null; + + public function __construct() + { + $this->reviews = new ArrayCollection(); + } + + public function getId(): ?int + { + return $this->id; + } + + public function setIsbn(?string $isbn): void + { + $this->isbn = $isbn; + } + + public function getIsbn(): ?string + { + return $this->isbn; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } + + public function getTitle(): string + { + return $this->title; + } + + public function setDescription(string $description): void + { + $this->description = $description; + } + + public function getDescription(): string + { + return $this->description; + } + + public function setAuthor(string $author): void + { + $this->author = $author; + } + + public function getAuthor(): string + { + return $this->author; + } + + public function setPublicationDate(\DateTimeInterface $publicationDate): void + { + $this->publicationDate = $publicationDate; + } + + public function getPublicationDate(): \DateTimeInterface + { + return $this->publicationDate; + } + + public function addReview(Review $review): void + { + $this->reviews[] = $review; + } + + public function removeReview(Review $review): void + { + $this->reviews->removeElement($review); + } + + /** + * @return Collection + */ + public function getReviews(): Collection + { + return $this->reviews; + } + + public function setCover(?string $cover): void + { + $this->cover = $cover; + } + + public function setArchivedAt(?\DateTimeInterface $archivedAt): void + { + $this->archivedAt = $archivedAt; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/Order.php b/tests/e2e/original/App/OpenApi/Entity/Order.php new file mode 100644 index 00000000..eec2f20a --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/Order.php @@ -0,0 +1,107 @@ + [], 'delete' => []], collectionOperations: [])] +class Order +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + #[ORM\OneToOne(targetEntity: 'App\OpenApi\Entity\Pet')] + #[ORM\JoinColumn(nullable: false)] + #[ApiProperty] + #[Assert\NotNull] + private Pet $petId; + + #[ORM\Column(type: 'integer')] + #[ApiProperty] + #[Assert\NotNull] + private int $quantity; + + #[ORM\Column(type: 'date')] + #[ApiProperty] + #[Assert\Type(\DateTimeInterface::class)] + #[Assert\NotNull] + private \DateTimeInterface $shipDate; + + /** + * Order Status. + */ + #[ORM\Column] + #[ApiProperty] + #[Assert\NotNull] + #[Assert\Choice(callback: [OrderStatus::class, 'toArray'])] + private OrderStatus $status; + + #[ORM\Column(type: 'boolean')] + #[ApiProperty] + #[Assert\NotNull] + private bool $complete; + + public function getId(): ?int + { + return $this->id; + } + + public function setPetId(Pet $petId): void + { + $this->petId = $petId; + } + + public function getPetId(): Pet + { + return $this->petId; + } + + public function setQuantity(int $quantity): void + { + $this->quantity = $quantity; + } + + public function getQuantity(): int + { + return $this->quantity; + } + + public function setShipDate(\DateTimeInterface $shipDate): void + { + $this->shipDate = $shipDate; + } + + public function getShipDate(): \DateTimeInterface + { + return $this->shipDate; + } + + public function setStatus(OrderStatus $status): void + { + $this->status = $status; + } + + public function getStatus(): OrderStatus + { + return $this->status; + } + + public function setComplete(bool $complete): void + { + $this->complete = $complete; + } + + public function getComplete(): bool + { + return $this->complete; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/Parchment.php b/tests/e2e/original/App/OpenApi/Entity/Parchment.php new file mode 100644 index 00000000..8bb5059c --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/Parchment.php @@ -0,0 +1,64 @@ + [], 'put' => [], 'patch' => [], 'delete' => []], + collectionOperations: ['get' => [], 'post' => []], +)] +class Parchment +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + /** + * The title of the book. + */ + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $title; + + /** + * A description of the item. + */ + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $description; + + public function getId(): ?int + { + return $this->id; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } + + public function getTitle(): string + { + return $this->title; + } + + public function setDescription(string $description): void + { + $this->description = $description; + } + + public function getDescription(): string + { + return $this->description; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/Pet.php b/tests/e2e/original/App/OpenApi/Entity/Pet.php new file mode 100644 index 00000000..15a96916 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/Pet.php @@ -0,0 +1,128 @@ + [], 'delete' => []], collectionOperations: [])] +class Pet +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $name; + + #[ApiProperty] + #[Assert\NotNull] + private string $category; + + /** + * @var string[] + */ + #[ApiProperty] + #[Assert\NotNull] + private array $photoUrls = []; + + /** + * @var string[] + */ + #[ApiProperty] + #[Assert\NotNull] + private array $tags = []; + + /** + * pet status in the store. + */ + #[ORM\Column] + #[ApiProperty] + #[Assert\NotNull] + #[Assert\Choice(callback: [PetStatus::class, 'toArray'])] + private PetStatus $status; + + public function getId(): ?int + { + return $this->id; + } + + public function setName(string $name): void + { + $this->name = $name; + } + + public function getName(): string + { + return $this->name; + } + + public function setCategory(string $category): void + { + $this->category = $category; + } + + public function getCategory(): string + { + return $this->category; + } + + public function addPhotoUrl(string $photoUrl): void + { + $this->photoUrls[] = $photoUrl; + } + + public function removePhotoUrl(string $photoUrl): void + { + if (false !== $key = array_search($photoUrl, $this->photoUrls, true)) { + unset($this->photoUrls[$key]); + } + } + + /** + * @return string[] + */ + public function getPhotoUrls(): array + { + return $this->photoUrls; + } + + public function addTag(string $tag): void + { + $this->tags[] = $tag; + } + + public function removeTag(string $tag): void + { + if (false !== $key = array_search($tag, $this->tags, true)) { + unset($this->tags[$key]); + } + } + + /** + * @return string[] + */ + public function getTags(): array + { + return $this->tags; + } + + public function setStatus(PetStatus $status): void + { + $this->status = $status; + } + + public function getStatus(): PetStatus + { + return $this->status; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/Review.php b/tests/e2e/original/App/OpenApi/Entity/Review.php new file mode 100644 index 00000000..e489d92a --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/Review.php @@ -0,0 +1,145 @@ + [], 'put' => [], 'patch' => [], 'delete' => []], + collectionOperations: ['get' => [], 'post' => []], +)] +class Review +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + /** + * The actual body of the review. + * + * @see http://schema.org/reviewBody + */ + #[ORM\Column(type: 'text')] + #[ApiProperty(iri: 'http://schema.org/reviewBody')] + #[Assert\NotNull] + private string $body; + + /** + * A rating. + */ + #[ORM\Column(type: 'integer')] + #[ApiProperty] + #[Assert\NotNull] + private int $rating; + + /** + * DEPRECATED (use rating now): A letter to rate the book. + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty] + private ?string $letter = null; + + /** + * @see https://schema.org/Book + */ + #[ORM\OneToOne(targetEntity: 'App\OpenApi\Entity\Book')] + #[ORM\JoinColumn(nullable: false)] + #[ApiProperty(iri: 'https://schema.org/Book')] + #[Assert\NotNull] + private Book $book; + + /** + * The author of the review. + * + * @see http://schema.org/author + */ + #[ORM\Column(type: 'text', nullable: true)] + #[ApiProperty(iri: 'http://schema.org/author')] + private ?string $author = null; + + /** + * Publication date of the review. + */ + #[ORM\Column(type: 'date', nullable: true)] + #[ApiProperty] + #[Assert\Type(\DateTimeInterface::class)] + private ?\DateTimeInterface $publicationDate = null; + + public function getId(): ?int + { + return $this->id; + } + + public function setBody(string $body): void + { + $this->body = $body; + } + + public function getBody(): string + { + return $this->body; + } + + public function setRating(int $rating): void + { + $this->rating = $rating; + } + + public function getRating(): int + { + return $this->rating; + } + + public function setLetter(?string $letter): void + { + $this->letter = $letter; + } + + public function getLetter(): ?string + { + return $this->letter; + } + + public function setBook(Book $book): void + { + $this->book = $book; + } + + public function getBook(): Book + { + return $this->book; + } + + public function setAuthor(?string $author): void + { + $this->author = $author; + } + + public function getAuthor(): ?string + { + return $this->author; + } + + public function setPublicationDate(?\DateTimeInterface $publicationDate): void + { + $this->publicationDate = $publicationDate; + } + + public function getPublicationDate(): ?\DateTimeInterface + { + return $this->publicationDate; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/TopBook.php b/tests/e2e/original/App/OpenApi/Entity/TopBook.php new file mode 100644 index 00000000..644f88c2 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/TopBook.php @@ -0,0 +1,103 @@ + []], collectionOperations: ['get' => []])] +class TopBook +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $title; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $author; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $part; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $place; + + #[ORM\Column(type: 'integer')] + #[ApiProperty] + #[Assert\NotNull] + private int $borrowCount; + + public function getId(): ?int + { + return $this->id; + } + + public function setTitle(string $title): void + { + $this->title = $title; + } + + public function getTitle(): string + { + return $this->title; + } + + public function setAuthor(string $author): void + { + $this->author = $author; + } + + public function getAuthor(): string + { + return $this->author; + } + + public function setPart(string $part): void + { + $this->part = $part; + } + + public function getPart(): string + { + return $this->part; + } + + public function setPlace(string $place): void + { + $this->place = $place; + } + + public function getPlace(): string + { + return $this->place; + } + + public function setBorrowCount(int $borrowCount): void + { + $this->borrowCount = $borrowCount; + } + + public function getBorrowCount(): int + { + return $this->borrowCount; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/User.php b/tests/e2e/original/App/OpenApi/Entity/User.php new file mode 100644 index 00000000..bad095dd --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/User.php @@ -0,0 +1,133 @@ + [], 'put' => [], 'delete' => []], collectionOperations: [])] +class User +{ + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $username; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $firstName; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $lastName; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $email; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $password; + + #[ORM\Column(type: 'text')] + #[ApiProperty] + #[Assert\NotNull] + private string $phone; + + /** + * User Status. + */ + #[ORM\Column(type: 'integer')] + #[ApiProperty] + #[Assert\NotNull] + private int $userStatus; + + public function getId(): ?int + { + return $this->id; + } + + public function setUsername(string $username): void + { + $this->username = $username; + } + + public function getUsername(): string + { + return $this->username; + } + + public function setFirstName(string $firstName): void + { + $this->firstName = $firstName; + } + + public function getFirstName(): string + { + return $this->firstName; + } + + public function setLastName(string $lastName): void + { + $this->lastName = $lastName; + } + + public function getLastName(): string + { + return $this->lastName; + } + + public function setEmail(string $email): void + { + $this->email = $email; + } + + public function getEmail(): string + { + return $this->email; + } + + public function setPassword(string $password): void + { + $this->password = $password; + } + + public function getPassword(): string + { + return $this->password; + } + + public function setPhone(string $phone): void + { + $this->phone = $phone; + } + + public function getPhone(): string + { + return $this->phone; + } + + public function setUserStatus(int $userStatus): void + { + $this->userStatus = $userStatus; + } + + public function getUserStatus(): int + { + return $this->userStatus; + } +} diff --git a/tests/e2e/original/App/OpenApi/Enum/OrderStatus.php b/tests/e2e/original/App/OpenApi/Enum/OrderStatus.php new file mode 100644 index 00000000..816dc159 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Enum/OrderStatus.php @@ -0,0 +1,33 @@ +id; + } +} diff --git a/tests/e2e/original/App/OpenApi/Enum/PetStatus.php b/tests/e2e/original/App/OpenApi/Enum/PetStatus.php new file mode 100644 index 00000000..053b2872 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Enum/PetStatus.php @@ -0,0 +1,33 @@ +id; + } +} diff --git a/tests/e2e/customized/App/Entity/Brand.php b/tests/e2e/original/App/Schema/Entity/Brand.php similarity index 97% rename from tests/e2e/customized/App/Entity/Brand.php rename to tests/e2e/original/App/Schema/Entity/Brand.php index a4093a2a..02d9ee4f 100644 --- a/tests/e2e/customized/App/Entity/Brand.php +++ b/tests/e2e/original/App/Schema/Entity/Brand.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; diff --git a/tests/e2e/original/App/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php similarity index 95% rename from tests/e2e/original/App/Entity/Person.php rename to tests/e2e/original/App/Schema/Entity/Person.php index 55416876..34657c59 100644 --- a/tests/e2e/original/App/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -2,11 +2,11 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; -use App\Enum\GenderType; +use App\Schema\Enum\GenderType; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -77,7 +77,7 @@ class Person extends Thing * * @see https://schema.org/address */ - #[ORM\ManyToOne(targetEntity: 'App\Entity\PostalAddress')] + #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] #[ApiProperty(iri: 'https://schema.org/address')] private ?PostalAddress $address = null; @@ -121,11 +121,11 @@ class Person extends Thing private ?string $url = null; /** - * A sibling of the person. + * @var Collection|null a sibling of the person * * @see https://schema.org/siblings */ - #[ORM\ManyToMany(targetEntity: 'App\Entity\Person')] + #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\InverseJoinColumn(unique: true)] #[ApiProperty(iri: 'https://schema.org/siblings')] private ?Collection $siblings = null; @@ -246,6 +246,9 @@ public function removeSibling(Person $sibling): void $this->siblings->removeElement($sibling); } + /** + * @return Collection|null + */ public function getSiblings(): Collection { return $this->siblings; diff --git a/tests/e2e/customized/App/Entity/PostalAddress.php b/tests/e2e/original/App/Schema/Entity/PostalAddress.php similarity index 99% rename from tests/e2e/customized/App/Entity/PostalAddress.php rename to tests/e2e/original/App/Schema/Entity/PostalAddress.php index f17cf43e..d28b672d 100644 --- a/tests/e2e/customized/App/Entity/PostalAddress.php +++ b/tests/e2e/original/App/Schema/Entity/PostalAddress.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use ApiPlatform\Core\Annotation\ApiResource; diff --git a/tests/e2e/original/App/Entity/Thing.php b/tests/e2e/original/App/Schema/Entity/Thing.php similarity index 95% rename from tests/e2e/original/App/Entity/Thing.php rename to tests/e2e/original/App/Schema/Entity/Thing.php index e8405b00..8c1926a7 100644 --- a/tests/e2e/original/App/Entity/Thing.php +++ b/tests/e2e/original/App/Schema/Entity/Thing.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Entity; +namespace App\Schema\Entity; use ApiPlatform\Core\Annotation\ApiProperty; use Doctrine\ORM\Mapping as ORM; diff --git a/tests/e2e/original/App/Enum/GenderType.php b/tests/e2e/original/App/Schema/Enum/GenderType.php similarity index 93% rename from tests/e2e/original/App/Enum/GenderType.php rename to tests/e2e/original/App/Schema/Enum/GenderType.php index bb68634a..f2a24993 100644 --- a/tests/e2e/original/App/Enum/GenderType.php +++ b/tests/e2e/original/App/Schema/Enum/GenderType.php @@ -2,7 +2,7 @@ declare(strict_types=1); -namespace App\Enum; +namespace App\Schema\Enum; use MyCLabs\Enum\Enum; diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index e917a6bd..442592a9 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -1,5 +1,10 @@ # app/config/schema.yml +namespaces: + entity: App\Schema\Entity + enum: App\Schema\Enum + interface: App\Schema\Model + # The list of types and properties we want to use types: # Parent class of Person diff --git a/tests/e2e/schema_openapi.yml b/tests/e2e/schema_openapi.yml new file mode 100644 index 00000000..a2a69342 --- /dev/null +++ b/tests/e2e/schema_openapi.yml @@ -0,0 +1,7 @@ +namespaces: + entity: App\OpenApi\Entity + enum: App\OpenApi\Enum + interface: App\OpenApi\Model + +openApi: + file: './openapi.yml' diff --git a/tests/e2e/schema_openapi_ref.yml b/tests/e2e/schema_openapi_ref.yml new file mode 100644 index 00000000..10ab31ce --- /dev/null +++ b/tests/e2e/schema_openapi_ref.yml @@ -0,0 +1,7 @@ +namespaces: + entity: App\OpenApi\Entity + enum: App\OpenApi\Enum + interface: App\OpenApi\Model + +openApi: + file: './openapi_ref.yml' From 57441daf99c035a86558b6f9be9ed744243340bd Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 9 Jun 2022 12:11:32 +0200 Subject: [PATCH 206/258] fix: do not generate property when range is missing (#369) --- src/ClassMutator/ClassPropertiesAppender.php | 4 +++- src/OpenApi/ClassGenerator.php | 4 +++- src/OpenApi/PropertyGenerator/PropertyGenerator.php | 2 +- src/PropertyGenerator/PropertyGenerator.php | 2 +- src/PropertyGenerator/PropertyGeneratorInterface.php | 2 +- src/Schema/PropertyGenerator/PropertyGenerator.php | 4 ++-- 6 files changed, 11 insertions(+), 7 deletions(-) diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 4c82693b..4a31ae6d 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -129,7 +129,9 @@ private function generateField(array $config, SchemaClass $class, RdfResource $t { $property = ($this->propertyGenerator)($typeProperty->localName(), $config, $class, ['type' => $type, 'typeConfig' => $typeConfig, 'property' => $typeProperty], $isCustom); - $class->addProperty($property); + if ($property) { + $class->addProperty($property); + } } /** diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 876a48e6..6a642663 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -227,7 +227,9 @@ private function buildClassFromSchema(Schema $schema, string $name, array $confi foreach ($schema->properties as $propertyName => $schemaProperty) { \assert($schemaProperty instanceof Schema); $property = ($this->propertyGenerator)($propertyName, $config, $class, ['schema' => $schema, 'property' => $schemaProperty]); - $class->addProperty($property); + if ($property) { + $class->addProperty($property); + } } if ($config['doctrine']['useCollection']) { diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index bd40d5ac..9dac3e44 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -34,7 +34,7 @@ public function __construct(?PropertyGeneratorInterface $propertyGenerator = nul * @param Configuration $config * @param array{schema: Schema, property: Schema} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property { $schema = $context['schema']; $schemaProperty = $context['property']; diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index fbdbc146..5f2562fd 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -22,7 +22,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface * @param Configuration $config * @param array{} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property { if (!$property) { throw new \LogicException('A property must be given.'); diff --git a/src/PropertyGenerator/PropertyGeneratorInterface.php b/src/PropertyGenerator/PropertyGeneratorInterface.php index a2e80811..3bdfe421 100644 --- a/src/PropertyGenerator/PropertyGeneratorInterface.php +++ b/src/PropertyGenerator/PropertyGeneratorInterface.php @@ -29,5 +29,5 @@ public function __invoke( array $context, bool $isCustom = false, ?Property $property = null - ): Property; + ): ?Property; } diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index fb930980..ccfcc97b 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -62,7 +62,7 @@ public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConver * property: RdfResource * } $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property { $type = $context['type']; $typeConfig = $context['typeConfig']; @@ -136,7 +136,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont } if (!$ranges) { - return $schemaProperty; + return null; } $isNullable = (bool) ($propertyConfig['nullable'] ?? !\in_array($cardinality, [ From 9f6e3a6579972ed519cd63112f9c117893545b3d Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 9 Jun 2022 16:11:13 +0200 Subject: [PATCH 207/258] fix: do not add a doctrine relation if it is a mapped superclass (#370) --- .../DoctrineMongoDBAttributeGenerator.php | 20 +++++++++++++++---- .../DoctrineOrmAttributeGenerator.php | 20 +++++++++++++++---- .../DoctrineMongoDBAttributeGeneratorTest.php | 19 ++++++++++++++++++ .../DoctrineOrmAttributeGeneratorTest.php | 19 ++++++++++++++++++ .../customized/App/Schema/Entity/Person.php | 18 +++++++++++++++++ .../e2e/original/App/Schema/Entity/Person.php | 18 +++++++++++++++++ tests/e2e/schema.yml | 1 + 7 files changed, 107 insertions(+), 8 deletions(-) diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index 563176f4..dd268e35 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -113,9 +113,7 @@ public function generatePropertyAttributes(Property $property, string $className return [new Attribute('MongoDB\Field', ['type' => $type])]; } - if (null === $relationName = $this->getRelationName($property->reference)) { - $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; - + if (null === $relationName = $this->getRelationName($property, $className)) { return []; } @@ -146,9 +144,23 @@ public function generateUses(Class_ $class): array /** * Gets class or interface name to use in relations. */ - private function getRelationName(?Class_ $reference): ?string + private function getRelationName(Property $property, string $className): ?string { + $reference = $property->reference; + if (!$reference) { + $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; + + return null; + } + + if ($reference->isAbstract && !$this->config['doctrine']['inheritanceAttributes']) { + $this->logger ? $this->logger->warning( + <<<'EOD' + Cannot create a relation from the property "{property}" of the class "{class}" to the class "{referenceClass}" because the latter is a Mapped Superclass. + If you want to add a relation anyway, use an inheritance mapping strategy and a discriminator column to do so. + EOD, ['property' => $property->name(), 'class' => $className, 'referenceClass' => $reference->shortName()]) : null; + return null; } diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index e37650da..a87204a0 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -170,9 +170,7 @@ public function generatePropertyAttributes(Property $property, string $className return [new Attribute('ORM\Column', $args)]; } - if (null === $relationName = $this->getRelationName($property->reference)) { - $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; - + if (null === $relationName = $this->getRelationName($property, $className)) { return []; } @@ -276,9 +274,23 @@ private function generateIdAttributes(): array /** * Gets class or interface name to use in relations. */ - private function getRelationName(?Class_ $reference): ?string + private function getRelationName(Property $property, string $className): ?string { + $reference = $property->reference; + if (!$reference) { + $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; + + return null; + } + + if ($reference->isAbstract && !$this->config['doctrine']['inheritanceAttributes']) { + $this->logger ? $this->logger->warning( + <<<'EOD' + Cannot create a relation from the property "{property}" of the class "{class}" to the class "{referenceClass}" because the latter is a Mapped Superclass. + If you want to add a relation anyway, use an inheritance mapping strategy and a discriminator column to do so. + EOD, ['property' => $property->name(), 'class' => $className, 'referenceClass' => $reference->shortName()]) : null; + return null; } diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 2018480f..c287537a 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -24,11 +24,16 @@ use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Prophecy\PhpUnit\ProphecyTrait; +use Psr\Log\LoggerInterface; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\String\Inflector\EnglishInflector; class DoctrineMongoDBAttributeGeneratorTest extends TestCase { + use ProphecyTrait; + private DoctrineMongoDBAttributeGenerator $generator; private array $classMap = []; @@ -66,6 +71,11 @@ protected function setUp(): void $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); $weightProperty->type = 'nonPositiveInteger'; $vehicle->addProperty($weightProperty); + $productProperty = new Property('product'); + $productProperty->rangeName = 'Product'; + $productProperty->range = new RdfResource('https://schema.org/Product'); + $productProperty->reference = $product; + $vehicle->addProperty($productProperty); $relationProperty = new Property('relation'); $relationProperty->rangeName = 'Person'; $relationProperty->range = new RdfResource('https://schema.org/Person'); @@ -145,4 +155,13 @@ public function testGenerateFieldAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relations'), 'Vehicle') ); } + + public function testGenerateAbstractRelation(): void + { + $loggerProphecy = $this->prophesize(LoggerInterface::class); + $loggerProphecy->warning(Argument::cetera())->shouldBeCalledOnce(); + $this->generator->setLogger($loggerProphecy->reveal()); + + $this->assertSame([], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('product'), 'Vehicle')); + } } diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index ca4c0f77..670af3ed 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -24,6 +24,9 @@ use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; +use Prophecy\PhpUnit\ProphecyTrait; +use Psr\Log\LoggerInterface; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\String\Inflector\EnglishInflector; @@ -32,6 +35,8 @@ */ class DoctrineOrmAttributeGeneratorTest extends TestCase { + use ProphecyTrait; + private DoctrineOrmAttributeGenerator $generator; private array $classMap = []; @@ -76,6 +81,11 @@ protected function setUp(): void $prefixedWeightProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $prefixedWeightProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $vehicle->addProperty($prefixedWeightProperty); + $productProperty = new Property('product'); + $productProperty->rangeName = 'Product'; + $productProperty->range = new RdfResource('https://schema.org/Product'); + $productProperty->reference = $product; + $vehicle->addProperty($productProperty); $relation01Property = new Property('relation0_1'); $relation01Property->rangeName = 'QuantitativeValue'; $relation01Property->range = new RdfResource('https://schema.org/QuantitativeValue'); @@ -216,4 +226,13 @@ public function testGenerateFieldAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle') ); } + + public function testGenerateAbstractRelation(): void + { + $loggerProphecy = $this->prophesize(LoggerInterface::class); + $loggerProphecy->warning(Argument::cetera())->shouldBeCalledOnce(); + $this->generator->setLogger($loggerProphecy->reveal()); + + $this->assertSame([], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('product'), 'Vehicle')); + } } diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 02e85d8d..d80f40b5 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -139,6 +139,14 @@ class Person extends MyCustomClass implements MyCustomInterface #[ApiProperty(iri: 'https://schema.org/siblings')] private ?Collection $siblings = null; + /** + * Of a \[\[Person\]\], and less typically of an \[\[Organization\]\], to indicate a topic that is known about - suggesting possible expertise but not implying it. We do not distinguish skill levels here, or relate this to educational content, events, objectives or \[\[JobPosting\]\] descriptions. + * + * @see https://schema.org/knowsAbout + */ + #[ApiProperty(iri: 'https://schema.org/knowsAbout')] + private ?Thing $knowsAbout = null; + /** @see _:customColumn */ #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] private ?Person $customColumn = null; @@ -266,6 +274,16 @@ public function getSiblings(): Collection return $this->siblings; } + public function setKnowsAbout(?Thing $knowsAbout): void + { + $this->knowsAbout = $knowsAbout; + } + + public function getKnowsAbout(): ?Thing + { + return $this->knowsAbout; + } + public function setCustomColumn(?Person $customColumn): void { $this->customColumn = $customColumn; diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 34657c59..7da0f67e 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -130,6 +130,14 @@ class Person extends Thing #[ApiProperty(iri: 'https://schema.org/siblings')] private ?Collection $siblings = null; + /** + * Of a \[\[Person\]\], and less typically of an \[\[Organization\]\], to indicate a topic that is known about - suggesting possible expertise but not implying it. We do not distinguish skill levels here, or relate this to educational content, events, objectives or \[\[JobPosting\]\] descriptions. + * + * @see https://schema.org/knowsAbout + */ + #[ApiProperty(iri: 'https://schema.org/knowsAbout')] + private ?Thing $knowsAbout = null; + /** * @see _:customColumn */ @@ -254,6 +262,16 @@ public function getSiblings(): Collection return $this->siblings; } + public function setKnowsAbout(?Thing $knowsAbout): void + { + $this->knowsAbout = $knowsAbout; + } + + public function getKnowsAbout(): ?Thing + { + return $this->knowsAbout; + } + public function setCustomColumn(?Person $customColumn): void { $this->customColumn = $customColumn; diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 442592a9..323d9def 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -35,6 +35,7 @@ types: email: { unique: true, security: "is_granted('ROLE_ADMIN')" } url: ~ siblings: { cardinality: "(0..*)" } + knowsAbout: { range: https://schema.org/Thing } customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } Brand: properties: From fd77c343133dbb0418669843a76b449ebb2468f4 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 9 Jun 2022 16:26:09 +0200 Subject: [PATCH 208/258] fix: remove simple in ODM attributes (#371) --- src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php | 4 ++-- .../DoctrineMongoDBAttributeGeneratorTest.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index dd268e35..fa7c4712 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -121,13 +121,13 @@ public function generatePropertyAttributes(Property $property, string $className || CardinalitiesExtractor::CARDINALITY_1_1 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_0 === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_1 === $property->cardinality) { - return [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => $relationName, 'simple' => true])]; + return [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => $relationName])]; } if (CardinalitiesExtractor::CARDINALITY_0_N === $property->cardinality || CardinalitiesExtractor::CARDINALITY_1_N === $property->cardinality || CardinalitiesExtractor::CARDINALITY_N_N === $property->cardinality) { - return [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => $relationName, 'simple' => true])]; + return [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => $relationName])]; } return []; diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index c287537a..27a3dda8 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -147,11 +147,11 @@ public function testGenerateFieldAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') ); $this->assertEquals( - [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => 'Person', 'simple' => true])], + [new Attribute('MongoDB\ReferenceOne', ['targetDocument' => 'Person'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation'), 'Vehicle') ); $this->assertEquals( - [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => 'Person', 'simple' => true])], + [new Attribute('MongoDB\ReferenceMany', ['targetDocument' => 'Person'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relations'), 'Vehicle') ); } From 847fd3c9bbb8f355e47d00bf592066cb7cca3dda Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 16 Jun 2022 17:21:16 +0200 Subject: [PATCH 209/258] feat: add resolveTypes and allTypes parameters (#374) The allTypes parameter can be set on a specific vocabulary to generate all its types on top of the explicit types you have provided. If the allTypes parameter is enabled globally, you can also use it to disable it on a specific vocabulary (but you can explicitly define types for this vocabulary). If resolveTypes is enabled, if a type is present in a vocabulary but not explicitly imported or if the vocabulary is not totally imported (allTypes), it will be generated. --- composer.json | 3 +- composer.lock | 2 +- phpstan.neon | 3 +- src/CardinalitiesExtractor.php | 16 +- src/ClassMutator/AnnotationsAppender.php | 5 +- src/ClassMutator/AttributeAppender.php | 5 +- src/ClassMutator/ClassIdAppender.php | 5 +- src/ClassMutator/ClassInterfaceMutator.php | 5 +- src/ClassMutator/ClassMutatorInterface.php | 3 +- src/ClassMutator/ClassParentMutator.php | 7 +- src/ClassMutator/ClassPropertiesAppender.php | 53 ++-- .../ClassPropertiesTypehintMutator.php | 5 +- src/ClassMutator/EnumClassMutator.php | 5 +- src/Command/ExtractCardinalitiesCommand.php | 4 +- src/OpenApi/ClassGenerator.php | 12 +- src/Schema/Generator.php | 7 +- .../PropertyGenerator/PropertyGenerator.php | 14 +- src/SchemaGeneratorConfiguration.php | 2 + src/TypesGenerator.php | 266 ++++++++++-------- tests/ClassMutator/ClassParentMutatorTest.php | 4 +- .../ClassPropertiesAppenderTest.php | 6 +- tests/Command/DumpConfigurationTest.php | 6 + tests/TypesGeneratorTest.php | 201 ++++++++++--- 23 files changed, 422 insertions(+), 217 deletions(-) diff --git a/composer.json b/composer.json index a14df74f..8fadae1c 100644 --- a/composer.json +++ b/composer.json @@ -59,7 +59,8 @@ "symfony/serializer": "^5.2 || ^6.0", "symfony/validator": "^5.2 || ^6.0", "phpspec/prophecy-phpunit": "^2.0", - "phpstan/phpstan": "^1.2.0" + "phpstan/phpstan": "^1.2.0", + "symfony/finder": "^5.2 || ^6.0" }, "bin": [ "bin/schema" diff --git a/composer.lock b/composer.lock index e0364352..05b1aa0e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6c3e382a4abfab20197f48b9bb9e1e68", + "content-hash": "22c506cdcd2c21e50081504cbe03e7bd", "packages": [ { "name": "cebe/php-openapi", diff --git a/phpstan.neon b/phpstan.neon index 81cdbed9..823b6bb1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -41,7 +41,7 @@ parameters: ''' Configuration: ''' array{ - vocabularies: array{uri: string, format: string}[], + vocabularies: array{uri: string, format: string, allTypes: ?boolean}[], vocabularyNamespace: string, relations: string[], debug: boolean, @@ -58,6 +58,7 @@ parameters: fluentMutatorMethods: boolean, rangeMapping: array, allTypes: boolean, + resolveTypes: boolean, types: array, annotationGenerators: class-string[], attributeGenerators: class-string[], diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index b2ebc6ec..4674defe 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -32,31 +32,25 @@ class CardinalitiesExtractor public const CARDINALITY_N_N = '(*..*)'; public const CARDINALITY_UNKNOWN = 'unknown'; - /** - * @var RdfGraph[] - */ - private array $graphs; private GoodRelationsBridge $goodRelationsBridge; - /** - * @param RdfGraph[] $graphs - */ - public function __construct(array $graphs, GoodRelationsBridge $goodRelationsBridge) + public function __construct(GoodRelationsBridge $goodRelationsBridge) { - $this->graphs = $graphs; $this->goodRelationsBridge = $goodRelationsBridge; } /** * Extracts cardinality of properties. * + * @param RdfGraph[] $graphs + * * @return array */ - public function extract(): array + public function extract(array $graphs): array { $properties = []; - foreach ($this->graphs as $graph) { + foreach ($graphs as $graph) { foreach (TypesGenerator::$propertyTypes as $propertyType) { /** @var RdfResource $property */ foreach ($graph->allOfType($propertyType) as $property) { diff --git a/src/ClassMutator/AnnotationsAppender.php b/src/ClassMutator/AnnotationsAppender.php index 2d4c2aff..14d5c5ad 100644 --- a/src/ClassMutator/AnnotationsAppender.php +++ b/src/ClassMutator/AnnotationsAppender.php @@ -39,7 +39,10 @@ public function __construct(array $classes, array $annotationGenerators, array $ $this->typesToGenerate = $typesToGenerate; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { $this->generateClassUses($class); $this->generateClassAnnotations($class); diff --git a/src/ClassMutator/AttributeAppender.php b/src/ClassMutator/AttributeAppender.php index 0bc7ea62..8c7c99cb 100644 --- a/src/ClassMutator/AttributeAppender.php +++ b/src/ClassMutator/AttributeAppender.php @@ -34,7 +34,10 @@ public function __construct(array $classes, array $attributeGenerators) $this->classes = $classes; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { $this->generateClassUses($class); $this->generateClassAttributes($class); diff --git a/src/ClassMutator/ClassIdAppender.php b/src/ClassMutator/ClassIdAppender.php index 9510c1d7..5d1af6ca 100644 --- a/src/ClassMutator/ClassIdAppender.php +++ b/src/ClassMutator/ClassIdAppender.php @@ -31,7 +31,10 @@ public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator, a $this->config = $config; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { if ( $class->isEnum() diff --git a/src/ClassMutator/ClassInterfaceMutator.php b/src/ClassMutator/ClassInterfaceMutator.php index 506bc213..8b315afd 100644 --- a/src/ClassMutator/ClassInterfaceMutator.php +++ b/src/ClassMutator/ClassInterfaceMutator.php @@ -25,7 +25,10 @@ public function __construct(string $desiredNamespace) $this->desiredNamespace = $desiredNamespace; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { $class->interface = new Interface_(sprintf('%sInterface', $class->name()), $this->desiredNamespace); } diff --git a/src/ClassMutator/ClassMutatorInterface.php b/src/ClassMutator/ClassMutatorInterface.php index d52f1600..387d2a0e 100644 --- a/src/ClassMutator/ClassMutatorInterface.php +++ b/src/ClassMutator/ClassMutatorInterface.php @@ -17,5 +17,6 @@ interface ClassMutatorInterface { - public function __invoke(Class_ $class): void; + // @phpstan-ignore-next-line + public function __invoke(Class_ $class, array $context): void; } diff --git a/src/ClassMutator/ClassParentMutator.php b/src/ClassMutator/ClassParentMutator.php index 52c5d032..6cd4b745 100644 --- a/src/ClassMutator/ClassParentMutator.php +++ b/src/ClassMutator/ClassParentMutator.php @@ -36,7 +36,10 @@ public function __construct(array $config, PhpTypeConverterInterface $phpTypeCon $this->config = $config; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { if (!$class instanceof SchemaClass) { return; @@ -47,7 +50,7 @@ public function __invoke(Class_ $class): void if (null === $class->parent() && $subclassOf = $class->getSubClassOf()) { if (\count($subclassOf) > 1) { - $this->logger ? $this->logger->warning(sprintf('The type "%s" has several supertypes. Using the first one.', $class->rdfType())) : null; + $this->logger ? $this->logger->info(sprintf('The type "%s" has several supertypes. Using the first one.', $class->rdfType())) : null; } $class->withParent($this->phpTypeConverter->escapeIdentifier($subclassOf[0]->localName())); diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 4a31ae6d..e6d799db 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -36,28 +36,30 @@ final class ClassPropertiesAppender implements ClassMutatorInterface 'rdfs:Class', 'owl:Class', ]; - /** @var RdfGraph[] */ - private array $graphs; /** * @param Configuration $config * @param array $propertiesMap - * @param RdfGraph[] $graphs */ - public function __construct(PropertyGeneratorInterface $propertyGenerator, array $config, array $propertiesMap, array $graphs) + public function __construct(PropertyGeneratorInterface $propertyGenerator, array $config, array $propertiesMap) { $this->propertiesMap = $propertiesMap; $this->propertyGenerator = $propertyGenerator; $this->config = $config; - $this->graphs = $graphs; } - public function __invoke(Class_ $class): void + /** + * @param array{graphs: RdfGraph[], cardinalities: array} $context + */ + public function __invoke(Class_ $class, array $context): void { if (!$class instanceof SchemaClass) { return; } + $graphs = $context['graphs']; + $cardinalities = $context['cardinalities']; + $typeConfig = $this->config['types'][$class->name()] ?? null; if (null !== $typeConfig && !$typeConfig['allProperties']) { @@ -66,18 +68,18 @@ public function __invoke(Class_ $class): void continue; } - foreach ($this->getParentClasses($class->resource()) as $typeInHierarchy) { + foreach ($this->getParentClasses($graphs, $class->resource()) as $typeInHierarchy) { foreach ($this->propertiesMap[$typeInHierarchy->getUri()] ?? [] as $property) { if ($key !== $property->localName()) { continue; } - $this->generateField($this->config, $class, $class->resource(), $typeConfig, $property); + $this->generateField($this->config, $class, $class->resource(), $typeConfig, $cardinalities, $property); continue 3; } } - $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); + $this->generateCustomField($key, $class->resource(), $typeConfig, $cardinalities, $class, $this->config); } } else { $remainingProperties = $typeConfig['properties'] ?? []; @@ -89,9 +91,9 @@ public function __invoke(Class_ $class): void unset($remainingProperties[$property->localName()]); if ($property->hasProperty(self::SCHEMA_ORG_SUPERSEDED_BY)) { $supersededBy = $property->get(self::SCHEMA_ORG_SUPERSEDED_BY); - $this->logger ? $this->logger->warning(sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())) : null; + $this->logger ? $this->logger->info(sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())) : null; } else { - $this->generateField($this->config, $class, $class->resource(), $typeConfig, $property); + $this->generateField($this->config, $class, $class->resource(), $typeConfig, $cardinalities, $property); } } @@ -99,7 +101,7 @@ public function __invoke(Class_ $class): void if ($remainingProperty['exclude']) { continue; } - $this->generateCustomField($key, $class->resource(), $typeConfig, $class, $this->config); + $this->generateCustomField($key, $class->resource(), $typeConfig, $cardinalities, $class, $this->config); } } } @@ -107,27 +109,29 @@ public function __invoke(Class_ $class): void /** * Add custom fields (not defined in the vocabulary). * - * @param ?TypeConfiguration $typeConfig - * @param Configuration $config + * @param ?TypeConfiguration $typeConfig + * @param Configuration $config + * @param array $cardinalities */ - private function generateCustomField(string $propertyName, RdfResource $type, ?array $typeConfig, SchemaClass $class, array $config): void + private function generateCustomField(string $propertyName, RdfResource $type, ?array $typeConfig, array $cardinalities, SchemaClass $class, array $config): void { $this->logger ? $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())) : null; $customResource = new RdfResource('_:'.$propertyName, new RdfGraph()); $customResource->add('rdfs:range', $type); - $this->generateField($config, $class, $type, $typeConfig, $customResource, true); + $this->generateField($config, $class, $type, $typeConfig, $cardinalities, $customResource, true); } /** * Updates generated $class with given field config. * - * @param Configuration $config - * @param ?TypeConfiguration $typeConfig + * @param Configuration $config + * @param ?TypeConfiguration $typeConfig + * @param array $cardinalities */ - private function generateField(array $config, SchemaClass $class, RdfResource $type, ?array $typeConfig, RdfResource $typeProperty, bool $isCustom = false): void + private function generateField(array $config, SchemaClass $class, RdfResource $type, ?array $typeConfig, array $cardinalities, RdfResource $typeProperty, bool $isCustom = false): void { - $property = ($this->propertyGenerator)($typeProperty->localName(), $config, $class, ['type' => $type, 'typeConfig' => $typeConfig, 'property' => $typeProperty], $isCustom); + $property = ($this->propertyGenerator)($typeProperty->localName(), $config, $class, ['type' => $type, 'typeConfig' => $typeConfig, 'cardinalities' => $cardinalities, 'property' => $typeProperty], $isCustom); if ($property) { $class->addProperty($property); @@ -137,14 +141,15 @@ private function generateField(array $config, SchemaClass $class, RdfResource $t /** * Gets the parent classes of the current one and add them to $parentClasses array. * + * @param RdfGraph[] $graphs * @param RdfResource[] $parentClasses * * @return RdfResource[] */ - private function getParentClasses(RdfResource $resource, array $parentClasses = []): array + private function getParentClasses(array $graphs, RdfResource $resource, array $parentClasses = []): array { if ([] === $parentClasses) { - return $this->getParentClasses($resource, [$resource]); + return $this->getParentClasses($graphs, $resource, [$resource]); } $filterBNodes = fn ($parentClasses) => array_filter($parentClasses, fn ($parentClass) => !$parentClass->isBNode()); @@ -155,11 +160,11 @@ private function getParentClasses(RdfResource $resource, array $parentClasses = $parentClassUri = $subclasses[0]->getUri(); $parentClasses[] = $subclasses[0]; - foreach ($this->graphs as $graph) { + foreach ($graphs as $graph) { foreach (self::$classTypes as $classType) { foreach ($graph->allOfType($classType) as $type) { if ($type->getUri() === $parentClassUri) { - return $this->getParentClasses($type, $parentClasses); + return $this->getParentClasses($graphs, $type, $parentClasses); } } } diff --git a/src/ClassMutator/ClassPropertiesTypehintMutator.php b/src/ClassMutator/ClassPropertiesTypehintMutator.php index cc648b4e..9ba9db2d 100644 --- a/src/ClassMutator/ClassPropertiesTypehintMutator.php +++ b/src/ClassMutator/ClassPropertiesTypehintMutator.php @@ -35,7 +35,10 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, array $ $this->config = $config; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { foreach ($class->properties() as $property) { $property->isEnum = $property->isEnum ?: $property->reference && $property->reference->isEnum(); diff --git a/src/ClassMutator/EnumClassMutator.php b/src/ClassMutator/EnumClassMutator.php index 10e0827a..a80f63d0 100644 --- a/src/ClassMutator/EnumClassMutator.php +++ b/src/ClassMutator/EnumClassMutator.php @@ -29,7 +29,10 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, string $this->desiredNamespace = $desiredNamespace; } - public function __invoke(Class_ $class): void + /** + * @param array{} $context + */ + public function __invoke(Class_ $class, array $context): void { $class->namespace = $this->desiredNamespace; $class diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 1e721918..3170be67 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -64,8 +64,8 @@ protected function execute(InputInterface $input, OutputInterface $output): int $cardinality = [new \SimpleXMLElement($input->getOption('cardinality-file'), 0, true)]; $goodRelationsBridge = new GoodRelationsBridge($cardinality); - $cardinalitiesExtractor = new CardinalitiesExtractor($relations, $goodRelationsBridge); - $result = $cardinalitiesExtractor->extract(); + $cardinalitiesExtractor = new CardinalitiesExtractor($goodRelationsBridge); + $result = $cardinalitiesExtractor->extract($relations); $output->writeln(json_encode($result, \JSON_THROW_ON_ERROR | \JSON_PRETTY_PRINT)); diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 6a642663..2ef200df 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -142,11 +142,11 @@ public function generate(OpenApi $openApi, array $config): array // Second pass foreach ($classes as $class) { if ($config['useInterface']) { - (new ClassInterfaceMutator($config['namespaces']['interface']))($class); + (new ClassInterfaceMutator($config['namespaces']['interface']))($class, []); } if ($config['id']['generate']) { - (new ClassIdAppender(new IdPropertyGenerator(), $config))($class); + (new ClassIdAppender(new IdPropertyGenerator(), $config))($class, []); } // Try to guess the references from the property names. @@ -163,7 +163,7 @@ public function generate(OpenApi $openApi, array $config): array // Third pass foreach ($classes as $class) { - (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class); + (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class, []); // Try to guess the mapped by from the references foreach ($class->properties() as $property) { @@ -201,8 +201,8 @@ public function generate(OpenApi $openApi, array $config): array } foreach ($classes as $class) { - (new AnnotationsAppender($classes, $annotationGenerators, []))($class); - (new AttributeAppender($classes, $attributeGenerators))($class); + (new AnnotationsAppender($classes, $annotationGenerators, []))($class, []); + (new AttributeAppender($classes, $attributeGenerators))($class, []); } return $classes; @@ -259,7 +259,7 @@ private function buildEnumClasses(Schema $schema, OpenApiClass $class, array $co $this->phpTypeConverter, $config['namespaces']['enum'], $schemaProperty->enum - ))($enumClass); + ))($enumClass, []); $enumClasses[$name] = $enumClass; if ($classProperty = $class->getPropertyByName($propertyName)) { diff --git a/src/Schema/Generator.php b/src/Schema/Generator.php index e5400bb6..67c8de6c 100644 --- a/src/Schema/Generator.php +++ b/src/Schema/Generator.php @@ -35,7 +35,7 @@ public function generate(array $configuration, OutputInterface $output, SymfonyS { $graphs = []; foreach ($configuration['vocabularies'] as $vocab) { - $graph = new RdfGraph(); + $graph = new RdfGraph($vocab['uri']); if (0 === strpos($vocab['uri'], 'http://') || 0 === strpos($vocab['uri'], 'https://')) { $graph->load($vocab['uri'], $vocab['format']); } else { @@ -51,7 +51,7 @@ public function generate(array $configuration, OutputInterface $output, SymfonyS } $goodRelationsBridge = new GoodRelationsBridge($relations); - $cardinalitiesExtractor = new CardinalitiesExtractor($graphs, $goodRelationsBridge); + $cardinalitiesExtractor = new CardinalitiesExtractor($goodRelationsBridge); $inflector = new EnglishInflector(); @@ -59,14 +59,13 @@ public function generate(array $configuration, OutputInterface $output, SymfonyS $entitiesGenerator = new TypesGenerator( $inflector, - $graphs, new PhpTypeConverter(), $cardinalitiesExtractor, $goodRelationsBridge ); $entitiesGenerator->setLogger($logger); - $classes = $entitiesGenerator->generate($configuration); + $classes = $entitiesGenerator->generate($graphs, $configuration); $twig = (new TwigBuilder())->build($configuration); diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index ccfcc97b..78f7a8f9 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -37,20 +37,14 @@ final class PropertyGenerator implements PropertyGeneratorInterface private GoodRelationsBridge $goodRelationsBridge; private PhpTypeConverterInterface $phpTypeConverter; - /** @var array */ - private array $cardinalities; private TypeConverter $typeConverter; private PropertyGeneratorInterface $propertyGenerator; - /** - * @param array $cardinalities - */ - public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, array $cardinalities, ?PropertyGeneratorInterface $propertyGenerator = null) + public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, ?PropertyGeneratorInterface $propertyGenerator = null) { $this->goodRelationsBridge = $goodRelationsBridge; $this->typeConverter = $typeConverter; $this->phpTypeConverter = $phpTypeConverter; - $this->cardinalities = $cardinalities; $this->propertyGenerator = $propertyGenerator ?? new CommonPropertyGenerator(); } @@ -59,6 +53,7 @@ public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConver * @param array{ * type: RdfResource, * typeConfig: ?TypeConfiguration, + * cardinalities: array, * property: RdfResource * } $context */ @@ -66,6 +61,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont { $type = $context['type']; $typeConfig = $context['typeConfig']; + $cardinalities = $context['cardinalities']; $typeProperty = $context['property']; $typeUri = $type->getUri(); @@ -75,7 +71,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $cardinality = $propertyConfig['cardinality'] ?? false; if (!$cardinality || CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { - $cardinality = $this->cardinalities[$propertyUri] ?? CardinalitiesExtractor::CARDINALITY_1_1; + $cardinality = $cardinalities[$propertyUri] ?? CardinalitiesExtractor::CARDINALITY_1_1; } $isArray = \in_array($cardinality, [ @@ -121,7 +117,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont } if (\count($ranges) > 1) { - $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") has several types. Using the first one ("%s"). Other possible options: "%s".', $propertyUri, $typeUri, $ranges[0]->getUri(), implode('", "', array_map(static fn (RdfResource $range) => $range->getUri(), $ranges)))) : null; + $this->logger ? $this->logger->info(sprintf('The property "%s" (type "%s") has several types. Using the first one ("%s"). Other possible options: "%s".', $propertyUri, $typeUri, $ranges[0]->getUri(), implode('", "', array_map(static fn (RdfResource $range) => $range->getUri(), $ranges)))) : null; } $rangeName = null; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 321dc8f5..4b0a9cc4 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -75,6 +75,7 @@ static function ($rdf) { ->children() ->scalarNode('uri')->defaultValue(self::SCHEMA_ORG_URI)->info('RDF vocabulary to use')->example('https://schema.org/version/latest/schemaorg-current-https.rdf')->end() ->scalarNode('format')->defaultNull()->info('RDF vocabulary format')->example('rdfxml')->end() + ->booleanNode('allTypes')->defaultNull()->info('Generate all types for this vocabulary, even if an explicit configuration exists. If allTypes is enabled globally, it can be disabled for this particular vocabulary')->end() ->end() ->end() ->end() @@ -138,6 +139,7 @@ static function ($rdf) { ->prototype('scalar')->end() ->end() ->booleanNode('allTypes')->defaultFalse()->info('Generate all types, even if an explicit configuration exists')->end() + ->booleanNode('resolveTypes')->defaultFalse()->info('If a type is present in a vocabulary but not explicitly imported (types) or if the vocabulary is not totally imported (allTypes), it will be generated')->end() ->arrayNode('types') ->beforeNormalization() ->always() diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 3614941d..5a3ddbad 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -79,28 +79,17 @@ class TypesGenerator 'rdfs:domain', ]; - /** @var RdfGraph[] */ - private array $graphs; private PhpTypeConverterInterface $phpTypeConverter; - /** @var array */ - private array $cardinalities; private InflectorInterface $inflector; + private CardinalitiesExtractor $cardinalitiesExtractor; private PropertyGeneratorInterface $propertyGenerator; - /** - * @param RdfGraph[] $graphs - */ - public function __construct(InflectorInterface $inflector, array $graphs, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge) + public function __construct(InflectorInterface $inflector, PhpTypeConverterInterface $phpTypeConverter, CardinalitiesExtractor $cardinalitiesExtractor, GoodRelationsBridge $goodRelationsBridge) { - if (!$graphs) { - throw new \InvalidArgumentException('At least one graph must be injected.'); - } - $this->inflector = $inflector; - $this->graphs = $graphs; $this->phpTypeConverter = $phpTypeConverter; - $this->cardinalities = $cardinalitiesExtractor->extract(); - $this->propertyGenerator = new PropertyGenerator($goodRelationsBridge, new TypeConverter(), $phpTypeConverter, $this->cardinalities); + $this->cardinalitiesExtractor = $cardinalitiesExtractor; + $this->propertyGenerator = new PropertyGenerator($goodRelationsBridge, new TypeConverter(), $phpTypeConverter); RdfNamespace::set('schema', 'https://schema.org/'); } @@ -108,85 +97,53 @@ public function __construct(InflectorInterface $inflector, array $graphs, PhpTyp /** * Generates files. * + * @param RdfGraph[] $graphs * @param Configuration $config * * @return Class_[] */ - public function generate(array $config): array + public function generate(array $graphs, array $config): array { - $typesToGenerate = $this->defineTypesToGenerate($config); - - $classes = []; - $propertiesMap = $this->createPropertiesMap($typesToGenerate, $config); + if (!$graphs) { + throw new \InvalidArgumentException('At least one graph must be injected.'); + } - foreach ($typesToGenerate as $typeName => $type) { - if ($type->isBNode()) { - // Ignore blank nodes - continue; - } + [$typeNamesToGenerate, $types] = $this->defineTypesToGenerate($graphs, $config); - $typeName = $this->phpTypeConverter->escapeIdentifier(\is_string($typeName) ? $typeName : $type->localName()); - if ($type->isA('owl:DeprecatedClass')) { - if (!isset($config['types'][$typeName])) { - continue; - } + $classes = []; + $propertiesMap = $this->createPropertiesMap($graphs, $types, $config); + $cardinalities = $this->cardinalitiesExtractor->extract($graphs); - $this->logger ? $this->logger->warning('The type "{type}" is deprecated', ['type' => $type->getUri()]) : null; + foreach ($types as $typeName => $type) { + if ($class = $this->buildClass($graphs, $cardinalities, $typeName, $type, $propertiesMap, $config)) { + $classes[$typeName] = $class; } + } - $typeConfig = $config['types'][$typeName] ?? null; - $parent = $typeConfig['parent'] ?? null; - $class = new SchemaClass($typeName, $type, $parent); - $class->operations = $typeConfig['operations'] ?? []; - $class->security = $typeConfig['security'] ?? null; - - if ($class->isEnum()) { - (new SchemaEnumClassMutator( - $this->phpTypeConverter, - $this->graphs, - $config['namespaces']['enum'] - ))($class); - } else { - $class->namespace = $typeConfig['namespaces']['class'] ?? $config['namespaces']['entity']; - - // Interfaces - if ($config['useInterface']) { - $interfaceNamespace = isset($typeConfig['namespaces']['interface']) && $typeConfig['namespaces']['interface'] ? $typeConfig['namespaces']['interface'] : $config['namespaces']['interface']; - (new ClassInterfaceMutator($interfaceNamespace))($class); + foreach ($typeNamesToGenerate as $typeNameToGenerate) { + $class = $classes[$typeNameToGenerate]; + while (($parent = $class->parent()) && !$class->isParentEnum()) { + if (!isset($classes[$parent])) { + $this->logger ? $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $parent, $class->rdfType())) : null; + break; } - - $classParentMutator = new ClassParentMutator($config, $this->phpTypeConverter); - if ($this->logger) { - $classParentMutator->setLogger($this->logger); + if (!\in_array($parent, $typeNamesToGenerate, true)) { + $typeNamesToGenerate[] = $parent; } - ($classParentMutator)($class); - } - - $classPropertiesAppender = new ClassPropertiesAppender($this->propertyGenerator, $config, $propertiesMap, $this->graphs); - if ($this->logger) { - $classPropertiesAppender->setLogger($this->logger); - } - ($classPropertiesAppender)($class); - $class->isEmbeddable = $typeConfig['embeddable'] ?? false; - - if ($config['doctrine']['useCollection']) { - $class->addUse(new Use_(ArrayCollection::class)); - $class->addUse(new Use_(Collection::class)); + $class = $classes[$parent]; } - - $classes[$typeName] = $class; } + $classes = array_intersect_key($classes, array_flip($typeNamesToGenerate)); + $types = array_intersect_key($types, array_flip($typeNamesToGenerate)); // Second pass foreach ($classes as $class) { /** @var $class SchemaClass */ if ($class->hasParent() && !$class->isParentEnum()) { $parentClass = $classes[$class->parent()] ?? null; - if (isset($parentClass)) { + if ($parentClass) { $parentClass->hasChild = true; $class->parentHasConstructor = $parentClass->hasConstructor; - } else { - $this->logger ? $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $class->parent(), $class->rdfType())) : null; } } @@ -200,7 +157,7 @@ public function generate(array $config): array } } - (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class); + (new ClassPropertiesTypehintMutator($this->phpTypeConverter, $config, $classes))($class, []); } // Third pass @@ -237,7 +194,7 @@ public function generate(array $config): array // Generate ID if ($config['id']['generate']) { foreach ($classes as $class) { - (new ClassIdAppender(new IdPropertyGenerator(), $config))($class); + (new ClassIdAppender(new IdPropertyGenerator(), $config))($class, []); } } @@ -264,24 +221,89 @@ public function generate(array $config): array } foreach ($classes as $class) { - (new AnnotationsAppender($classes, $annotationGenerators, $typesToGenerate))($class); - (new AttributeAppender($classes, $attributeGenerators))($class); + (new AnnotationsAppender($classes, $annotationGenerators, $types))($class, []); + (new AttributeAppender($classes, $attributeGenerators))($class, []); } return $classes; } + /** + * @param RdfGraph[] $graphs + * @param array $cardinalities + * @param array $propertiesMap + * @param Configuration $config + */ + private function buildClass(array $graphs, array $cardinalities, string $typeName, RdfResource $type, array $propertiesMap, array $config): ?SchemaClass + { + if ($type->isBNode()) { + // Ignore blank nodes + return null; + } + + if ($type->isA('owl:DeprecatedClass')) { + if (!isset($config['types'][$typeName])) { + return null; + } + + $this->logger ? $this->logger->warning('The type "{type}" is deprecated', ['type' => $type->getUri()]) : null; + } + + $typeConfig = $config['types'][$typeName] ?? null; + $parent = $typeConfig['parent'] ?? null; + $class = new SchemaClass($typeName, $type, $parent); + $class->operations = $typeConfig['operations'] ?? []; + $class->security = $typeConfig['security'] ?? null; + + if ($class->isEnum()) { + (new SchemaEnumClassMutator( + $this->phpTypeConverter, + $graphs, + $config['namespaces']['enum'] + ))($class, []); + } else { + $class->namespace = $typeConfig['namespaces']['class'] ?? $config['namespaces']['entity']; + + // Interfaces + if ($config['useInterface']) { + $interfaceNamespace = isset($typeConfig['namespaces']['interface']) && $typeConfig['namespaces']['interface'] ? $typeConfig['namespaces']['interface'] : $config['namespaces']['interface']; + (new ClassInterfaceMutator($interfaceNamespace))($class, []); + } + + $classParentMutator = new ClassParentMutator($config, $this->phpTypeConverter); + if ($this->logger) { + $classParentMutator->setLogger($this->logger); + } + ($classParentMutator)($class, []); + } + + $classPropertiesAppender = new ClassPropertiesAppender($this->propertyGenerator, $config, $propertiesMap); + if ($this->logger) { + $classPropertiesAppender->setLogger($this->logger); + } + ($classPropertiesAppender)($class, ['graphs' => $graphs, 'cardinalities' => $cardinalities]); + $class->isEmbeddable = $typeConfig['embeddable'] ?? false; + + if ($config['doctrine']['useCollection']) { + $class->addUse(new Use_(ArrayCollection::class)); + $class->addUse(new Use_(Collection::class)); + } + + return $class; + } + /** * Gets the parent classes of the current one and add them to $parentClasses array. * + * @param RdfGraph[] $graphs * @param RdfResource[] $parentClasses * * @return RdfResource[] */ - private function getParentClasses(RdfResource $resource, array $parentClasses = []): array + private function getParentClasses(array $graphs, RdfResource $resource, array $parentClasses = []): array { if ([] === $parentClasses) { - return $this->getParentClasses($resource, [$resource]); + return $this->getParentClasses($graphs, $resource, [$resource]); } $filterBNodes = fn ($parentClasses) => array_filter($parentClasses, fn ($parentClass) => !$parentClass->isBNode()); @@ -292,11 +314,11 @@ private function getParentClasses(RdfResource $resource, array $parentClasses = $parentClassUri = $subclasses[0]->getUri(); $parentClasses[] = $subclasses[0]; - foreach ($this->graphs as $graph) { + foreach ($graphs as $graph) { foreach (self::$classTypes as $classType) { foreach ($graph->allOfType($classType) as $type) { if ($type->getUri() === $parentClassUri) { - return $this->getParentClasses($type, $parentClasses); + return $this->getParentClasses($graphs, $type, $parentClasses); } } } @@ -308,18 +330,19 @@ private function getParentClasses(RdfResource $resource, array $parentClasses = /** * Creates a map between classes and properties. * + * @param RdfGraph[] $graphs * @param RdfResource[] $types * @param Configuration $config * * @return array */ - private function createPropertiesMap(array $types, array $config): array + private function createPropertiesMap(array $graphs, array $types, array $config): array { $typesResources = []; $map = []; foreach ($types as $type) { // get all parent classes until the root - $parentClasses = $this->getParentClasses($type); + $parentClasses = $this->getParentClasses($graphs, $type); $typesResources[] = [ 'resources' => $parentClasses, 'uris' => array_map(static fn (RdfResource $parentClass) => $parentClass->getUri(), $parentClasses), @@ -328,7 +351,7 @@ private function createPropertiesMap(array $types, array $config): array $map[$type->getUri()] = []; } - foreach ($this->graphs as $graph) { + foreach ($graphs as $graph) { foreach (self::$propertyTypes as $propertyType) { /** @var RdfResource $property */ foreach ($graph->allOfType($propertyType) as $property) { @@ -401,51 +424,72 @@ private function addPropertyToMap(RdfResource $property, RdfResource $domain, ar } /** + * @param RdfGraph[] $graphs * @param Configuration $config * - * @return RdfResource[] + * @return array{0: string[], 1: array} */ - private function defineTypesToGenerate(array $config): array + private function defineTypesToGenerate(array $graphs, array $config): array { - $typesToGenerate = []; - if ($config['allTypes']) { - foreach ($this->graphs as $graph) { - foreach (self::$classTypes as $classType) { - foreach ($graph->allOfType($classType) as $type) { - if (!($config['types'][$this->phpTypeConverter->escapeIdentifier($type->localName())]['exclude'] ?? false)) { - $typesToGenerate[] = $type; + $typeNamesToGenerate = []; + $allTypes = []; + + foreach ($graphs as $graph) { + $vocabAllTypes = $config['allTypes']; + foreach ($config['vocabularies'] as $vocab) { + if ($graph->getUri() !== $vocab['uri']) { + continue; + } + $vocabAllTypes = $vocab['allTypes'] ?? $vocabAllTypes; + } + foreach (self::$classTypes as $classType) { + foreach ($graph->allOfType($classType) as $type) { + $typeName = $this->phpTypeConverter->escapeIdentifier($type->localName()); + if (!($config['types'][$typeName]['exclude'] ?? false)) { + if ($config['resolveTypes'] || $vocabAllTypes) { + $allTypes[$typeName] = $type; + } + if ($vocabAllTypes) { + $typeNamesToGenerate[] = $typeName; } } } } - } else { - foreach ($config['types'] as $typeName => $typeConfig) { - $vocabularyNamespace = $typeConfig['vocabularyNamespace'] ?? $config['vocabularyNamespace']; + } - $resource = null; - foreach ($this->graphs as $graph) { - $resources = $graph->resources(); + foreach ($config['types'] as $typeName => $typeConfig) { + $vocabularyNamespace = $typeConfig['vocabularyNamespace'] ?? $config['vocabularyNamespace']; - $typeIri = $vocabularyNamespace.$typeName; - if (isset($resources[$typeIri])) { - $resource = $graph->resource($typeIri); - break; - } + $resource = null; + foreach ($graphs as $graph) { + $resources = $graph->resources(); + + $typeIri = $vocabularyNamespace.$typeName; + if (isset($resources[$typeIri])) { + $resource = $graph->resource($typeIri); + break; } + } - if ($resource) { - $typesToGenerate[$typeName] = $resource; - } else { - $this->logger ? $this->logger->warning('Type "{typeName}" cannot be found. Using "{guessFrom}" type to generate entity.', ['typeName' => $typeName, 'guessFrom' => $typeConfig['guessFrom']]) : null; - if (isset($graph)) { - $type = $graph->resource($vocabularyNamespace.$typeConfig['guessFrom']); - $typesToGenerate[$typeName] = $type; + $typeName = $this->phpTypeConverter->escapeIdentifier($typeName); + if ($resource) { + $allTypes[$typeName] = $resource; + if (!\in_array($typeName, $typeNamesToGenerate, true)) { + $typeNamesToGenerate[] = $typeName; + } + } else { + $this->logger ? $this->logger->warning('Type "{typeName}" cannot be found. Using "{guessFrom}" type to generate entity.', ['typeName' => $typeName, 'guessFrom' => $typeConfig['guessFrom']]) : null; + if (isset($graph)) { + $type = $graph->resource($vocabularyNamespace.$typeConfig['guessFrom']); + $allTypes[$typeName] = $type; + if (!\in_array($typeName, $typeNamesToGenerate, true)) { + $typeNamesToGenerate[] = $typeName; } } } } - return $typesToGenerate; + return [$typeNamesToGenerate, $allTypes]; } public function setLogger(LoggerInterface $logger): void diff --git a/tests/ClassMutator/ClassParentMutatorTest.php b/tests/ClassMutator/ClassParentMutatorTest.php index 77c2adfa..82598fbc 100644 --- a/tests/ClassMutator/ClassParentMutatorTest.php +++ b/tests/ClassMutator/ClassParentMutatorTest.php @@ -56,10 +56,10 @@ protected function setUp(): void public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?string $loggerMessage = null): void { if ($loggerMessage) { - $this->loggerProphecy->warning($loggerMessage)->shouldBeCalled(); + $this->loggerProphecy->info($loggerMessage)->shouldBeCalled(); } - ($this->classParentMutator)($class); + ($this->classParentMutator)($class, []); $this->assertEquals($expectedClass, $class); } diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index dd5fd812..bedd045c 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -42,7 +42,7 @@ protected function setUp(): void { $this->loggerProphecy = $this->prophesize(LoggerInterface::class); - $propertyGenerator = new SchemaPropertyGenerator(new GoodRelationsBridge([]), new TypeConverter(), new PhpTypeConverter(), []); + $propertyGenerator = new SchemaPropertyGenerator(new GoodRelationsBridge([]), new TypeConverter(), new PhpTypeConverter()); $configuration = new SchemaGeneratorConfiguration(); $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ @@ -67,7 +67,7 @@ protected function setUp(): void 'https://schema.org/Person' => [new RdfResource('https://schema.org/givenName', $this->graph)], ]; - $this->classPropertiesAppender = new ClassPropertiesAppender($propertyGenerator, $processedConfiguration, $propertiesMap, []); + $this->classPropertiesAppender = new ClassPropertiesAppender($propertyGenerator, $processedConfiguration, $propertiesMap); $this->classPropertiesAppender->setLogger($this->loggerProphecy->reveal()); } @@ -85,7 +85,7 @@ public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, RdfGr $this->loggerProphecy->warning($loggerMessage)->shouldBeCalled(); } - ($this->classPropertiesAppender)($class); + ($this->classPropertiesAppender)($class, ['graphs' => [], 'cardinalities' => []]); $this->assertEquals($expectedClass, $class); } diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index d552092c..b2cda850 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -43,6 +43,9 @@ public function testDumpConfiguration(): void # RDF vocabulary format format: null # Example: rdfxml + # Generate all types for this vocabulary, even if an explicit configuration exists. If allTypes is enabled globally, it can be disabled for this particular vocabulary + allTypes: null + # Namespace of the vocabulary to import vocabularyNamespace: 'https://schema.org/' # Example: 'http://www.w3.org/ns/activitystreams#' @@ -134,6 +137,9 @@ interface: App\Model # Example: App\Model # Generate all types, even if an explicit configuration exists allTypes: false + # If a type is present in a vocabulary but not explicitly imported (types) or if the vocabulary is not totally imported (allTypes), it will be generated + resolveTypes: false + # Types to import from the vocabulary types: diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index ec895196..011e43d7 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -23,34 +23,56 @@ use EasyRdf\Graph as RdfGraph; use EasyRdf\RdfNamespace; use PHPUnit\Framework\TestCase; +use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; +use Psr\Log\LoggerInterface; +use Psr\Log\NullLogger; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Symfony\Component\Console\Style\SymfonyStyle; +use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\Finder\Finder; use Symfony\Component\String\Inflector\EnglishInflector; use Twig\Environment; /** * @author Teoh Han Hui + * + * @phpstan-type Config array{ + * vocabularies?: array{uri: string, format: ?string, allTypes?: boolean}[], + * annotationGenerators: string[], + * attributeGenerators: string[], + * types?: array, + * parent?: ?string + * }>, + * allTypes?: boolean, + * resolveTypes?: boolean + * } */ class TypesGeneratorTest extends TestCase { use ProphecyTrait; + private string $outputDir = 'build/type-generator-test'; + private TypesGenerator $typesGenerator; + private FilesGenerator $filesGenerator; + protected function setUp(): void { RdfNamespace::set('schema', 'https://schema.org/'); - } - public function testGenerate(): void - { $twigProphecy = $this->prophesize(Environment::class); $twig = $twigProphecy->reveal(); $cardinalitiesExtractorProphecy = $this->prophesize(CardinalitiesExtractor::class); $cardinalities = $this->getCardinalities(); - $cardinalitiesExtractorProphecy->extract()->willReturn($cardinalities)->shouldBeCalled(); + $cardinalitiesExtractorProphecy->extract(Argument::type('array'))->willReturn($cardinalities); $cardinalitiesExtractor = $cardinalitiesExtractorProphecy->reveal(); $goodRelationsBridgeProphecy = $this->prophesize(GoodRelationsBridge::class); @@ -58,30 +80,29 @@ public function testGenerate(): void $inflector = new EnglishInflector(); - $typesGenerator = new TypesGenerator( + $this->typesGenerator = new TypesGenerator( $inflector, - $this->getGraphs(), new PhpTypeConverter(), $cardinalitiesExtractor, $goodRelationsBridge ); - $filesGenerator = new FilesGenerator( + $this->filesGenerator = new FilesGenerator( $inflector, new Printer(), $twig, new SymfonyStyle(new ArrayInput([]), new NullOutput()) ); + } - $outputDir = 'build/type-generator-test'; - $configuration = new SchemaGeneratorConfiguration(); - /** @var Configuration $processedConfiguration */ - $processedConfiguration = (new Processor())->processConfiguration($configuration, [$this->getConfig()]); - $processedConfiguration['output'] = $outputDir; - $classes = $typesGenerator->generate($processedConfiguration); - $filesGenerator->generate($classes, $processedConfiguration); + public function testGenerate(): void + { + $this->generateForConfiguration($this->getConfig(), $this->getGraphs()); + + $finder = new Finder(); + self::assertSame(6, $finder->files()->in($this->outputDir)->count()); - $article = file_get_contents("$outputDir/App/Entity/Article.php"); + $article = file_get_contents("$this->outputDir/App/Entity/Article.php"); $this->assertStringContainsString('abstract class Article extends CreativeWork', $article); $this->assertStringContainsString('private ?string $articleBody = null;', $article); $this->assertStringContainsString('private array $articleSection = [];', $article); @@ -90,19 +111,19 @@ public function testGenerate(): void $this->assertStringContainsString('public function addArticleSection(string $articleSection): void', $article); $this->assertStringContainsString('public function removeArticleSection(string $articleSection): void', $article); - $creativeWork = file_get_contents("$outputDir/App/Entity/CreativeWork.php"); + $creativeWork = file_get_contents("$this->outputDir/App/Entity/CreativeWork.php"); $this->assertStringContainsString('abstract class CreativeWork extends Thing', $creativeWork); $this->assertStringContainsString('private ?Person $author = null;', $creativeWork); $this->assertStringContainsString('private ?\DateTimeInterface $datePublished = null;', $creativeWork); $this->assertStringContainsString('private ?string $headline = null;', $creativeWork); $this->assertStringContainsString('private ?bool $isFamilyFriendly = null;', $creativeWork); - $blogPosting = file_get_contents("$outputDir/App/Entity/BlogPosting.php"); + $blogPosting = file_get_contents("$this->outputDir/App/Entity/BlogPosting.php"); $this->assertStringContainsString('class BlogPosting extends SocialMediaPosting', $blogPosting); $this->assertStringContainsString('private ?int $id = null;', $blogPosting); $this->assertStringContainsString('public function getId(): ?int', $blogPosting); - $socialMediaPosting = file_get_contents("$outputDir/App/Entity/SocialMediaPosting.php"); + $socialMediaPosting = file_get_contents("$this->outputDir/App/Entity/SocialMediaPosting.php"); $this->assertStringContainsString('abstract class SocialMediaPosting extends Article', $socialMediaPosting); $this->assertStringContainsString('private ?CreativeWork $sharedContent = null;', $socialMediaPosting); $this->assertStringContainsString(<<<'PHP' @@ -119,12 +140,12 @@ public function getSharedContent(): ?CreativeWork } PHP, $socialMediaPosting); - $person = file_get_contents("$outputDir/App/Entity/Person.php"); + $person = file_get_contents("$this->outputDir/App/Entity/Person.php"); $this->assertStringContainsString('class Person extends Thing', $person); $this->assertStringContainsString('private ?int $id = null;', $person); $this->assertStringContainsString('public function getId(): ?int', $person); - $thing = file_get_contents("$outputDir/App/Entity/Thing.php"); + $thing = file_get_contents("$this->outputDir/App/Entity/Thing.php"); $this->assertStringContainsString(<<<'PHP' abstract class Thing { @@ -143,12 +164,71 @@ public function getName(): ?string PHP, $thing); } + public function testGenerateAllResolveTypes(): void + { + $this->generateForConfiguration($this->getAllResolveTypesConfig(), $this->getGraphs()); + + $finder = new Finder(); + self::assertSame(2, $finder->files()->in($this->outputDir)->count()); + } + + public function testGenerateVocabAllTypes(): void + { + $this->generateForConfiguration($this->getVocabAllTypesConfig(), $this->getGraphs()); + + $finder = new Finder(); + self::assertSame(2, $finder->files()->in($this->outputDir)->count()); + } + + public function testGenerateMissingParent(): void + { + $loggerProphecy = $this->prophesize(LoggerInterface::class); + $loggerProphecy->error('The type "CreativeWork" (parent of "https://schema.org/Article") doesn\'t exist')->shouldBeCalled(); + $this->typesGenerator->setLogger($loggerProphecy->reveal()); + + $this->generateForConfiguration($this->getMissingParentConfig(), $this->getGraphs()); + + $finder = new Finder(); + self::assertSame(1, $finder->files()->in($this->outputDir)->count()); + + $this->typesGenerator->setLogger(new NullLogger()); + } + + /** + * @param Config $config + */ + private function generateForConfiguration(array $config, array $graphs): void + { + $finder = new Finder(); + + $filesystem = new Filesystem(); + if ($filesystem->exists($this->outputDir)) { + $filesystem->remove($finder->files()->in($this->outputDir)); + } + + $configuration = new SchemaGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [$config]); + $processedConfiguration['output'] = $this->outputDir; + $classes = $this->typesGenerator->generate($graphs, $processedConfiguration); + $this->filesGenerator->generate($classes, $processedConfiguration); + } + /** * @return RdfGraph[] */ private function getGraphs(): array { - $graph = new RdfGraph(); + $nodeGraph = new RdfGraph('nodefr-2.jsonld'); + + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity', 'rdf:type', 'rdfs:Class'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity', 'rdfs:subClassOf', 'https://schema.org/Thing'); + + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'rdf:type', 'rdf:Property'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'https://schema.org/Text'); + + $graph = new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI); $graph->addResource('https://schema.org/Article', 'rdf:type', 'rdfs:Class'); $graph->addResource('https://schema.org/Article', 'rdfs:subClassOf', 'https://schema.org/CreativeWork'); @@ -199,7 +279,7 @@ private function getGraphs(): array $graph->addResource('https://schema.org/sharedContent', 'schema:domainIncludes', 'https://schema.org/SocialMediaPosting'); $graph->addResource('https://schema.org/sharedContent', 'schema:rangeIncludes', 'https://schema.org/CreativeWork'); - return [$graph]; + return [$nodeGraph, $graph]; } /** @@ -220,17 +300,7 @@ private function getCardinalities(): array } /** - * @return array{ - * annotationGenerators: string[], - * attributeGenerators: string[], - * types: array - * }> - * } + * @return Config */ private function getConfig(): array { @@ -279,4 +349,69 @@ private function getConfig(): array ], ]; } + + /** + * @return Config + */ + private function getMissingParentConfig(): array + { + return [ + 'annotationGenerators' => [ + ], + 'attributeGenerators' => [ + ], + 'types' => [ + 'Article' => [ + 'parent' => null, + 'properties' => [ + 'articleBody' => null, + 'articleSection' => null, + ], + ], + ], + ]; + } + + /** + * @return Config + */ + private function getAllResolveTypesConfig(): array + { + return [ + 'vocabularies' => [ + ['uri' => SchemaGeneratorConfiguration::SCHEMA_ORG_URI, 'format' => null, 'allTypes' => false], + ['uri' => 'nodefr-2.jsonld', 'format' => 'jsonld'], + ], + 'annotationGenerators' => [ + ], + 'attributeGenerators' => [ + ], + 'allTypes' => true, + 'resolveTypes' => true, + ]; + } + + /** + * @return Config + */ + private function getVocabAllTypesConfig(): array + { + return [ + 'vocabularies' => [ + ['uri' => SchemaGeneratorConfiguration::SCHEMA_ORG_URI, 'format' => null, 'allTypes' => false], + ['uri' => 'nodefr-2.jsonld', 'format' => 'jsonld', 'allTypes' => true], + ], + 'annotationGenerators' => [ + ], + 'attributeGenerators' => [ + ], + 'types' => [ + 'BlogPosting' => [ + 'parent' => null, + 'allProperties' => true, + 'properties' => null, + ], + ], + ]; + } } From cb37c415b12f916c4ae90a7bdce26638b9d210b4 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 16 Jun 2022 17:56:44 +0200 Subject: [PATCH 210/258] fix: do not define blank node types (#375) --- src/TypesGenerator.php | 9 ++++----- tests/TypesGeneratorTest.php | 2 ++ 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 5a3ddbad..14d05c13 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -236,11 +236,6 @@ public function generate(array $graphs, array $config): array */ private function buildClass(array $graphs, array $cardinalities, string $typeName, RdfResource $type, array $propertiesMap, array $config): ?SchemaClass { - if ($type->isBNode()) { - // Ignore blank nodes - return null; - } - if ($type->isA('owl:DeprecatedClass')) { if (!isset($config['types'][$typeName])) { return null; @@ -444,6 +439,10 @@ private function defineTypesToGenerate(array $graphs, array $config): array } foreach (self::$classTypes as $classType) { foreach ($graph->allOfType($classType) as $type) { + if ($type->isBNode()) { + continue; + } + $typeName = $this->phpTypeConverter->escapeIdentifier($type->localName()); if (!($config['types'][$typeName]['exclude'] ?? false)) { if ($config['resolveTypes'] || $vocabAllTypes) { diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 011e43d7..873e586c 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -224,6 +224,8 @@ private function getGraphs(): array $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity', 'rdf:type', 'rdfs:Class'); $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity', 'rdfs:subClassOf', 'https://schema.org/Thing'); + $nodeGraph->addResource('_:b0_n0', 'rdf:type', 'rdfs:Class'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'rdf:type', 'rdf:Property'); $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity'); $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'https://schema.org/Text'); From e634e2fd1c339e4aa98537b20547ee686002cf36 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Fri, 17 Jun 2022 11:36:06 +0200 Subject: [PATCH 211/258] fix: manage lang string directly in range (#376) --- src/PhpTypeConverter.php | 9 ++++--- tests/Command/GenerateCommandTest.php | 24 +++++++++++++++++++ tests/TypesGeneratorTest.php | 9 +++++++ ...vitystreams.yaml => activity-streams.yaml} | 0 4 files changed, 39 insertions(+), 3 deletions(-) rename tests/config/{activitystreams.yaml => activity-streams.yaml} (100%) diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index 7ac6e714..7460382f 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -21,6 +21,8 @@ final class PhpTypeConverter implements PhpTypeConverterInterface { + private const RDF_LANG_STRING = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'; + /** * Is this type a datatype? */ @@ -107,16 +109,17 @@ private function getNonArrayType(SchemaProperty $property, array $classes): ?str } /** - * This is a hack to detect internationalized strings in ActivityStreams. + * This is a hack to detect internationalized strings. * * @todo find something smarter to detect this kind of strings */ private function isLangString(RdfResource $range): bool { - return $range->isBNode() && + return self::RDF_LANG_STRING === $this->getUri($range) + || ($range->isBNode() && null !== ($unionOf = $range->get('owl:unionOf')) && null !== ($rdfFirst = $unionOf->get('rdf:first')) && - 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString' === $rdfFirst->getUri(); + self::RDF_LANG_STRING === $rdfFirst->getUri()); } private function getUri(RdfResource $range): string diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index b62456a3..1afbfded 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -424,6 +424,30 @@ public function testSupersededProperties(): void $this->assertStringNotContainsString('protected', $creativeWork); } + public function testActivityStreams(): void + { + $outputDir = __DIR__.'/../../build/activity-streams'; + $config = __DIR__.'/../config/activity-streams.yaml'; + + $this->fs->mkdir($outputDir); + + $commandTester = new CommandTester(new GenerateCommand()); + $this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config])); + + $object = file_get_contents("$outputDir/App/Entity/Object_.php"); + + $this->assertStringContainsString(<<<'PHP' + /** + * The content of the object. + * + * @see http://www.w3.org/ns/activitystreams#content + */ + #[ApiProperty(iri: 'http://www.w3.org/ns/activitystreams#content')] + private ?string $content = null; +PHP + , $object); + } + public function testGenerationWithoutConfigFileQuestion(): void { // No config file is given. diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 873e586c..4c203840 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -170,6 +170,14 @@ public function testGenerateAllResolveTypes(): void $finder = new Finder(); self::assertSame(2, $finder->files()->in($this->outputDir)->count()); + + $competencyWorldEntity = file_get_contents("$this->outputDir/App/Entity/CompetencyWorldEntity.php"); + $this->assertStringContainsString('class CompetencyWorldEntity extends Thing', $competencyWorldEntity); + $this->assertStringContainsString('private ?int $id = null;', $competencyWorldEntity); + $this->assertStringContainsString('private string $hasAppellation;', $competencyWorldEntity); + $this->assertStringContainsString('public function getId(): ?int', $competencyWorldEntity); + $this->assertStringContainsString('public function setHasAppellation(string $hasAppellation): void', $competencyWorldEntity); + $this->assertStringContainsString('public function getHasAppellation(): string', $competencyWorldEntity); } public function testGenerateVocabAllTypes(): void @@ -228,6 +236,7 @@ private function getGraphs(): array $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'rdf:type', 'rdf:Property'); $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'); $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'https://schema.org/Text'); $graph = new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI); diff --git a/tests/config/activitystreams.yaml b/tests/config/activity-streams.yaml similarity index 100% rename from tests/config/activitystreams.yaml rename to tests/config/activity-streams.yaml From 9ecfdc80221d47e3745ca1337657e871d37cd0af Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Fri, 17 Jun 2022 14:21:33 +0200 Subject: [PATCH 212/258] refactor: better handling of data types (#377) --- src/OpenApi/PhpTypeConverter.php | 6 --- src/PhpTypeConverter.php | 39 ++----------------- src/PhpTypeConverterInterface.php | 6 --- .../PropertyGenerator/PropertyGenerator.php | 2 +- src/Schema/TypeConverter.php | 12 +++++- tests/Command/GenerateCommandTest.php | 1 + 6 files changed, 16 insertions(+), 50 deletions(-) diff --git a/src/OpenApi/PhpTypeConverter.php b/src/OpenApi/PhpTypeConverter.php index 07f5b208..a2a6b303 100644 --- a/src/OpenApi/PhpTypeConverter.php +++ b/src/OpenApi/PhpTypeConverter.php @@ -15,15 +15,9 @@ use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; -use EasyRdf\Resource as RdfResource; final class PhpTypeConverter implements PhpTypeConverterInterface { - public function isDatatype(RdfResource $range): bool - { - return true; - } - public function getPhpType(Property $property, array $config = [], array $classes = []): ?string { if ($property->reference && $property->isArray) { diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index 7460382f..340d2a21 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -17,18 +17,14 @@ use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; use ApiPlatform\SchemaGenerator\Schema\TypeConverter; -use EasyRdf\Resource as RdfResource; final class PhpTypeConverter implements PhpTypeConverterInterface { - private const RDF_LANG_STRING = 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'; + private TypeConverter $typeConverter; - /** - * Is this type a datatype? - */ - public function isDatatype(RdfResource $range): bool + public function __construct() { - return isset(TypeConverter::RANGE_MAPPING[$this->getUri($range)]) || $this->isLangString($range); + $this->typeConverter = new TypeConverter(); } public function getPhpType(Property $property, array $config = [], array $classes = []): ?string @@ -38,7 +34,7 @@ public function getPhpType(Property $property, array $config = [], array $classe } if ($property->isArray && $property->range) { - return ($config['doctrine']['useCollection'] ?? false) && !$this->isDatatype($property->range) ? 'Collection' : 'array'; + return ($config['doctrine']['useCollection'] ?? false) && !$this->typeConverter->getType($property->range) ? 'Collection' : 'array'; } return $this->getNonArrayType($property, $classes); @@ -101,33 +97,6 @@ private function getNonArrayType(SchemaProperty $property, array $classes): ?str return $type; } - if ($this->isLangString($property->range)) { - return 'string'; - } - return null; } - - /** - * This is a hack to detect internationalized strings. - * - * @todo find something smarter to detect this kind of strings - */ - private function isLangString(RdfResource $range): bool - { - return self::RDF_LANG_STRING === $this->getUri($range) - || ($range->isBNode() && - null !== ($unionOf = $range->get('owl:unionOf')) && - null !== ($rdfFirst = $unionOf->get('rdf:first')) && - self::RDF_LANG_STRING === $rdfFirst->getUri()); - } - - private function getUri(RdfResource $range): string - { - if ($range->isBNode() && $onDatatype = $range->get('owl:onDatatype')) { - return $onDatatype->getUri(); - } - - return $range->getUri(); - } } diff --git a/src/PhpTypeConverterInterface.php b/src/PhpTypeConverterInterface.php index d588849f..5d280bcb 100644 --- a/src/PhpTypeConverterInterface.php +++ b/src/PhpTypeConverterInterface.php @@ -15,7 +15,6 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; -use EasyRdf\Resource as RdfResource; interface PhpTypeConverterInterface { @@ -27,11 +26,6 @@ interface PhpTypeConverterInterface 'collection', // Doctrine ]; - /** - * Is this type a datatype? - */ - public function isDatatype(RdfResource $range): bool; - /** * Gets the PHP type of this field. * diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 78f7a8f9..b05afebb 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -177,7 +177,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont private function getRanges(RdfResource $range, ?array $propertyConfig, array $config): array { $localName = $range->localName(); - $dataType = $this->phpTypeConverter->isDatatype($range); + $dataType = (bool) $this->typeConverter->getType($range); $ranges = []; if (!$dataType && $range->isBNode()) { if (null !== ($unionOf = $range->get('owl:unionOf'))) { diff --git a/src/Schema/TypeConverter.php b/src/Schema/TypeConverter.php index fc789818..6b0a515b 100644 --- a/src/Schema/TypeConverter.php +++ b/src/Schema/TypeConverter.php @@ -17,7 +17,7 @@ final class TypeConverter { - public const RANGE_MAPPING = [ + public const RANGE_DATA_TYPE_MAPPING = [ 'https://schema.org/URL' => 'url', 'https://schema.org/Boolean' => 'boolean', @@ -89,6 +89,8 @@ final class TypeConverter 'http://www.w3.org/2001/XMLSchema#ENTITY' => 'string', 'http://www.w3.org/2001/XMLSchema#ENTITIES' => 'string', + 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString' => 'string', + 'https://schema.org/DataType' => 'mixed', ]; @@ -98,7 +100,7 @@ public function getType(?RdfResource $range): ?string return null; } - return self::RANGE_MAPPING[$this->getUri($range)] ?? null; + return self::RANGE_DATA_TYPE_MAPPING[$this->getUri($range)] ?? null; } private function getUri(RdfResource $range): string @@ -107,6 +109,12 @@ private function getUri(RdfResource $range): string return $onDatatype->getUri(); } + if ($range->isBNode() && + null !== ($unionOf = $range->get('owl:unionOf')) && + null !== ($rdfFirst = $unionOf->get('rdf:first'))) { + return $rdfFirst->getUri(); + } + return $range->getUri(); } } diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 1afbfded..491dc538 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -442,6 +442,7 @@ public function testActivityStreams(): void * * @see http://www.w3.org/ns/activitystreams#content */ + #[ORM\Column(type: 'text', nullable: true)] #[ApiProperty(iri: 'http://www.w3.org/ns/activitystreams#content')] private ?string $content = null; PHP From cc3461983b933a6a969a27e0b9084b9fbad34aab Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Mon, 20 Jun 2022 16:56:57 +0200 Subject: [PATCH 213/258] feat: add api(Resource/Property)Arguments to types and vocab (#378) --- phpstan.neon | 6 +- .../ApiPlatformCoreAttributeGenerator.php | 8 +-- src/ClassMutator/ClassMutatorInterface.php | 2 +- src/Model/Class_.php | 3 +- src/Model/Property.php | 3 +- .../PropertyGeneratorInterface.php | 2 +- src/Schema/Generator.php | 10 +-- .../PropertyGenerator/PropertyGenerator.php | 2 +- src/SchemaGeneratorConfiguration.php | 69 +++++++++++++------ src/TypesGenerator.php | 11 +-- .../ApiPlatformCoreAttributeGeneratorTest.php | 14 ++-- tests/Command/DumpConfigurationTest.php | 15 ++-- tests/Command/GenerateCommandTest.php | 14 ++++ tests/config/activity-streams.yaml | 2 +- tests/e2e/schema.yml | 5 +- 15 files changed, 103 insertions(+), 63 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 823b6bb1..38698a67 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,7 +10,7 @@ parameters: relationTableName: ?string, cardinality: string, ormColumn: array, - security: ?string, + apiPropertyArguments: array{}, groups: string[], mappedBy: ?string, inversedBy: ?string, @@ -34,14 +34,14 @@ parameters: parent: false|string, guessFrom: string, operations: array>, - security: ?string, + apiResourceArguments: array{}, allProperties: boolean, properties: array } ''' Configuration: ''' array{ - vocabularies: array{uri: string, format: string, allTypes: ?boolean}[], + vocabularies: array{uri: string, format: string, allTypes: ?boolean, apiResourceArguments: array{}}[], vocabularyNamespace: string, relations: string[], debug: boolean, diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 3251093e..cbff304c 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -46,8 +46,8 @@ public function generateClassAttributes(Class_ $class): array if ($class->rdfType()) { $arguments['iri'] = $class->rdfType(); } - if ($class->security) { - $arguments['security'] = $class->security; + if ($class->apiResourceArguments) { + $arguments = array_merge($arguments, $class->apiResourceArguments); } if ($class->operations) { @@ -98,8 +98,8 @@ public function generatePropertyAttributes(Property $property, string $className $arguments['iri'] = $property->rdfType(); } - if ($property->security) { - $arguments['security'] = $property->security; + if ($property->apiPropertyArguments) { + $arguments = array_merge($arguments, $property->apiPropertyArguments); } return $property->isCustom ? [] : [new Attribute('ApiProperty', $arguments)]; diff --git a/src/ClassMutator/ClassMutatorInterface.php b/src/ClassMutator/ClassMutatorInterface.php index 387d2a0e..ccc16ab4 100644 --- a/src/ClassMutator/ClassMutatorInterface.php +++ b/src/ClassMutator/ClassMutatorInterface.php @@ -17,6 +17,6 @@ interface ClassMutatorInterface { - // @phpstan-ignore-next-line + // @phpstan-ignore-next-line dynamic context public function __invoke(Class_ $class, array $context): void; } diff --git a/src/Model/Class_.php b/src/Model/Class_.php index e2e0bcaa..7b04af28 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -44,7 +44,8 @@ abstract class Class_ public bool $isAbstract = false; public bool $hasChild = false; public bool $isEmbeddable = false; - public ?string $security = null; + // @phpstan-ignore-next-line dynamic array + public array $apiResourceArguments = []; /** @var array> */ public array $operations = []; diff --git a/src/Model/Property.php b/src/Model/Property.php index dad3071a..21ac37bb 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -51,7 +51,8 @@ abstract class Property public ?string $adderRemoverTypeHint = null; /** @var string[] */ public array $groups = []; - public ?string $security = null; + // @phpstan-ignore-next-line dynamic array + public array $apiPropertyArguments = []; /** @var Attribute[] */ private array $attributes = []; /** @var string[] */ diff --git a/src/PropertyGenerator/PropertyGeneratorInterface.php b/src/PropertyGenerator/PropertyGeneratorInterface.php index 3bdfe421..e82c13f0 100644 --- a/src/PropertyGenerator/PropertyGeneratorInterface.php +++ b/src/PropertyGenerator/PropertyGeneratorInterface.php @@ -21,7 +21,7 @@ interface PropertyGeneratorInterface /** * @param Configuration $config */ - // @phpstan-ignore-next-line + // @phpstan-ignore-next-line dynamic context public function __invoke( string $name, array $config, diff --git a/src/Schema/Generator.php b/src/Schema/Generator.php index 67c8de6c..aa0a5bee 100644 --- a/src/Schema/Generator.php +++ b/src/Schema/Generator.php @@ -34,12 +34,12 @@ final class Generator public function generate(array $configuration, OutputInterface $output, SymfonyStyle $io): void { $graphs = []; - foreach ($configuration['vocabularies'] as $vocab) { - $graph = new RdfGraph($vocab['uri']); - if (0 === strpos($vocab['uri'], 'http://') || 0 === strpos($vocab['uri'], 'https://')) { - $graph->load($vocab['uri'], $vocab['format']); + foreach ($configuration['vocabularies'] as $uri => $vocab) { + $graph = new RdfGraph($uri); + if (0 === strpos($uri, 'http://') || 0 === strpos($uri, 'https://')) { + $graph->load($uri, $vocab['format']); } else { - $graph->parseFile($vocab['uri'], $vocab['format']); + $graph->parseFile($uri, $vocab['format']); } $graphs[] = $graph; diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index b05afebb..fefb40da 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -163,7 +163,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; $schemaProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; $schemaProperty->groups = $propertyConfig['groups'] ?? []; - $schemaProperty->security = $propertyConfig['security'] ?? null; + $schemaProperty->apiPropertyArguments = $propertyConfig['apiPropertyArguments'] ?? []; return $schemaProperty; } diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 4b0a9cc4..31c7bd97 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -46,6 +46,15 @@ public function getConfigTreeBuilder(): TreeBuilder { $namespacePrefix = $this->defaultPrefix ?? 'App\\'; + /* @see https://yaml.org/type/omap.html */ + $transformOmap = fn (array $nodeConfig) => !empty(array_filter( + $nodeConfig, + fn ($v, $k) => \is_int($k) && \is_array($v) && 1 === \count($v) && \is_string(array_keys($v)[0]), + \ARRAY_FILTER_USE_BOTH + )) + ? array_reduce(array_values($nodeConfig), fn (array $map, array $v) => $map + $v, []) + : $nodeConfig; + $treeBuilder = new TreeBuilder('config'); $treeBuilder @@ -59,23 +68,25 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->arrayNode('vocabularies') ->info('RDF vocabularies') - ->defaultValue([['uri' => self::SCHEMA_ORG_URI, 'format' => 'rdfxml']]) + ->defaultValue([self::SCHEMA_ORG_URI => ['format' => 'rdfxml']]) ->beforeNormalization() ->ifArray() - ->then(static function (array $v) { - return array_map( - static function ($rdf) { - return \is_scalar($rdf) ? ['uri' => $rdf, 'format' => null] : $rdf; - }, - $v - ); - }) + ->then(fn (array $v) => array_map(fn ($rdf) => \is_scalar($rdf) ? ['uri' => $rdf] : $rdf, $v)) ->end() + ->useAttributeAsKey('uri') ->arrayPrototype() ->children() - ->scalarNode('uri')->defaultValue(self::SCHEMA_ORG_URI)->info('RDF vocabulary to use')->example('https://schema.org/version/latest/schemaorg-current-https.rdf')->end() + ->scalarNode('uri')->info('RDF vocabulary to use')->example('https://schema.org/version/latest/schemaorg-current-https.rdf')->end() ->scalarNode('format')->defaultNull()->info('RDF vocabulary format')->example('rdfxml')->end() ->booleanNode('allTypes')->defaultNull()->info('Generate all types for this vocabulary, even if an explicit configuration exists. If allTypes is enabled globally, it can be disabled for this particular vocabulary')->end() + ->arrayNode('apiResourceArguments') + ->info('Arguments to add to ApiResource for all the classes generated for this vocabulary') + ->variablePrototype()->end() + ->beforeNormalization() + ->ifArray() + ->then($transformOmap) + ->end() + ->end() ->end() ->end() ->end() @@ -84,7 +95,7 @@ static function ($rdf) { ->info('OWL relation files containing cardinality information in the GoodRelations format') ->example(self::GOOD_RELATIONS_URI) ->defaultValue([self::GOOD_RELATIONS_URI]) - ->prototype('scalar')->end() + ->scalarPrototype()->end() ->end() ->booleanNode('debug')->defaultFalse()->info('Debug mode')->end() ->arrayNode('id') @@ -119,7 +130,7 @@ static function ($rdf) { ->enumNode('resolveTargetEntityConfigType')->defaultValue('XML')->values(['XML', 'yaml'])->info('The Resolve Target Entity Listener config file type')->end() ->arrayNode('inheritanceAttributes') ->info('Doctrine inheritance attributes (if set, no other attributes are generated)') - ->prototype('variable')->end() + ->variablePrototype()->end() ->end() ->end() ->end() @@ -136,7 +147,7 @@ static function ($rdf) { ->booleanNode('fluentMutatorMethods')->defaultFalse()->info('Set this flag to true to generate fluent setter, adder and remover methods')->end() ->arrayNode('rangeMapping') ->useAttributeAsKey('name') - ->prototype('scalar')->end() + ->scalarPrototype()->end() ->end() ->booleanNode('allTypes')->defaultFalse()->info('Generate all types, even if an explicit configuration exists')->end() ->booleanNode('resolveTypes')->defaultFalse()->info('If a type is present in a vocabulary but not explicitly imported (types) or if the vocabulary is not totally imported (allTypes), it will be generated')->end() @@ -172,7 +183,7 @@ static function ($rdf) { ->children() ->arrayNode('attributes') ->info('Doctrine attributes (if set, no other attributes are generated)') - ->prototype('variable')->end() + ->variablePrototype()->end() ->end() ->end() ->end() @@ -180,9 +191,16 @@ static function ($rdf) { ->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end() ->arrayNode('operations') ->info('Operations for the class') - ->prototype('variable')->end() + ->variablePrototype()->end() + ->end() + ->arrayNode('apiResourceArguments') + ->info('Arguments to add to ApiResource (for instance security)') + ->variablePrototype()->end() + ->beforeNormalization() + ->ifArray() + ->then($transformOmap) + ->end() ->end() - ->scalarNode('security')->defaultNull()->info('Security directive for the class')->end() ->booleanNode('allProperties')->defaultFalse()->info('Import all existing properties')->end() ->arrayNode('properties') ->info('Properties of this type to use') @@ -206,12 +224,19 @@ static function ($rdf) { ->arrayNode('ormColumn') ->info('The doctrine column attribute content') ->example('{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}') - ->prototype('variable')->end() + ->variablePrototype()->end() + ->end() + ->arrayNode('apiPropertyArguments') + ->info('Arguments to add to ApiProperty (for instance security)') + ->variablePrototype()->end() + ->beforeNormalization() + ->ifArray() + ->then($transformOmap) + ->end() ->end() - ->scalarNode('security')->defaultNull()->info('Security directive for the property')->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') - ->prototype('scalar')->end() + ->scalarPrototype()->end() ->end() ->scalarNode('mappedBy')->defaultNull()->info('The doctrine mapped by attribute')->example('partOfSeason')->end() ->scalarNode('inversedBy')->defaultNull()->info('The doctrine inversed by attribute')->example('episodes')->end() @@ -233,7 +258,7 @@ static function ($rdf) { ->defaultValue([ PhpDocAnnotationGenerator::class, ]) - ->prototype('scalar')->end() + ->scalarPrototype()->end() ->end() ->arrayNode('attributeGenerators') ->info('Attribute generators to use') @@ -243,11 +268,11 @@ static function ($rdf) { ConstraintAttributeGenerator::class, SerializerGroupsAttributeGenerator::class, ]) - ->prototype('scalar')->end() + ->scalarPrototype()->end() ->end() ->arrayNode('generatorTemplates') ->info('Directories for custom generator twig templates') - ->prototype('scalar')->end() + ->scalarPrototype()->end() ->end() ->end(); diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 14d05c13..f16c877c 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -245,10 +245,11 @@ private function buildClass(array $graphs, array $cardinalities, string $typeNam } $typeConfig = $config['types'][$typeName] ?? null; + $vocabConfig = $config['vocabularies'][$type->getGraph()->getUri()] ?? null; $parent = $typeConfig['parent'] ?? null; $class = new SchemaClass($typeName, $type, $parent); $class->operations = $typeConfig['operations'] ?? []; - $class->security = $typeConfig['security'] ?? null; + $class->apiResourceArguments = array_merge($vocabConfig['apiResourceArguments'] ?? [], $typeConfig['apiResourceArguments'] ?? []); if ($class->isEnum()) { (new SchemaEnumClassMutator( @@ -430,13 +431,7 @@ private function defineTypesToGenerate(array $graphs, array $config): array $allTypes = []; foreach ($graphs as $graph) { - $vocabAllTypes = $config['allTypes']; - foreach ($config['vocabularies'] as $vocab) { - if ($graph->getUri() !== $vocab['uri']) { - continue; - } - $vocabAllTypes = $vocab['allTypes'] ?? $vocabAllTypes; - } + $vocabAllTypes = $config['vocabularies'][$graph->getUri()]['allTypes'] ?? $config['allTypes']; foreach (self::$classTypes as $classType) { foreach ($graph->allOfType($classType) as $type) { if ($type->isBNode()) { diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 85856cf4..7e628b44 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -74,9 +74,9 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'with short name' => [(new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; - $class = new SchemaClass('WithSecurity', new RdfResource('https://schema.org/WithSecurity', new RdfGraph())); - $class->security = "is_granted('ROLE_USER')"; - yield 'with security' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"])]]; + $class = new SchemaClass('WithApiResourceArguments', new RdfResource('https://schema.org/WithApiResourceArguments', new RdfGraph())); + $class->apiResourceArguments = ['security' => "is_granted('ROLE_USER')"]; + yield 'with ApiResource arguments' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithApiResourceArguments', 'security' => "is_granted('ROLE_USER')"])]]; } /** @@ -93,10 +93,10 @@ public function provideGeneratePropertyAttributesCases(): \Generator $property->resource = new RdfResource('https://schema.org/prop'); yield 'classical' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/prop'])]]; - $property = new Property('WithSecurity'); - $property->resource = new RdfResource('https://schema.org/WithSecurity'); - $property->security = "is_granted('ROLE_ADMIN')"; - yield 'with security' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_ADMIN')"])]]; + $property = new Property('WithApiPropertyArguments'); + $property->resource = new RdfResource('https://schema.org/WithApiPropertyArguments'); + $property->apiPropertyArguments = ['security' => "is_granted('ROLE_ADMIN')"]; + yield 'with ApiProperty arguments' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/WithApiPropertyArguments', 'security' => "is_granted('ROLE_ADMIN')"])]]; } public function testGenerateCustomPropertyAttributes(): void diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index b2cda850..505dc3b5 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -35,10 +35,10 @@ public function testDumpConfiguration(): void vocabularies: # Prototype - - + uri: # RDF vocabulary to use - uri: 'https://schema.org/version/latest/schemaorg-current-https.rdf' # Example: 'https://schema.org/version/latest/schemaorg-current-https.rdf' + uri: ~ # Example: 'https://schema.org/version/latest/schemaorg-current-https.rdf' # RDF vocabulary format format: null # Example: rdfxml @@ -46,6 +46,9 @@ public function testDumpConfiguration(): void # Generate all types for this vocabulary, even if an explicit configuration exists. If allTypes is enabled globally, it can be disabled for this particular vocabulary allTypes: null + # Arguments to add to ApiResource for all the classes generated for this vocabulary + apiResourceArguments: [] + # Namespace of the vocabulary to import vocabularyNamespace: 'https://schema.org/' # Example: 'http://www.w3.org/ns/activitystreams#' @@ -180,8 +183,8 @@ interface: null # Operations for the class operations: [] - # Security directive for the class - security: null + # Arguments to add to ApiResource (for instance security) + apiResourceArguments: [] # Import all existing properties allProperties: false @@ -205,8 +208,8 @@ interface: null # The doctrine column attribute content ormColumn: [] # Example: '{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}' - # Security directive for the property - security: null + # Arguments to add to ApiProperty (for instance security) + apiPropertyArguments: [] # Symfony Serialization Groups groups: [] diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 491dc538..e98f5875 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -447,6 +447,20 @@ public function testActivityStreams(): void private ?string $content = null; PHP , $object); + + $page = file_get_contents("$outputDir/App/Entity/Page.php"); + + $this->assertStringContainsString(<<<'PHP' +/** + * A Web Page. + * + * @see http://www.w3.org/ns/activitystreams#Page + */ +#[ORM\Entity] +#[ApiResource(iri: 'http://www.w3.org/ns/activitystreams#Page', routePrefix: 'as')] +class Page extends Object_ +PHP + , $page); } public function testGenerationWithoutConfigFileQuestion(): void diff --git a/tests/config/activity-streams.yaml b/tests/config/activity-streams.yaml index 7eb547cf..11288fd8 100644 --- a/tests/config/activity-streams.yaml +++ b/tests/config/activity-streams.yaml @@ -1,5 +1,5 @@ vocabularies: - - tests/data/activitystreams2.owl + - { uri: tests/data/activitystreams2.owl, apiResourceArguments: [routePrefix: 'as'] } vocabularyNamespace: http://www.w3.org/ns/activitystreams# allTypes: true types: diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 323d9def..9fdfa279 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -23,7 +23,8 @@ types: collection: get: route_name: get_person_collection - security: "is_granted('ROLE_USER')" + apiResourceArguments: + security: "is_granted('ROLE_USER')" properties: familyName: ~ givenName: ~ @@ -32,7 +33,7 @@ types: address: { range: https://schema.org/PostalAddress } birthDate: ~ telephone: ~ - email: { unique: true, security: "is_granted('ROLE_ADMIN')" } + email: { unique: true, apiPropertyArguments: [security: "is_granted('ROLE_ADMIN')"] } url: ~ siblings: { cardinality: "(0..*)" } knowsAbout: { range: https://schema.org/Thing } From 5df7d1be1b08d1a268222144064af779e65656b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Suwi=C5=84ski?= Date: Mon, 20 Jun 2022 18:47:35 +0200 Subject: [PATCH 214/258] feat: custom attributes (#366) --- phpstan.neon | 10 +-- .../ApiPlatformCoreAttributeGenerator.php | 7 --- .../DoctrineMongoDBAttributeGenerator.php | 9 --- .../DoctrineOrmAttributeGenerator.php | 9 --- src/Model/AddAttributeTrait.php | 38 ++++++++++++ src/Model/Class_.php | 12 +--- src/Model/Property.php | 12 +--- src/OpenApi/ClassGenerator.php | 4 ++ .../PropertyGenerator/PropertyGenerator.php | 6 +- src/SchemaGeneratorConfiguration.php | 61 +++++++++---------- src/TypesGenerator.php | 9 ++- .../ApiPlatformCoreAttributeGeneratorTest.php | 9 --- .../DoctrineMongoDBAttributeGeneratorTest.php | 6 -- .../DoctrineOrmAttributeGeneratorTest.php | 6 -- tests/Command/DumpConfigurationTest.php | 30 +++++---- tests/Command/GenerateCommandTest.php | 45 +++++++++++++- tests/config/activity-streams.yaml | 2 +- tests/config/custom-attributes.yaml | 28 +++++++++ .../customized/App/Schema/Entity/Person.php | 2 +- .../e2e/original/App/Schema/Entity/Person.php | 2 +- tests/e2e/schema.yml | 8 ++- 21 files changed, 189 insertions(+), 126 deletions(-) create mode 100644 src/Model/AddAttributeTrait.php create mode 100644 tests/config/custom-attributes.yaml diff --git a/phpstan.neon b/phpstan.neon index 38698a67..f3e92614 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -10,7 +10,6 @@ parameters: relationTableName: ?string, cardinality: string, ormColumn: array, - apiPropertyArguments: array{}, groups: string[], mappedBy: ?string, inversedBy: ?string, @@ -20,7 +19,8 @@ parameters: required: ?boolean, unique: boolean, embedded: boolean, - columnPrefix: false|string + columnPrefix: false|string, + attributes: array } ''' TypeConfiguration: ''' @@ -30,18 +30,17 @@ parameters: abstract: ?boolean, embeddable: boolean, namespaces: array{class: ?string, interface: ?string}, - doctrine: array{attributes: array}, + attributes: array, parent: false|string, guessFrom: string, operations: array>, - apiResourceArguments: array{}, allProperties: boolean, properties: array } ''' Configuration: ''' array{ - vocabularies: array{uri: string, format: string, allTypes: ?boolean, apiResourceArguments: array{}}[], + vocabularies: array{uri: string, format: string, allTypes: ?boolean, attributes: array}[], vocabularyNamespace: string, relations: string[], debug: boolean, @@ -50,6 +49,7 @@ parameters: checkIsGoodRelations: boolean, header: ?string, namespaces: array{prefix: ?string, entity: string, enum: string, interface: string}, + uses: array, doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, resolveTargetEntityConfigType: 'XML'|'yaml', inheritanceAttributes: array}, validator: array{assertType: boolean}, author: false|string, diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index cbff304c..96003152 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -46,9 +46,6 @@ public function generateClassAttributes(Class_ $class): array if ($class->rdfType()) { $arguments['iri'] = $class->rdfType(); } - if ($class->apiResourceArguments) { - $arguments = array_merge($arguments, $class->apiResourceArguments); - } if ($class->operations) { $operations = $this->validateClassOperations($class->operations); @@ -98,10 +95,6 @@ public function generatePropertyAttributes(Property $property, string $className $arguments['iri'] = $property->rdfType(); } - if ($property->apiPropertyArguments) { - $arguments = array_merge($arguments, $property->apiPropertyArguments); - } - return $property->isCustom ? [] : [new Attribute('ApiProperty', $arguments)]; } diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index fa7c4712..4d77f086 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -31,15 +31,6 @@ final class DoctrineMongoDBAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($doctrineAttributes = isset($this->config['types'][$class->name()]) ? $this->config['types'][$class->name()]['doctrine']['attributes'] : false) { - $attributes = []; - foreach ($doctrineAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs); - } - - return $attributes; - } - if ($class->isEnum()) { return []; } diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index a87204a0..352b2c99 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -42,15 +42,6 @@ final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($doctrineAttributes = (isset($this->config['types'][$class->name()]) ? $this->config['types'][$class->name()]['doctrine']['attributes'] : false)) { - $attributes = []; - foreach ($doctrineAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs); - } - - return $attributes; - } - if ($class->isEnum()) { return []; } diff --git a/src/Model/AddAttributeTrait.php b/src/Model/AddAttributeTrait.php new file mode 100644 index 00000000..df93e9b9 --- /dev/null +++ b/src/Model/AddAttributeTrait.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model; + +trait AddAttributeTrait +{ + public function addAttribute(Attribute $attribute): self + { + if (!\in_array($attribute, $this->attributes, true)) { + if (empty(array_filter( + $this->attributes, + fn (Attribute $attr) => $attr->name() === $attribute->name() + ))) { + $this->attributes[] = $attribute; + } else { + $this->attributes = array_map( + fn (Attribute $attr) => $attr->name() === $attribute->name() + ? new Attribute($attr->name(), array_merge($attribute->args(), $attr->args())) + : $attr, + $this->attributes + ); + } + } + + return $this; + } +} diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 7b04af28..acc79f52 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -22,6 +22,7 @@ abstract class Class_ { + use AddAttributeTrait; use ResolveNameTrait; protected string $name; @@ -44,8 +45,6 @@ abstract class Class_ public bool $isAbstract = false; public bool $hasChild = false; public bool $isEmbeddable = false; - // @phpstan-ignore-next-line dynamic array - public array $apiResourceArguments = []; /** @var array> */ public array $operations = []; @@ -168,15 +167,6 @@ public function addUse(Use_ $use): self return $this; } - public function addAttribute(Attribute $attribute): self - { - if (!\in_array($attribute, $this->attributes, true)) { - $this->attributes[] = $attribute; - } - - return $this; - } - public function addAnnotation(string $annotation): self { if ('' === $annotation || !\in_array($annotation, $this->annotations, true)) { diff --git a/src/Model/Property.php b/src/Model/Property.php index 21ac37bb..5de420e2 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -20,6 +20,7 @@ abstract class Property { + use AddAttributeTrait; use ResolveNameTrait; private string $name; @@ -51,8 +52,6 @@ abstract class Property public ?string $adderRemoverTypeHint = null; /** @var string[] */ public array $groups = []; - // @phpstan-ignore-next-line dynamic array - public array $apiPropertyArguments = []; /** @var Attribute[] */ private array $attributes = []; /** @var string[] */ @@ -80,15 +79,6 @@ abstract public function description(): ?string; abstract public function rdfType(): ?string; - public function addAttribute(Attribute $attribute): self - { - if (!\in_array($attribute, $this->attributes, true)) { - $this->attributes[] = $attribute; - } - - return $this; - } - public function addAnnotation(string $annotation): self { if ('' === $annotation || !\in_array($annotation, $this->annotations, true)) { diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 2ef200df..9365feb5 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -224,6 +224,10 @@ private function buildClassFromSchema(Schema $schema, string $name, array $confi $class->setRdfType($schema->externalDocs->url); } + foreach ($config['uses'] as $useName => $useArgs) { + $class->addUse(new Use_($useName, $useArgs['alias'] ?? null)); + } + foreach ($schema->properties as $propertyName => $schemaProperty) { \assert($schemaProperty instanceof Schema); $property = ($this->propertyGenerator)($propertyName, $config, $class, ['schema' => $schema, 'property' => $schemaProperty]); diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index fefb40da..f0b2f8bd 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -15,6 +15,7 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; @@ -163,7 +164,10 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; $schemaProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; $schemaProperty->groups = $propertyConfig['groups'] ?? []; - $schemaProperty->apiPropertyArguments = $propertyConfig['apiPropertyArguments'] ?? []; + + foreach ($propertyConfig['attributes'] ?? [] as $attributeName => $attributeArgs) { + $schemaProperty->addAttribute(new Attribute($attributeName, $attributeArgs ?? [])); + } return $schemaProperty; } diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 31c7bd97..1510a8e1 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -18,6 +18,7 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; +use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -55,6 +56,16 @@ public function getConfigTreeBuilder(): TreeBuilder ? array_reduce(array_values($nodeConfig), fn (array $map, array $v) => $map + $v, []) : $nodeConfig; + // @phpstan-ignore-next-line node is not null + $attributesNode = fn () => (new NodeBuilder()) + ->arrayNode('attributes') + ->info('Attributes (merged with generated attributes)') + ->variablePrototype()->end() + ->beforeNormalization() + ->ifArray() + ->then($transformOmap) + ->end(); + $treeBuilder = new TreeBuilder('config'); $treeBuilder @@ -79,14 +90,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('uri')->info('RDF vocabulary to use')->example('https://schema.org/version/latest/schemaorg-current-https.rdf')->end() ->scalarNode('format')->defaultNull()->info('RDF vocabulary format')->example('rdfxml')->end() ->booleanNode('allTypes')->defaultNull()->info('Generate all types for this vocabulary, even if an explicit configuration exists. If allTypes is enabled globally, it can be disabled for this particular vocabulary')->end() - ->arrayNode('apiResourceArguments') - ->info('Arguments to add to ApiResource for all the classes generated for this vocabulary') - ->variablePrototype()->end() - ->beforeNormalization() - ->ifArray() - ->then($transformOmap) - ->end() - ->end() + ->append($attributesNode()) ->end() ->end() ->end() @@ -121,6 +125,16 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('interface')->defaultValue("{$namespacePrefix}Model")->info('The namespace of the generated interfaces')->example('App\Model')->end() ->end() ->end() + ->arrayNode('uses') + ->info('Custom uses (for instance if you use a custom attribute)') + ->useAttributeAsKey('name') + ->arrayPrototype() + ->children() + ->scalarNode('name')->cannotBeEmpty()->info('Name of this use')->example('App\Attributes\MyAttribute')->end() + ->scalarNode('alias')->defaultNull()->info('The alias to use for this use')->end() + ->end() + ->end() + ->end() ->arrayNode('doctrine') ->addDefaultsIfNotSet() ->info('Doctrine') @@ -131,6 +145,10 @@ public function getConfigTreeBuilder(): TreeBuilder ->arrayNode('inheritanceAttributes') ->info('Doctrine inheritance attributes (if set, no other attributes are generated)') ->variablePrototype()->end() + ->beforeNormalization() + ->ifArray() + ->then($transformOmap) + ->end() ->end() ->end() ->end() @@ -178,29 +196,13 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('interface')->defaultNull()->info('The namespace for the generated interface (override any other defined namespace)')->end() ->end() ->end() - ->arrayNode('doctrine') - ->addDefaultsIfNotSet() - ->children() - ->arrayNode('attributes') - ->info('Doctrine attributes (if set, no other attributes are generated)') - ->variablePrototype()->end() - ->end() - ->end() - ->end() + ->append($attributesNode()) ->scalarNode('parent')->defaultFalse()->info('The parent class, set to false for a top level class')->end() ->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end() ->arrayNode('operations') ->info('Operations for the class') ->variablePrototype()->end() ->end() - ->arrayNode('apiResourceArguments') - ->info('Arguments to add to ApiResource (for instance security)') - ->variablePrototype()->end() - ->beforeNormalization() - ->ifArray() - ->then($transformOmap) - ->end() - ->end() ->booleanNode('allProperties')->defaultFalse()->info('Import all existing properties')->end() ->arrayNode('properties') ->info('Properties of this type to use') @@ -226,14 +228,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->example('{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}') ->variablePrototype()->end() ->end() - ->arrayNode('apiPropertyArguments') - ->info('Arguments to add to ApiProperty (for instance security)') - ->variablePrototype()->end() - ->beforeNormalization() - ->ifArray() - ->then($transformOmap) - ->end() - ->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') ->scalarPrototype()->end() @@ -247,6 +241,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->booleanNode('unique')->defaultFalse()->info('The property unique')->end() ->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end() ->scalarNode('columnPrefix')->defaultFalse()->info('The property columnPrefix')->end() + ->append($attributesNode()) ->end() ->end() ->end() diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index f16c877c..63359433 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -20,6 +20,7 @@ use ApiPlatform\SchemaGenerator\ClassMutator\ClassParentMutator; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesAppender; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesTypehintMutator; +use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; @@ -249,7 +250,13 @@ private function buildClass(array $graphs, array $cardinalities, string $typeNam $parent = $typeConfig['parent'] ?? null; $class = new SchemaClass($typeName, $type, $parent); $class->operations = $typeConfig['operations'] ?? []; - $class->apiResourceArguments = array_merge($vocabConfig['apiResourceArguments'] ?? [], $typeConfig['apiResourceArguments'] ?? []); + $attributes = array_merge($vocabConfig['attributes'] ?? [], $typeConfig['attributes'] ?? []); + foreach ($attributes as $attributeName => $attributeArgs) { + $class->addAttribute(new Attribute($attributeName, $attributeArgs ?? [])); + } + foreach ($config['uses'] as $useName => $useArgs) { + $class->addUse(new Use_($useName, $useArgs['alias'] ?? null)); + } if ($class->isEnum()) { (new SchemaEnumClassMutator( diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 7e628b44..1dbd5ccb 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -73,10 +73,6 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'enum' => [$class, []]; yield 'with short name' => [(new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; - - $class = new SchemaClass('WithApiResourceArguments', new RdfResource('https://schema.org/WithApiResourceArguments', new RdfGraph())); - $class->apiResourceArguments = ['security' => "is_granted('ROLE_USER')"]; - yield 'with ApiResource arguments' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithApiResourceArguments', 'security' => "is_granted('ROLE_USER')"])]]; } /** @@ -92,11 +88,6 @@ public function provideGeneratePropertyAttributesCases(): \Generator $property = new Property('prop'); $property->resource = new RdfResource('https://schema.org/prop'); yield 'classical' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/prop'])]]; - - $property = new Property('WithApiPropertyArguments'); - $property->resource = new RdfResource('https://schema.org/WithApiPropertyArguments'); - $property->apiPropertyArguments = ['security' => "is_granted('ROLE_ADMIN')"]; - yield 'with ApiProperty arguments' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/WithApiPropertyArguments', 'security' => "is_granted('ROLE_ADMIN')"])]]; } public function testGenerateCustomPropertyAttributes(): void diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 27a3dda8..82054983 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -97,16 +97,11 @@ protected function setUp(): void $myEnumClass = new SchemaClass('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; - $customAttributes = new RdfResource('https://schema.org/CustomAttributes', $graph); - $customAttributesClass = new SchemaClass('CustomAttributes', $customAttributes); - $this->classMap[$customAttributesClass->name()] = $customAttributesClass; - $configuration = new SchemaGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'id' => ['generationStrategy' => 'auto', 'writable' => true], 'types' => [ - 'CustomAttributes' => ['doctrine' => ['attributes' => ['MongoDB\Document' => ['db' => 'my_db']]]], 'Product' => null, // Vehicle is not added deliberately ], @@ -123,7 +118,6 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); - $this->assertEquals([new Attribute('MongoDB\Document', ['db' => 'my_db'])], $this->generator->generateClassAttributes($this->classMap['CustomAttributes'])); $this->assertEquals([new Attribute('MongoDB\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); $this->assertEquals([new Attribute('MongoDB\Document')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); } diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index 670af3ed..f77e4984 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -143,16 +143,11 @@ protected function setUp(): void $myEnumClass = new SchemaClass('MyEnum', $myEnum); $this->classMap[$myEnumClass->name()] = $myEnumClass; - $customAttributes = new RdfResource('https://schema.org/CustomAttributes', $graph); - $customAttributesClass = new SchemaClass('CustomAttributes', $customAttributes); - $this->classMap[$customAttributesClass->name()] = $customAttributesClass; - $configuration = new SchemaGeneratorConfiguration(); /** @var Configuration $processedConfiguration */ $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ 'id' => ['generationStrategy' => 'auto', 'writable' => true], 'types' => [ - 'CustomAttributes' => ['doctrine' => ['attributes' => ['ORM\Entity' => ['readOnly' => true]]]], 'Product' => null, // Vehicle is not added deliberately ], @@ -169,7 +164,6 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); - $this->assertEquals([new Attribute('ORM\Entity', ['readOnly' => true])], $this->generator->generateClassAttributes($this->classMap['CustomAttributes'])); $this->assertEquals([new Attribute('ORM\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); $this->assertEquals([new Attribute('ORM\Entity')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); $this->assertEquals([new Attribute('ORM\Embeddable')], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 505dc3b5..f7210c96 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -46,8 +46,8 @@ public function testDumpConfiguration(): void # Generate all types for this vocabulary, even if an explicit configuration exists. If allTypes is enabled globally, it can be disabled for this particular vocabulary allTypes: null - # Arguments to add to ApiResource for all the classes generated for this vocabulary - apiResourceArguments: [] + # Attributes (merged with generated attributes) + attributes: [] # Namespace of the vocabulary to import vocabularyNamespace: 'https://schema.org/' # Example: 'http://www.w3.org/ns/activitystreams#' @@ -100,6 +100,18 @@ enum: App\Enum # Example: App\Enum # The namespace of the generated interfaces interface: App\Model # Example: App\Model + # Custom uses (for instance if you use a custom attribute) + uses: + + # Prototype + name: + + # Name of this use + name: ~ # Example: App\Attributes\MyAttribute + + # The alias to use for this use + alias: null + # Doctrine doctrine: @@ -169,10 +181,9 @@ class: null # The namespace for the generated interface (override any other defined namespace) interface: null - doctrine: - # Doctrine attributes (if set, no other attributes are generated) - attributes: [] + # Attributes (merged with generated attributes) + attributes: [] # The parent class, set to false for a top level class parent: false @@ -183,9 +194,6 @@ interface: null # Operations for the class operations: [] - # Arguments to add to ApiResource (for instance security) - apiResourceArguments: [] - # Import all existing properties allProperties: false @@ -208,9 +216,6 @@ interface: null # The doctrine column attribute content ormColumn: [] # Example: '{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}' - # Arguments to add to ApiProperty (for instance security) - apiPropertyArguments: [] - # Symfony Serialization Groups groups: [] @@ -241,6 +246,9 @@ interface: null # The property columnPrefix columnPrefix: false + # Attributes (merged with generated attributes) + attributes: [] + # Annotation generators to use annotationGenerators: diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index e98f5875..8cfe23b1 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -75,6 +75,49 @@ public function getFriends(): Collection , $person); } + public function testCustomAttributes(): void + { + $outputDir = __DIR__.'/../../build/custom-attributes'; + $config = __DIR__.'/../config/custom-attributes.yaml'; + $this->fs->mkdir($outputDir); + $commandTester = new CommandTester(new GenerateCommand()); + $this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config])); + + $book = file_get_contents("$outputDir/App/Entity/Book.php"); + + // Attributes given as ordered map (omap). + $this->assertStringContainsString(<<<'PHP' +use ApiPlatform\Core\Annotation\ApiProperty; +use ApiPlatform\Core\Annotation\ApiResource; +use App\Attributes\MyAttribute; +use Doctrine\Common\Collections\ArrayCollection; +use Doctrine\Common\Collections\Collection; +use Doctrine\ORM\Mapping as ORM; + +/** + * A book. + * + * @see https://schema.org/Book + */ +#[ORM\Entity] +#[ApiResource(iri: 'https://schema.org/Book', routePrefix: '/library')] +#[MyAttribute] +class Book +{ +PHP + , $book); + + // Attributes given as unordered map. + $this->assertStringContainsString(<<<'PHP' + #[ORM\OneToMany(targetEntity: 'App\Entity\Review', mappedBy: 'book', cascade: ['persist', 'remove'])] +PHP + , $book); + $this->assertStringContainsString(<<<'PHP' + #[ORM\OrderBy(name: 'ASC')] +PHP + , $book); + } + public function testFluentMutators(): void { $outputDir = __DIR__.'/../../build/fluent-mutators'; @@ -456,8 +499,8 @@ public function testActivityStreams(): void * * @see http://www.w3.org/ns/activitystreams#Page */ -#[ORM\Entity] #[ApiResource(iri: 'http://www.w3.org/ns/activitystreams#Page', routePrefix: 'as')] +#[ORM\Entity] class Page extends Object_ PHP , $page); diff --git a/tests/config/activity-streams.yaml b/tests/config/activity-streams.yaml index 11288fd8..fec56a5a 100644 --- a/tests/config/activity-streams.yaml +++ b/tests/config/activity-streams.yaml @@ -1,5 +1,5 @@ vocabularies: - - { uri: tests/data/activitystreams2.owl, apiResourceArguments: [routePrefix: 'as'] } + - { uri: tests/data/activitystreams2.owl, attributes: { ApiResource: { routePrefix: 'as' } } } vocabularyNamespace: http://www.w3.org/ns/activitystreams# allTypes: true types: diff --git a/tests/config/custom-attributes.yaml b/tests/config/custom-attributes.yaml new file mode 100644 index 00000000..b70e4ca8 --- /dev/null +++ b/tests/config/custom-attributes.yaml @@ -0,0 +1,28 @@ +uses: + App\Attributes\MyAttribute: ~ +types: + Book: + attributes: + - ORM\Entity: ~ + - ApiResource: { routePrefix: '/library' } + - MyAttribute: ~ + properties: + isbn: ~ + title: { range: "https://schema.org/Text" } + author: { range: "https://schema.org/Text" } + description: ~ + reviews: + mappedBy: book + cardinality: (1..*) + attributes: + ORM\OneToMany: { cascade: [persist, remove] } + ORM\OrderBy: { name: ASC } + Review: + properties: + book: + range: Book + inversedBy: reviews + cardinality: (*..1) + author: { range: "https://schema.org/Text" } + reviewBody: ~ + rating: { range: "https://schema.org/Integer" } diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index d80f40b5..4d4eb1de 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -25,9 +25,9 @@ #[ORM\Entity] #[ApiResource( iri: 'https://schema.org/Person', - security: 'is_granted(\'ROLE_USER\')', itemOperations: ['get' => ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], collectionOperations: ['get' => ['route_name' => 'get_person_collection']], + security: 'is_granted(\'ROLE_USER\')', )] #[UniqueEntity('email')] #[MyCustomAttribute(foo: 'bar')] diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 7da0f67e..459ba111 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -22,9 +22,9 @@ #[ORM\Entity] #[ApiResource( iri: 'https://schema.org/Person', - security: 'is_granted(\'ROLE_USER\')', itemOperations: ['get' => ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], collectionOperations: ['get' => ['route_name' => 'get_person_collection']], + security: 'is_granted(\'ROLE_USER\')', )] #[UniqueEntity('email')] class Person extends Thing diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 9fdfa279..b72a5527 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -23,8 +23,10 @@ types: collection: get: route_name: get_person_collection - apiResourceArguments: - security: "is_granted('ROLE_USER')" + attributes: + ORM\Entity: ~ + ApiResource: + security: "is_granted('ROLE_USER')" properties: familyName: ~ givenName: ~ @@ -33,7 +35,7 @@ types: address: { range: https://schema.org/PostalAddress } birthDate: ~ telephone: ~ - email: { unique: true, apiPropertyArguments: [security: "is_granted('ROLE_ADMIN')"] } + email: { unique: true, attributes: { ORM\Column: ~, ApiProperty: { security: "is_granted('ROLE_ADMIN')" } } } url: ~ siblings: { cardinality: "(0..*)" } knowsAbout: { range: https://schema.org/Thing } From ce38f6eee04f71acf2f2f7ed85f8df3039a88fa9 Mon Sep 17 00:00:00 2001 From: Emmanuel Averty Date: Tue, 21 Jun 2022 13:15:24 +0200 Subject: [PATCH 215/258] feat: api platform 2.7 attributes generation (#367) --- composer.json | 4 +- composer.lock | 45 ++++++----- phpstan.neon | 3 +- .../ApiPlatformCoreAttributeGenerator.php | 77 +++++++++++++++---- src/FilesGenerator.php | 1 + src/Model/Class_.php | 2 +- src/OpenApi/ClassGenerator.php | 20 ++--- src/SchemaGeneratorConfiguration.php | 1 + src/TypesGenerator.php | 3 + .../ApiPlatformCoreAttributeGeneratorTest.php | 67 ++++++++++++---- tests/Command/DumpConfigurationTest.php | 3 + tests/Command/GenerateCommandTest.php | 12 +-- tests/config/activity-streams.yaml | 2 + .../customized/App/Schema/Entity/Brand.php | 10 +-- .../customized/App/Schema/Entity/Person.php | 38 +++++---- .../App/Schema/Entity/PostalAddress.php | 35 ++------- .../customized/App/Schema/Entity/Thing.php | 4 +- .../e2e/original/App/OpenApi/Entity/Book.php | 27 ++++--- .../e2e/original/App/OpenApi/Entity/Order.php | 8 +- .../original/App/OpenApi/Entity/Parchment.php | 15 ++-- tests/e2e/original/App/OpenApi/Entity/Pet.php | 8 +- .../original/App/OpenApi/Entity/Review.php | 21 +++-- .../original/App/OpenApi/Entity/TopBook.php | 8 +- .../e2e/original/App/OpenApi/Entity/User.php | 9 ++- .../e2e/original/App/Schema/Entity/Brand.php | 10 +-- .../e2e/original/App/Schema/Entity/Person.php | 38 +++++---- .../App/Schema/Entity/PostalAddress.php | 35 ++------- .../e2e/original/App/Schema/Entity/Thing.php | 4 +- tests/e2e/schema.yml | 15 ++-- 29 files changed, 304 insertions(+), 221 deletions(-) diff --git a/composer.json b/composer.json index 8fadae1c..66e33803 100644 --- a/composer.json +++ b/composer.json @@ -44,14 +44,14 @@ "symfony/yaml": "^5.2 || ^6.0", "symfony/filesystem": "^5.2 || ^6.0", "twig/twig": "^3.0", - "nette/php-generator": "^3.6 || ^4.0-dev", + "nette/php-generator": "^3.6 || ^4.0", "nette/utils": "^3.1 || ^4.0-dev", "nikic/php-parser": "^4.13", "cebe/php-openapi": "^1.6", "symfony/string": "^5.2 || ^6.0" }, "require-dev": { - "api-platform/core": "^2.5", + "api-platform/core": "^v2.7.0-beta.1", "doctrine/orm": "^2.7", "myclabs/php-enum": "^1.7", "symfony/doctrine-bridge": "^5.2 || ^6.0", diff --git a/composer.lock b/composer.lock index 05b1aa0e..693456ce 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "22c506cdcd2c21e50081504cbe03e7bd", + "content-hash": "5fd1addf87a1b017576c7b5ad28e846a", "packages": [ { "name": "cebe/php-openapi", @@ -857,16 +857,16 @@ }, { "name": "nette/php-generator", - "version": "dev-master", + "version": "v4.0.1", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "a88a6c560b9d7e6f2f234444dd7f0e8feacfe300" + "reference": "23110ddbcdc7723f5ae06e94a535bbd01b72bfdc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/a88a6c560b9d7e6f2f234444dd7f0e8feacfe300", - "reference": "a88a6c560b9d7e6f2f234444dd7f0e8feacfe300", + "url": "https://api.github.com/repos/nette/php-generator/zipball/23110ddbcdc7723f5ae06e94a535bbd01b72bfdc", + "reference": "23110ddbcdc7723f5ae06e94a535bbd01b72bfdc", "shasum": "" }, "require": { @@ -882,7 +882,6 @@ "suggest": { "nikic/php-parser": "to use ClassType::from(withBodies: true) & ClassType::fromCode()" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { @@ -920,9 +919,9 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/master" + "source": "https://github.com/nette/php-generator/tree/v4.0.1" }, - "time": "2022-05-23T19:11:20+00:00" + "time": "2022-03-10T02:24:09+00:00" }, { "name": "nette/utils", @@ -2849,16 +2848,16 @@ "packages-dev": [ { "name": "api-platform/core", - "version": "v2.6.8", + "version": "v2.7.0-beta.1", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "ff3aab5b196709c721960c0bb4f1d52759af737d" + "reference": "4c16efe1f39c8aadd20e8e08b0b57a4d33034cd8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/ff3aab5b196709c721960c0bb4f1d52759af737d", - "reference": "ff3aab5b196709c721960c0bb4f1d52759af737d", + "url": "https://api.github.com/repos/api-platform/core/zipball/4c16efe1f39c8aadd20e8e08b0b57a4d33034cd8", + "reference": "4c16efe1f39c8aadd20e8e08b0b57a4d33034cd8", "shasum": "" }, "require": { @@ -2893,7 +2892,7 @@ "doctrine/mongodb-odm": "^2.2", "doctrine/mongodb-odm-bundle": "^4.0", "doctrine/orm": "^2.6.4", - "elasticsearch/elasticsearch": "^6.0 || ^7.0", + "elasticsearch/elasticsearch": "^7.11.0", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", "friends-of-behat/symfony-extension": "^2.1", @@ -2928,6 +2927,8 @@ "symfony/form": "^3.4 || ^4.4 || ^5.1 || ^6.0", "symfony/framework-bundle": "^4.4 || ^5.1 || ^6.0", "symfony/http-client": "^4.4 || ^5.1 || ^6.0", + "symfony/intl": "^4.4 || ^5.3 || ^6.0", + "symfony/maker-bundle": "^1.24", "symfony/mercure-bundle": "*", "symfony/messenger": "^4.4 || ^5.1 || ^6.0", "symfony/phpunit-bridge": "^5.4 || ^6.0", @@ -2944,7 +2945,6 @@ "suggest": { "doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.", "elasticsearch/elasticsearch": "To support Elasticsearch.", - "guzzlehttp/guzzle": "To use the HTTP cache invalidation system.", "ocramius/package-versions": "To display the API Platform's version in the debug bar.", "phpdocumentor/reflection-docblock": "To support extracting metadata from PHPDoc.", "psr/cache-implementation": "To use metadata caching.", @@ -2952,6 +2952,8 @@ "symfony/cache": "To have metadata caching when using Symfony integration.", "symfony/config": "To load XML configuration files.", "symfony/expression-language": "To use authorization features.", + "symfony/http-client": "To use the HTTP cache invalidation system.", + "symfony/messenger": "To support messenger integration.", "symfony/security": "To use authorization features.", "symfony/twig-bundle": "To use the Swagger UI integration.", "symfony/uid": "To support Symfony UUID/ULID identifiers.", @@ -2961,15 +2963,18 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.6.x-dev" + "dev-main": "2.7.x-dev" }, "symfony": { "require": "^3.4 || ^4.4 || ^5.1 || ^6.0" } }, "autoload": { + "files": [ + "src/deprecation.php" + ], "psr-4": { - "ApiPlatform\\Core\\": "src/" + "ApiPlatform\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -2998,7 +3003,7 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v2.6.8" + "source": "https://github.com/api-platform/core/tree/v2.7.0-beta.1" }, "funding": [ { @@ -3006,7 +3011,7 @@ "type": "tidelift" } ], - "time": "2022-01-11T10:29:54+00:00" + "time": "2022-05-31T14:59:40+00:00" }, { "name": "doctrine/cache", @@ -7171,8 +7176,8 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "nette/php-generator": 20, - "nette/utils": 20 + "nette/utils": 20, + "api-platform/core": 10 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/phpstan.neon b/phpstan.neon index f3e92614..dfab95cb 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -33,7 +33,7 @@ parameters: attributes: array, parent: false|string, guessFrom: string, - operations: array>, + operations: array>, allProperties: boolean, properties: array } @@ -44,6 +44,7 @@ parameters: vocabularyNamespace: string, relations: string[], debug: boolean, + apiPlatformOldAttributes: boolean, id: array{generate: boolean, generationStrategy: string, writable: boolean, onClass: string}, useInterface: boolean, checkIsGoodRelations: boolean, diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 96003152..91368a3c 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -13,12 +13,21 @@ namespace ApiPlatform\SchemaGenerator\AttributeGenerator; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Core\Annotation\ApiProperty as OldApiProperty; +use ApiPlatform\Core\Annotation\ApiResource as OldApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; +use Nette\PhpGenerator\Literal; use Symfony\Component\OptionsResolver\OptionsResolver; /** @@ -43,22 +52,43 @@ public function generateClassAttributes(Class_ $class): array if ($class->name() !== $localName = $class->shortName()) { $arguments['shortName'] = $localName; } + if ($class->rdfType()) { - $arguments['iri'] = $class->rdfType(); + if ($this->config['apiPlatformOldAttributes']) { + $arguments['iri'] = $class->rdfType(); + } else { + $arguments['types'] = [$class->rdfType()]; + } } if ($class->operations) { - $operations = $this->validateClassOperations($class->operations); - foreach ($operations as $operationTarget => $targetOperations) { - $targetArguments = []; - foreach ($targetOperations as $method => $methodConfig) { - $methodArguments = []; - foreach ($methodConfig ?? [] as $key => $value) { - $methodArguments[$key] = $value; + if ($this->config['apiPlatformOldAttributes']) { + $operations = $this->validateClassOperations($class->operations); + foreach ($operations as $operationTarget => $targetOperations) { + $targetArguments = []; + foreach ($targetOperations ?? [] as $method => $methodConfig) { + $methodArguments = []; + if (!is_iterable($methodConfig)) { + continue; + } + foreach ($methodConfig as $key => $value) { + $methodArguments[$key] = $value; + } + $targetArguments[$method] = $methodArguments; } - $targetArguments[$method] = $methodArguments; + $arguments[sprintf('%sOperations', $operationTarget)] = $targetArguments; + } + } else { + $arguments['operations'] = []; + foreach ($class->operations as $operationMetadataClass => $methodConfig) { + $arguments['operations'][] = new Literal(sprintf('new %s(%s)', + $operationMetadataClass, + implode(', ', array_map( + fn ($k, $v) => sprintf('%s: %s', $k, (\is_string($v) ? sprintf("'%s'", addslashes($v)) : (\is_scalar($v) ? $v : ''))), + array_keys($methodConfig ?? []), array_values($methodConfig ?? []) + )) + )); } - $arguments[sprintf('%sOperations', $operationTarget)] = $targetArguments; } } @@ -66,7 +96,7 @@ public function generateClassAttributes(Class_ $class): array } /** - * Verifies that the operations config is valid. + * Verifies that the operations' config is valid. * * @template T of array * @@ -92,7 +122,11 @@ public function generatePropertyAttributes(Property $property, string $className $arguments = []; if ($property->rdfType()) { - $arguments['iri'] = $property->rdfType(); + if ($this->config['apiPlatformOldAttributes']) { + $arguments['iri'] = $property->rdfType(); + } else { + $arguments['types'] = [$property->rdfType()]; + } } return $property->isCustom ? [] : [new Attribute('ApiProperty', $arguments)]; @@ -103,6 +137,19 @@ public function generatePropertyAttributes(Property $property, string $className */ public function generateUses(Class_ $class): array { - return [new Use_(ApiResource::class), new Use_(ApiProperty::class)]; + if ($this->config['apiPlatformOldAttributes']) { + return [new Use_(OldApiResource::class), new Use_(OldApiProperty::class)]; + } + + return [ + new Use_(ApiResource::class), + new Use_(ApiProperty::class), + new Use_(Get::class), + new Use_(Put::class), + new Use_(Patch::class), + new Use_(Delete::class), + new Use_(GetCollection::class), + new Use_(Post::class), + ]; } } diff --git a/src/FilesGenerator.php b/src/FilesGenerator.php index a201aa14..2f8a0e63 100644 --- a/src/FilesGenerator.php +++ b/src/FilesGenerator.php @@ -153,6 +153,7 @@ private function fixCs(array $files): void $fixers = (new FixerFactory()) ->registerBuiltInFixers() ->useRuleSet(new $rulesetClass([ // @phpstan-ignore-line + '@PhpCsFixer' => true, '@Symfony' => true, 'array_syntax' => ['syntax' => 'short'], 'phpdoc_order' => true, diff --git a/src/Model/Class_.php b/src/Model/Class_.php index acc79f52..fb5632c0 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -45,7 +45,7 @@ abstract class Class_ public bool $isAbstract = false; public bool $hasChild = false; public bool $isEmbeddable = false; - /** @var array> */ + /** @var array> */ public array $operations = []; /** diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 9365feb5..8ad8810a 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -123,18 +123,14 @@ public function generate(OpenApi $openApi, array $config): array $pathCollection = $openApi->paths->getPath(sprintf('/%s', $collectionResourceName)); $listOperation = $pathCollection->get ?? null; $createOperation = $pathCollection->post ?? null; - $class->operations = [ - 'item' => array_merge( - $showOperation ? ['get' => null] : [], - $putOperation ? ['put' => null] : [], - $patchOperation ? ['patch' => null] : [], - $deleteOperation ? ['delete' => null] : [], - ), - 'collection' => array_merge( - $listOperation ? ['get' => null] : [], - $createOperation ? ['post' => null] : [], - ), - ]; + $class->operations = array_merge( + $showOperation ? ['Get' => null] : [], + $putOperation ? ['Put' => null] : [], + $patchOperation ? ['Patch' => null] : [], + $deleteOperation ? ['Delete' => null] : [], + $listOperation ? ['GetCollection' => null] : [], + $createOperation ? ['Post' => null] : [], + ); $classes[$name] = $class; } diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 1510a8e1..4aa01f80 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -102,6 +102,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarPrototype()->end() ->end() ->booleanNode('debug')->defaultFalse()->info('Debug mode')->end() + ->booleanNode('apiPlatformOldAttributes')->defaultFalse()->info('Use old API Platform attributes (API Platform < 2.7)')->end() ->arrayNode('id') ->addDefaultsIfNotSet() ->info('IDs configuration') diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 63359433..3fb98e3d 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -459,6 +459,9 @@ private function defineTypesToGenerate(array $graphs, array $config): array } foreach ($config['types'] as $typeName => $typeConfig) { + if ($typeConfig['exclude']) { + continue; + } $vocabularyNamespace = $typeConfig['vocabularyNamespace'] ?? $config['vocabularyNamespace']; $resource = null; diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 1dbd5ccb..7bd2a990 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -13,8 +13,16 @@ namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Core\Annotation\ApiProperty as OldApiProperty; +use ApiPlatform\Core\Annotation\ApiResource as OldApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Use_; @@ -24,6 +32,7 @@ use ApiPlatform\SchemaGenerator\TypesGenerator; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use Nette\PhpGenerator\Literal; use PHPUnit\Framework\TestCase; use Symfony\Component\String\Inflector\EnglishInflector; @@ -32,14 +41,12 @@ */ class ApiPlatformCoreAttributeGeneratorTest extends TestCase { - private ApiPlatformCoreAttributeGenerator $generator; - - protected function setUp(): void + private function generator(bool $oldAttributes = false): ApiPlatformCoreAttributeGenerator { - $this->generator = new ApiPlatformCoreAttributeGenerator( + return new ApiPlatformCoreAttributeGenerator( new PhpTypeConverter(), new EnglishInflector(), - [], + ['apiPlatformOldAttributes' => $oldAttributes], [], ); } @@ -47,21 +54,29 @@ protected function setUp(): void /** * @dataProvider provideGenerateClassAttributesCases */ - public function testGenerateClassAttributes(SchemaClass $class, array $attributes): void + public function testGenerateClassAttributes(SchemaClass $class, array $attributes, bool $oldAttributes = false): void { - $this->assertEquals($attributes, $this->generator->generateClassAttributes($class)); + $this->assertEquals($attributes, $this->generator($oldAttributes)->generateClassAttributes($class)); } public function provideGenerateClassAttributesCases(): \Generator { - yield 'classical' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])]]; + yield 'classical' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['types' => ['https://schema.org/Res']])]]; + + yield 'classical (old)' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['iri' => 'https://schema.org/Res'])], true]; + + $class = new SchemaClass('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); + $class->operations = [ + 'Get' => ['routeName' => 'api_about_get'], + ]; + yield 'with operations' => [$class, [new Attribute('ApiResource', ['types' => ['https://schema.org/WithOperations'], 'operations' => [new Literal("new Get(routeName: 'api_about_get')")]])]]; $class = new SchemaClass('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); $class->operations = [ 'item' => ['get' => ['route_name' => 'api_about_get']], 'collection' => [], ]; - yield 'with operations' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []])]]; + yield 'with operations (old)' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []])], true]; $class = new SchemaClass('Abstract', new RdfResource('https://schema.org/Abstract')); $class->isAbstract = true; @@ -72,31 +87,49 @@ public function provideGenerateClassAttributesCases(): \Generator $class = new SchemaClass('Enum', $resource); yield 'enum' => [$class, []]; - yield 'with short name' => [(new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName'])]]; + yield 'with short name' => [(new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'types' => ['https://schema.org/DifferentLocalName']])]]; } /** * @dataProvider provideGeneratePropertyAttributesCases */ - public function testGeneratePropertyAttributes(Property $property, array $attributes): void + public function testGeneratePropertyAttributes(Property $property, array $attributes, bool $oldAttributes = false): void { - $this->assertEquals($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); + $this->assertEquals($attributes, $this->generator($oldAttributes)->generatePropertyAttributes($property, 'Res')); } public function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); $property->resource = new RdfResource('https://schema.org/prop'); - yield 'classical' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/prop'])]]; + yield 'classical' => [$property, [new Attribute('ApiProperty', ['types' => ['https://schema.org/prop']])]]; + + $property = new Property('prop'); + $property->resource = new RdfResource('https://schema.org/prop'); + yield 'classical (old)' => [$property, [new Attribute('ApiProperty', ['iri' => 'https://schema.org/prop'])], true]; } public function testGenerateCustomPropertyAttributes(): void { - $this->assertSame([], $this->generator->generatePropertyAttributes((new Property('customProp'))->markAsCustom(), 'Res')); + $this->assertSame([], $this->generator()->generatePropertyAttributes((new Property('customProp'))->markAsCustom(), 'Res')); } public function testGenerateUses(): void { - $this->assertEquals([new Use_(ApiResource::class), new Use_(ApiProperty::class)], $this->generator->generateUses(new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); + $this->assertEquals([ + new Use_(OldApiResource::class), + new Use_(OldApiProperty::class), + ], $this->generator(true)->generateUses(new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); + + $this->assertEquals([ + new Use_(ApiResource::class), + new Use_(ApiProperty::class), + new Use_(Get::class), + new Use_(Put::class), + new Use_(Patch::class), + new Use_(Delete::class), + new Use_(GetCollection::class), + new Use_(Post::class), + ], $this->generator()->generateUses(new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())))); } } diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index f7210c96..9c3a27c6 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -61,6 +61,9 @@ public function testDumpConfiguration(): void # Debug mode debug: false + # Use old API Platform attributes (API Platform < 2.7) + apiPlatformOldAttributes: false + # IDs configuration id: diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 8cfe23b1..b84280ed 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -87,8 +87,8 @@ public function testCustomAttributes(): void // Attributes given as ordered map (omap). $this->assertStringContainsString(<<<'PHP' -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; use App\Attributes\MyAttribute; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -100,7 +100,7 @@ public function testCustomAttributes(): void * @see https://schema.org/Book */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Book', routePrefix: '/library')] +#[ApiResource(types: ['https://schema.org/Book'], routePrefix: '/library')] #[MyAttribute] class Book { @@ -459,7 +459,7 @@ public function testSupersededProperties(): void * @see https://schema.org/award */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/award')] + #[ApiProperty(types: ['https://schema.org/award'])] private ?string $award = null; PHP , $creativeWork); @@ -486,7 +486,7 @@ public function testActivityStreams(): void * @see http://www.w3.org/ns/activitystreams#content */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'http://www.w3.org/ns/activitystreams#content')] + #[ApiProperty(types: ['http://www.w3.org/ns/activitystreams#content'])] private ?string $content = null; PHP , $object); @@ -499,7 +499,7 @@ public function testActivityStreams(): void * * @see http://www.w3.org/ns/activitystreams#Page */ -#[ApiResource(iri: 'http://www.w3.org/ns/activitystreams#Page', routePrefix: 'as')] +#[ApiResource(types: ['http://www.w3.org/ns/activitystreams#Page'], routePrefix: 'as')] #[ORM\Entity] class Page extends Object_ PHP diff --git a/tests/config/activity-streams.yaml b/tests/config/activity-streams.yaml index fec56a5a..b1579aeb 100644 --- a/tests/config/activity-streams.yaml +++ b/tests/config/activity-streams.yaml @@ -3,6 +3,8 @@ vocabularies: vocabularyNamespace: http://www.w3.org/ns/activitystreams# allTypes: true types: + Delete: + exclude: true Place: allProperties: true properties: diff --git a/tests/e2e/customized/App/Schema/Entity/Brand.php b/tests/e2e/customized/App/Schema/Entity/Brand.php index 02d9ee4f..ee7d16fd 100644 --- a/tests/e2e/customized/App/Schema/Entity/Brand.php +++ b/tests/e2e/customized/App/Schema/Entity/Brand.php @@ -4,8 +4,8 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; use Doctrine\ORM\Mapping as ORM; /** @@ -14,7 +14,7 @@ * @see https://schema.org/Brand */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Brand')] +#[ApiResource(types: ['https://schema.org/Brand'])] class Brand { #[ORM\Id] @@ -28,7 +28,7 @@ class Brand * @see https://schema.org/name */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/name')] + #[ApiProperty(types: ['https://schema.org/name'])] private ?string $name = null; /** @@ -37,7 +37,7 @@ class Brand * @see https://schema.org/slogan */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/slogan')] + #[ApiProperty(types: ['https://schema.org/slogan'])] private ?string $slogan = null; public function getId(): ?int diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 4d4eb1de..5e4ef86c 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -4,8 +4,11 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; use App\Attribute\MyCustomAttribute; use App\Model\MyCustomClass; use App\Model\MyCustomInterface; @@ -24,9 +27,12 @@ */ #[ORM\Entity] #[ApiResource( - iri: 'https://schema.org/Person', - itemOperations: ['get' => ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], - collectionOperations: ['get' => ['route_name' => 'get_person_collection']], + types: ['https://schema.org/Person'], + operations: [ + new Get(), + new GetCollection(routeName: 'get_person_collection'), + new Delete(security: 'is_granted(\'ROLE_ADMIN\')'), + ], security: 'is_granted(\'ROLE_USER\')', )] #[UniqueEntity('email')] @@ -49,7 +55,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/familyName */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/familyName')] + #[ApiProperty(types: ['https://schema.org/familyName'])] private ?string $familyName = null; /** @@ -58,7 +64,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/givenName */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/givenName')] + #[ApiProperty(types: ['https://schema.org/givenName'])] private ?string $givenName = null; /** @@ -67,7 +73,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/additionalName */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/additionalName')] + #[ApiProperty(types: ['https://schema.org/additionalName'])] #[Groups(['extra'])] private ?string $additionalName = null; @@ -77,7 +83,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/gender */ #[ORM\Column(nullable: true)] - #[ApiProperty(iri: 'https://schema.org/gender')] + #[ApiProperty(types: ['https://schema.org/gender'])] #[Assert\Choice(callback: [GenderType::class, 'toArray'])] private ?string $gender = null; @@ -87,7 +93,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/address */ #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] - #[ApiProperty(iri: 'https://schema.org/address')] + #[ApiProperty(types: ['https://schema.org/address'])] private ?PostalAddress $address = null; /** @@ -96,7 +102,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/birthDate */ #[ORM\Column(type: 'date', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/birthDate')] + #[ApiProperty(types: ['https://schema.org/birthDate'])] #[Assert\Type(\DateTimeInterface::class)] private ?\DateTimeInterface $birthDate = null; @@ -106,7 +112,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/telephone */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/telephone')] + #[ApiProperty(types: ['https://schema.org/telephone'])] private ?string $telephone = null; /** @@ -115,7 +121,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/email */ #[ORM\Column(type: 'text', nullable: true, unique: true)] - #[ApiProperty(iri: 'https://schema.org/email', security: 'is_granted(\'ROLE_ADMIN\')')] + #[ApiProperty(types: ['https://schema.org/email'], security: 'is_granted(\'ROLE_ADMIN\')')] #[Assert\Email] private ?string $email = null; @@ -125,7 +131,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/url */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/url')] + #[ApiProperty(types: ['https://schema.org/url'])] #[Assert\Url] private ?string $url = null; @@ -136,7 +142,7 @@ class Person extends MyCustomClass implements MyCustomInterface */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\InverseJoinColumn(unique: true)] - #[ApiProperty(iri: 'https://schema.org/siblings')] + #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; /** @@ -144,7 +150,7 @@ class Person extends MyCustomClass implements MyCustomInterface * * @see https://schema.org/knowsAbout */ - #[ApiProperty(iri: 'https://schema.org/knowsAbout')] + #[ApiProperty(types: ['https://schema.org/knowsAbout'])] private ?Thing $knowsAbout = null; /** @see _:customColumn */ diff --git a/tests/e2e/customized/App/Schema/Entity/PostalAddress.php b/tests/e2e/customized/App/Schema/Entity/PostalAddress.php index d28b672d..5e1437ac 100644 --- a/tests/e2e/customized/App/Schema/Entity/PostalAddress.php +++ b/tests/e2e/customized/App/Schema/Entity/PostalAddress.php @@ -4,8 +4,8 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; use Doctrine\ORM\Mapping as ORM; /** @@ -14,7 +14,7 @@ * @see https://schema.org/PostalAddress */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/PostalAddress')] +#[ApiResource(types: ['https://schema.org/PostalAddress'])] class PostalAddress { #[ORM\Id] @@ -28,7 +28,7 @@ class PostalAddress * @see https://schema.org/addressCountry */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/addressCountry')] + #[ApiProperty(types: ['https://schema.org/addressCountry'])] private ?string $addressCountry = null; /** @@ -37,7 +37,7 @@ class PostalAddress * @see https://schema.org/addressLocality */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/addressLocality')] + #[ApiProperty(types: ['https://schema.org/addressLocality'])] private ?string $addressLocality = null; /** @@ -46,25 +46,16 @@ class PostalAddress * @see https://schema.org/addressRegion */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/addressRegion')] + #[ApiProperty(types: ['https://schema.org/addressRegion'])] private ?string $addressRegion = null; - /** - * The post office box number for PO box addresses. - * - * @see https://schema.org/postOfficeBoxNumber - */ - #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/postOfficeBoxNumber')] - private ?string $postOfficeBoxNumber = null; - /** * The postal code. For example, 94043. * * @see https://schema.org/postalCode */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/postalCode')] + #[ApiProperty(types: ['https://schema.org/postalCode'])] private ?string $postalCode = null; /** @@ -73,7 +64,7 @@ class PostalAddress * @see https://schema.org/streetAddress */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/streetAddress')] + #[ApiProperty(types: ['https://schema.org/streetAddress'])] private ?string $streetAddress = null; public function getId(): ?int @@ -111,16 +102,6 @@ public function getAddressRegion(): ?string return $this->addressRegion; } - public function setPostOfficeBoxNumber(?string $postOfficeBoxNumber): void - { - $this->postOfficeBoxNumber = $postOfficeBoxNumber; - } - - public function getPostOfficeBoxNumber(): ?string - { - return $this->postOfficeBoxNumber; - } - public function setPostalCode(?string $postalCode): void { $this->postalCode = $postalCode; diff --git a/tests/e2e/customized/App/Schema/Entity/Thing.php b/tests/e2e/customized/App/Schema/Entity/Thing.php index 8c1926a7..d273b9f3 100644 --- a/tests/e2e/customized/App/Schema/Entity/Thing.php +++ b/tests/e2e/customized/App/Schema/Entity/Thing.php @@ -4,7 +4,7 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; +use ApiPlatform\Metadata\ApiProperty; use Doctrine\ORM\Mapping as ORM; /** @@ -21,7 +21,7 @@ abstract class Thing * @see https://schema.org/name */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/name')] + #[ApiProperty(types: ['https://schema.org/name'])] private ?string $name = null; public function setName(?string $name): void diff --git a/tests/e2e/original/App/OpenApi/Entity/Book.php b/tests/e2e/original/App/OpenApi/Entity/Book.php index c420a783..06786d7e 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Book.php +++ b/tests/e2e/original/App/OpenApi/Entity/Book.php @@ -4,8 +4,14 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; @@ -16,9 +22,8 @@ */ #[ORM\Entity] #[ApiResource( - iri: 'https://schema.org/Book', - itemOperations: ['get' => [], 'put' => [], 'patch' => [], 'delete' => []], - collectionOperations: ['get' => [], 'post' => []], + types: ['https://schema.org/Book'], + operations: [new Get(), new Put(), new Patch(), new Delete(), new GetCollection(), new Post()], )] class Book { @@ -33,7 +38,7 @@ class Book * @see https://schema.org/isbn */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/isbn')] + #[ApiProperty(types: ['https://schema.org/isbn'])] private ?string $isbn = null; /** @@ -42,7 +47,7 @@ class Book * @see https://schema.org/name */ #[ORM\Column(type: 'text')] - #[ApiProperty(iri: 'https://schema.org/name')] + #[ApiProperty(types: ['https://schema.org/name'])] #[Assert\NotNull] private string $title; @@ -52,7 +57,7 @@ class Book * @see https://schema.org/description */ #[ORM\Column(type: 'text')] - #[ApiProperty(iri: 'https://schema.org/description')] + #[ApiProperty(types: ['https://schema.org/description'])] #[Assert\NotNull] private string $description; @@ -62,7 +67,7 @@ class Book * @see https://schema.org/author */ #[ORM\Column(type: 'text')] - #[ApiProperty(iri: 'https://schema.org/author')] + #[ApiProperty(types: ['https://schema.org/author'])] #[Assert\NotNull] private string $author; @@ -72,7 +77,7 @@ class Book * @see https://schema.org/dateCreated */ #[ORM\Column(type: 'date')] - #[ApiProperty(iri: 'https://schema.org/dateCreated')] + #[ApiProperty(types: ['https://schema.org/dateCreated'])] #[Assert\Type(\DateTimeInterface::class)] #[Assert\NotNull] private \DateTimeInterface $publicationDate; @@ -84,7 +89,7 @@ class Book */ #[ORM\OneToMany(targetEntity: 'App\OpenApi\Entity\Review', mappedBy: 'book')] #[ORM\InverseJoinColumn(nullable: false, unique: true)] - #[ApiProperty(iri: 'https://schema.org/reviews')] + #[ApiProperty(types: ['https://schema.org/reviews'])] #[Assert\NotNull] private Collection $reviews; diff --git a/tests/e2e/original/App/OpenApi/Entity/Order.php b/tests/e2e/original/App/OpenApi/Entity/Order.php index eec2f20a..52d7523d 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Order.php +++ b/tests/e2e/original/App/OpenApi/Entity/Order.php @@ -4,14 +4,16 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; use App\OpenApi\Enum\OrderStatus; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] -#[ApiResource(itemOperations: ['get' => [], 'delete' => []], collectionOperations: [])] +#[ApiResource(operations: [new Get(), new Delete()])] class Order { #[ORM\Id] diff --git a/tests/e2e/original/App/OpenApi/Entity/Parchment.php b/tests/e2e/original/App/OpenApi/Entity/Parchment.php index 8bb5059c..50a41110 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Parchment.php +++ b/tests/e2e/original/App/OpenApi/Entity/Parchment.php @@ -4,16 +4,19 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] -#[ApiResource( - itemOperations: ['get' => [], 'put' => [], 'patch' => [], 'delete' => []], - collectionOperations: ['get' => [], 'post' => []], -)] +#[ApiResource(operations: [new Get(), new Put(), new Patch(), new Delete(), new GetCollection(), new Post()])] class Parchment { #[ORM\Id] diff --git a/tests/e2e/original/App/OpenApi/Entity/Pet.php b/tests/e2e/original/App/OpenApi/Entity/Pet.php index 15a96916..705897cc 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Pet.php +++ b/tests/e2e/original/App/OpenApi/Entity/Pet.php @@ -4,14 +4,16 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; use App\OpenApi\Enum\PetStatus; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] -#[ApiResource(itemOperations: ['get' => [], 'delete' => []], collectionOperations: [])] +#[ApiResource(operations: [new Get(), new Delete()])] class Pet { #[ORM\Id] diff --git a/tests/e2e/original/App/OpenApi/Entity/Review.php b/tests/e2e/original/App/OpenApi/Entity/Review.php index e489d92a..34e2fdb1 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Review.php +++ b/tests/e2e/original/App/OpenApi/Entity/Review.php @@ -4,8 +4,14 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; +use ApiPlatform\Metadata\Patch; +use ApiPlatform\Metadata\Post; +use ApiPlatform\Metadata\Put; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; @@ -16,9 +22,8 @@ */ #[ORM\Entity] #[ApiResource( - iri: 'http://schema.org/Review', - itemOperations: ['get' => [], 'put' => [], 'patch' => [], 'delete' => []], - collectionOperations: ['get' => [], 'post' => []], + types: ['http://schema.org/Review'], + operations: [new Get(), new Put(), new Patch(), new Delete(), new GetCollection(), new Post()], )] class Review { @@ -33,7 +38,7 @@ class Review * @see http://schema.org/reviewBody */ #[ORM\Column(type: 'text')] - #[ApiProperty(iri: 'http://schema.org/reviewBody')] + #[ApiProperty(types: ['http://schema.org/reviewBody'])] #[Assert\NotNull] private string $body; @@ -57,7 +62,7 @@ class Review */ #[ORM\OneToOne(targetEntity: 'App\OpenApi\Entity\Book')] #[ORM\JoinColumn(nullable: false)] - #[ApiProperty(iri: 'https://schema.org/Book')] + #[ApiProperty(types: ['https://schema.org/Book'])] #[Assert\NotNull] private Book $book; @@ -67,7 +72,7 @@ class Review * @see http://schema.org/author */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'http://schema.org/author')] + #[ApiProperty(types: ['http://schema.org/author'])] private ?string $author = null; /** diff --git a/tests/e2e/original/App/OpenApi/Entity/TopBook.php b/tests/e2e/original/App/OpenApi/Entity/TopBook.php index 644f88c2..a551030f 100644 --- a/tests/e2e/original/App/OpenApi/Entity/TopBook.php +++ b/tests/e2e/original/App/OpenApi/Entity/TopBook.php @@ -4,8 +4,10 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; @@ -13,7 +15,7 @@ * This entity represents a "most borrowed book" in a given a given French library. */ #[ORM\Entity] -#[ApiResource(itemOperations: ['get' => []], collectionOperations: ['get' => []])] +#[ApiResource(operations: [new Get(), new GetCollection()])] class TopBook { #[ORM\Id] diff --git a/tests/e2e/original/App/OpenApi/Entity/User.php b/tests/e2e/original/App/OpenApi/Entity/User.php index bad095dd..8b97ef65 100644 --- a/tests/e2e/original/App/OpenApi/Entity/User.php +++ b/tests/e2e/original/App/OpenApi/Entity/User.php @@ -4,13 +4,16 @@ namespace App\OpenApi\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\Put; use Doctrine\ORM\Mapping as ORM; use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] -#[ApiResource(itemOperations: ['get' => [], 'put' => [], 'delete' => []], collectionOperations: [])] +#[ApiResource(operations: [new Get(), new Put(), new Delete()])] class User { #[ORM\Id] diff --git a/tests/e2e/original/App/Schema/Entity/Brand.php b/tests/e2e/original/App/Schema/Entity/Brand.php index 02d9ee4f..ee7d16fd 100644 --- a/tests/e2e/original/App/Schema/Entity/Brand.php +++ b/tests/e2e/original/App/Schema/Entity/Brand.php @@ -4,8 +4,8 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; use Doctrine\ORM\Mapping as ORM; /** @@ -14,7 +14,7 @@ * @see https://schema.org/Brand */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/Brand')] +#[ApiResource(types: ['https://schema.org/Brand'])] class Brand { #[ORM\Id] @@ -28,7 +28,7 @@ class Brand * @see https://schema.org/name */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/name')] + #[ApiProperty(types: ['https://schema.org/name'])] private ?string $name = null; /** @@ -37,7 +37,7 @@ class Brand * @see https://schema.org/slogan */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/slogan')] + #[ApiProperty(types: ['https://schema.org/slogan'])] private ?string $slogan = null; public function getId(): ?int diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 459ba111..7985f9d6 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -4,8 +4,11 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; +use ApiPlatform\Metadata\Delete; +use ApiPlatform\Metadata\Get; +use ApiPlatform\Metadata\GetCollection; use App\Schema\Enum\GenderType; use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; @@ -21,9 +24,12 @@ */ #[ORM\Entity] #[ApiResource( - iri: 'https://schema.org/Person', - itemOperations: ['get' => ['method' => 'GET'], 'delete' => ['method' => 'DELETE', 'security' => 'is_granted(\'ROLE_ADMIN\')']], - collectionOperations: ['get' => ['route_name' => 'get_person_collection']], + types: ['https://schema.org/Person'], + operations: [ + new Get(), + new GetCollection(routeName: 'get_person_collection'), + new Delete(security: 'is_granted(\'ROLE_ADMIN\')'), + ], security: 'is_granted(\'ROLE_USER\')', )] #[UniqueEntity('email')] @@ -40,7 +46,7 @@ class Person extends Thing * @see https://schema.org/familyName */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/familyName')] + #[ApiProperty(types: ['https://schema.org/familyName'])] private ?string $familyName = null; /** @@ -49,7 +55,7 @@ class Person extends Thing * @see https://schema.org/givenName */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/givenName')] + #[ApiProperty(types: ['https://schema.org/givenName'])] private ?string $givenName = null; /** @@ -58,7 +64,7 @@ class Person extends Thing * @see https://schema.org/additionalName */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/additionalName')] + #[ApiProperty(types: ['https://schema.org/additionalName'])] #[Groups(['extra'])] private ?string $additionalName = null; @@ -68,7 +74,7 @@ class Person extends Thing * @see https://schema.org/gender */ #[ORM\Column(nullable: true)] - #[ApiProperty(iri: 'https://schema.org/gender')] + #[ApiProperty(types: ['https://schema.org/gender'])] #[Assert\Choice(callback: [GenderType::class, 'toArray'])] private ?string $gender = null; @@ -78,7 +84,7 @@ class Person extends Thing * @see https://schema.org/address */ #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] - #[ApiProperty(iri: 'https://schema.org/address')] + #[ApiProperty(types: ['https://schema.org/address'])] private ?PostalAddress $address = null; /** @@ -87,7 +93,7 @@ class Person extends Thing * @see https://schema.org/birthDate */ #[ORM\Column(type: 'date', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/birthDate')] + #[ApiProperty(types: ['https://schema.org/birthDate'])] #[Assert\Type(\DateTimeInterface::class)] private ?\DateTimeInterface $birthDate = null; @@ -97,7 +103,7 @@ class Person extends Thing * @see https://schema.org/telephone */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/telephone')] + #[ApiProperty(types: ['https://schema.org/telephone'])] private ?string $telephone = null; /** @@ -106,7 +112,7 @@ class Person extends Thing * @see https://schema.org/email */ #[ORM\Column(type: 'text', nullable: true, unique: true)] - #[ApiProperty(iri: 'https://schema.org/email', security: 'is_granted(\'ROLE_ADMIN\')')] + #[ApiProperty(types: ['https://schema.org/email'], security: 'is_granted(\'ROLE_ADMIN\')')] #[Assert\Email] private ?string $email = null; @@ -116,7 +122,7 @@ class Person extends Thing * @see https://schema.org/url */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/url')] + #[ApiProperty(types: ['https://schema.org/url'])] #[Assert\Url] private ?string $url = null; @@ -127,7 +133,7 @@ class Person extends Thing */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\InverseJoinColumn(unique: true)] - #[ApiProperty(iri: 'https://schema.org/siblings')] + #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; /** @@ -135,7 +141,7 @@ class Person extends Thing * * @see https://schema.org/knowsAbout */ - #[ApiProperty(iri: 'https://schema.org/knowsAbout')] + #[ApiProperty(types: ['https://schema.org/knowsAbout'])] private ?Thing $knowsAbout = null; /** diff --git a/tests/e2e/original/App/Schema/Entity/PostalAddress.php b/tests/e2e/original/App/Schema/Entity/PostalAddress.php index d28b672d..5e1437ac 100644 --- a/tests/e2e/original/App/Schema/Entity/PostalAddress.php +++ b/tests/e2e/original/App/Schema/Entity/PostalAddress.php @@ -4,8 +4,8 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; -use ApiPlatform\Core\Annotation\ApiResource; +use ApiPlatform\Metadata\ApiProperty; +use ApiPlatform\Metadata\ApiResource; use Doctrine\ORM\Mapping as ORM; /** @@ -14,7 +14,7 @@ * @see https://schema.org/PostalAddress */ #[ORM\Entity] -#[ApiResource(iri: 'https://schema.org/PostalAddress')] +#[ApiResource(types: ['https://schema.org/PostalAddress'])] class PostalAddress { #[ORM\Id] @@ -28,7 +28,7 @@ class PostalAddress * @see https://schema.org/addressCountry */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/addressCountry')] + #[ApiProperty(types: ['https://schema.org/addressCountry'])] private ?string $addressCountry = null; /** @@ -37,7 +37,7 @@ class PostalAddress * @see https://schema.org/addressLocality */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/addressLocality')] + #[ApiProperty(types: ['https://schema.org/addressLocality'])] private ?string $addressLocality = null; /** @@ -46,25 +46,16 @@ class PostalAddress * @see https://schema.org/addressRegion */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/addressRegion')] + #[ApiProperty(types: ['https://schema.org/addressRegion'])] private ?string $addressRegion = null; - /** - * The post office box number for PO box addresses. - * - * @see https://schema.org/postOfficeBoxNumber - */ - #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/postOfficeBoxNumber')] - private ?string $postOfficeBoxNumber = null; - /** * The postal code. For example, 94043. * * @see https://schema.org/postalCode */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/postalCode')] + #[ApiProperty(types: ['https://schema.org/postalCode'])] private ?string $postalCode = null; /** @@ -73,7 +64,7 @@ class PostalAddress * @see https://schema.org/streetAddress */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/streetAddress')] + #[ApiProperty(types: ['https://schema.org/streetAddress'])] private ?string $streetAddress = null; public function getId(): ?int @@ -111,16 +102,6 @@ public function getAddressRegion(): ?string return $this->addressRegion; } - public function setPostOfficeBoxNumber(?string $postOfficeBoxNumber): void - { - $this->postOfficeBoxNumber = $postOfficeBoxNumber; - } - - public function getPostOfficeBoxNumber(): ?string - { - return $this->postOfficeBoxNumber; - } - public function setPostalCode(?string $postalCode): void { $this->postalCode = $postalCode; diff --git a/tests/e2e/original/App/Schema/Entity/Thing.php b/tests/e2e/original/App/Schema/Entity/Thing.php index 8c1926a7..d273b9f3 100644 --- a/tests/e2e/original/App/Schema/Entity/Thing.php +++ b/tests/e2e/original/App/Schema/Entity/Thing.php @@ -4,7 +4,7 @@ namespace App\Schema\Entity; -use ApiPlatform\Core\Annotation\ApiProperty; +use ApiPlatform\Metadata\ApiProperty; use Doctrine\ORM\Mapping as ORM; /** @@ -21,7 +21,7 @@ abstract class Thing * @see https://schema.org/name */ #[ORM\Column(type: 'text', nullable: true)] - #[ApiProperty(iri: 'https://schema.org/name')] + #[ApiProperty(types: ['https://schema.org/name'])] private ?string $name = null; public function setName(?string $name): void diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index b72a5527..693e329e 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -14,15 +14,11 @@ types: Person: parent: ~ operations: - item: - get: - method: GET - delete: - method: DELETE - security: "is_granted('ROLE_ADMIN')" - collection: - get: - route_name: get_person_collection + Get: ~ + GetCollection: + routeName: get_person_collection + Delete: + security: "is_granted('ROLE_ADMIN')" attributes: ORM\Entity: ~ ApiResource: @@ -49,7 +45,6 @@ types: addressCountry: { range: https://schema.org/Text } addressLocality: ~ addressRegion: ~ - postOfficeBoxNumber: ~ postalCode: ~ streetAddress: ~ GenderType: From 9df0777e48bd28c68c36753ab87def8a3a55665a Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 21 Jun 2022 13:32:17 +0200 Subject: [PATCH 216/258] test: add a test for exclude (#379) --- tests/Command/GenerateCommandTest.php | 3 +++ tests/config/activity-streams.yaml | 2 ++ 2 files changed, 5 insertions(+) diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index b84280ed..51df6f13 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -504,6 +504,9 @@ public function testActivityStreams(): void class Page extends Object_ PHP , $page); + + self::assertFalse($this->fs->exists("$outputDir/App/Entity/Delete.php")); + self::assertFalse($this->fs->exists("$outputDir/App/Entity/Travel.php")); } public function testGenerationWithoutConfigFileQuestion(): void diff --git a/tests/config/activity-streams.yaml b/tests/config/activity-streams.yaml index b1579aeb..4b0b5d1d 100644 --- a/tests/config/activity-streams.yaml +++ b/tests/config/activity-streams.yaml @@ -9,3 +9,5 @@ types: allProperties: true properties: units: { range: 'http://www.w3.org/2001/XMLSchema#string' } + Travel: + exclude: true From b8ff914d057bf46416497510cabd5093fe81faf3 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Mon, 27 Jun 2022 16:05:23 +0200 Subject: [PATCH 217/258] fix: use choice instead of confirmation question (#380) --- src/FilesGenerator.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/FilesGenerator.php b/src/FilesGenerator.php index 2f8a0e63..58201119 100644 --- a/src/FilesGenerator.php +++ b/src/FilesGenerator.php @@ -25,7 +25,7 @@ use PhpCsFixer\RuleSet\RuleSet; use PhpCsFixer\Runner\Runner; use Psr\Log\LoggerAwareTrait; -use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Console\Style\SymfonyStyle; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\String\Inflector\InflectorInterface; @@ -69,8 +69,8 @@ public function generate(array $classes, array $config): void $file = null; if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) { - $confirmation = $this->io->askQuestion(new ConfirmationQuestion(sprintf('File "%s" already exists, use it (if no it will be overwritten)?', $path))); - if ($confirmation) { + $choice = $this->io->askQuestion(new ChoiceQuestion(sprintf('File "%s" already exists, keep your changes and update it (use) or overwrite it (overwrite)?', $path), ['use', 'overwrite'], 0)); + if ('use' === $choice) { $file = PhpFile::fromCode($fileContent); $this->logger ? $this->logger->info(sprintf('Using "%s" as base file.', $path)) : null; } From 181fac2942f7e600308d7e73074d900e51542ce4 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 30 Jun 2022 11:45:56 +0200 Subject: [PATCH 218/258] fix: introduce ConfigurationAttributeGenerator (#381) --- .../ConfigurationAttributeGenerator.php | 72 ++++++++++ src/Model/AddAttributeTrait.php | 6 +- src/Model/Attribute.php | 6 + src/OpenApi/ClassGenerator.php | 4 - .../PropertyGenerator/PropertyGenerator.php | 5 - src/SchemaGeneratorConfiguration.php | 3 + src/TypesGenerator.php | 9 -- .../ConfigurationAttributeGeneratorTest.php | 129 ++++++++++++++++++ tests/Command/DumpConfigurationTest.php | 1 + tests/Command/GenerateCommandTest.php | 2 +- 10 files changed, 216 insertions(+), 21 deletions(-) create mode 100644 src/AttributeGenerator/ConfigurationAttributeGenerator.php create mode 100644 tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php diff --git a/src/AttributeGenerator/ConfigurationAttributeGenerator.php b/src/AttributeGenerator/ConfigurationAttributeGenerator.php new file mode 100644 index 00000000..bf13ee45 --- /dev/null +++ b/src/AttributeGenerator/ConfigurationAttributeGenerator.php @@ -0,0 +1,72 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Use_; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; + +final class ConfigurationAttributeGenerator extends AbstractAttributeGenerator +{ + /** + * {@inheritdoc} + */ + public function generateClassAttributes(Class_ $class): array + { + $typeConfig = $this->config['types'][$class->name()] ?? null; + $vocabConfig = null; + if ($class instanceof SchemaClass) { + $vocabConfig = $this->config['vocabularies'][$class->resource()->getGraph()->getUri()] ?? null; + } + + $attributes = []; + $configAttributes = array_merge($vocabConfig['attributes'] ?? [], $typeConfig['attributes'] ?? []); + foreach ($configAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, ($attributeArgs ?? []) + ['alwaysGenerate' => !isset($vocabConfig['attributes'][$attributeName]) || isset($typeConfig['attributes'][$attributeName])]); + } + + return $attributes; + } + + /** + * {@inheritdoc} + */ + public function generatePropertyAttributes(Property $property, string $className): array + { + $typeConfig = $this->config['types'][$className] ?? null; + $propertyConfig = $typeConfig['properties'][$property->name()] ?? null; + + $attributes = []; + foreach ($propertyConfig['attributes'] ?? [] as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs ?? []); + } + + return $attributes; + } + + /** + * {@inheritdoc} + */ + public function generateUses(Class_ $class): array + { + $uses = []; + foreach ($this->config['uses'] as $useName => $useArgs) { + $uses[] = new Use_($useName, $useArgs['alias'] ?? null); + } + + return $uses; + } +} diff --git a/src/Model/AddAttributeTrait.php b/src/Model/AddAttributeTrait.php index df93e9b9..76c0a390 100644 --- a/src/Model/AddAttributeTrait.php +++ b/src/Model/AddAttributeTrait.php @@ -22,11 +22,13 @@ public function addAttribute(Attribute $attribute): self $this->attributes, fn (Attribute $attr) => $attr->name() === $attribute->name() ))) { - $this->attributes[] = $attribute; + if ($attribute->append) { + $this->attributes[] = $attribute; + } } else { $this->attributes = array_map( fn (Attribute $attr) => $attr->name() === $attribute->name() - ? new Attribute($attr->name(), array_merge($attribute->args(), $attr->args())) + ? new Attribute($attr->name(), array_merge($attr->args(), $attribute->args())) : $attr, $this->attributes ); diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php index b68b5e3b..38c4bef3 100644 --- a/src/Model/Attribute.php +++ b/src/Model/Attribute.php @@ -25,12 +25,18 @@ final class Attribute /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] */ private array $args; + public bool $append = true; + /** * @param (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] $args */ public function __construct(string $name, array $args = []) { $this->name = $name; + + $this->append = (bool) ($args['alwaysGenerate'] ?? true); + unset($args['alwaysGenerate']); + $this->args = $args; } diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 8ad8810a..2c026763 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -220,10 +220,6 @@ private function buildClassFromSchema(Schema $schema, string $name, array $confi $class->setRdfType($schema->externalDocs->url); } - foreach ($config['uses'] as $useName => $useArgs) { - $class->addUse(new Use_($useName, $useArgs['alias'] ?? null)); - } - foreach ($schema->properties as $propertyName => $schemaProperty) { \assert($schemaProperty instanceof Schema); $property = ($this->propertyGenerator)($propertyName, $config, $class, ['schema' => $schema, 'property' => $schemaProperty]); diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index f0b2f8bd..3d20a98a 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -15,7 +15,6 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\GoodRelationsBridge; -use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; @@ -165,10 +164,6 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; $schemaProperty->groups = $propertyConfig['groups'] ?? []; - foreach ($propertyConfig['attributes'] ?? [] as $attributeName => $attributeArgs) { - $schemaProperty->addAttribute(new Attribute($attributeName, $attributeArgs ?? [])); - } - return $schemaProperty; } diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 4aa01f80..4c06182e 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -15,6 +15,7 @@ use ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\ConfigurationAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; @@ -263,6 +264,8 @@ public function getConfigTreeBuilder(): TreeBuilder ApiPlatformCoreAttributeGenerator::class, ConstraintAttributeGenerator::class, SerializerGroupsAttributeGenerator::class, + // Configuration attribute generator needs to be last to merge its attributes with previously generated ones. + ConfigurationAttributeGenerator::class, ]) ->scalarPrototype()->end() ->end() diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 3fb98e3d..4a9b2850 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -20,7 +20,6 @@ use ApiPlatform\SchemaGenerator\ClassMutator\ClassParentMutator; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesAppender; use ApiPlatform\SchemaGenerator\ClassMutator\ClassPropertiesTypehintMutator; -use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; @@ -246,17 +245,9 @@ private function buildClass(array $graphs, array $cardinalities, string $typeNam } $typeConfig = $config['types'][$typeName] ?? null; - $vocabConfig = $config['vocabularies'][$type->getGraph()->getUri()] ?? null; $parent = $typeConfig['parent'] ?? null; $class = new SchemaClass($typeName, $type, $parent); $class->operations = $typeConfig['operations'] ?? []; - $attributes = array_merge($vocabConfig['attributes'] ?? [], $typeConfig['attributes'] ?? []); - foreach ($attributes as $attributeName => $attributeArgs) { - $class->addAttribute(new Attribute($attributeName, $attributeArgs ?? [])); - } - foreach ($config['uses'] as $useName => $useArgs) { - $class->addUse(new Use_($useName, $useArgs['alias'] ?? null)); - } if ($class->isEnum()) { (new SchemaEnumClassMutator( diff --git a/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php b/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php new file mode 100644 index 00000000..669d508f --- /dev/null +++ b/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php @@ -0,0 +1,129 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\ConfigurationAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\Model\Use_; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\TestCase; +use Symfony\Component\String\Inflector\EnglishInflector; + +class ConfigurationAttributeGeneratorTest extends TestCase +{ + /** + * @dataProvider provideGenerateClassAttributesCases + */ + public function testGenerateClassAttributes(SchemaClass $class, array $config, array $attributes): void + { + $this->assertEquals($attributes, $this->generator($config)->generateClassAttributes($class)); + } + + public function provideGenerateClassAttributesCases(): \Generator + { + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph())); + + yield 'no configuration' => [$class, [], []]; + + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph())); + + yield 'type configuration' => [ + $class, + ['types' => ['Foo' => ['attributes' => ['ApiResource' => ['routePrefix' => '/prefix']]]]], + [new Attribute('ApiResource', ['routePrefix' => '/prefix'])], + ]; + + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI))); + $expectedAttribute = new Attribute('ApiResource', ['routePrefix' => '/prefix']); + $expectedAttribute->append = false; + + yield 'vocab configuration' => [ + $class, + ['vocabularies' => [SchemaGeneratorConfiguration::SCHEMA_ORG_URI => ['attributes' => ['ApiResource' => ['routePrefix' => '/prefix']]]]], + [$expectedAttribute], + ]; + + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI))); + + yield 'vocab and type configuration' => [ + $class, + [ + 'vocabularies' => [SchemaGeneratorConfiguration::SCHEMA_ORG_URI => ['attributes' => ['ApiResource' => ['routePrefix' => '/prefix']]]], + 'types' => ['Foo' => ['attributes' => ['ApiResource' => ['security' => "is_granted('ROLE_USER')"]]]], + ], + [new Attribute('ApiResource', ['security' => "is_granted('ROLE_USER')"])], + ]; + } + + /** + * @dataProvider provideGeneratePropertyAttributesCases + */ + public function testGeneratePropertyAttributes(Property $property, array $config, array $attributes): void + { + $this->assertEquals($attributes, $this->generator($config)->generatePropertyAttributes($property, 'Res')); + } + + public function provideGeneratePropertyAttributesCases(): \Generator + { + $property = new Property('prop'); + + yield 'no configuration' => [$property, [], []]; + + $property = new Property('prop'); + + yield 'type configuration' => [ + $property, + ['types' => ['Res' => ['properties' => ['prop' => ['attributes' => ['ApiResource' => ['security' => "is_granted('ROLE_USER')"]]]]]]], + [new Attribute('ApiResource', ['security' => "is_granted('ROLE_USER')"])], + ]; + } + + /** + * @dataProvider provideGenerateUsesCases + */ + public function testGenerateUses(SchemaClass $class, array $config, array $uses): void + { + $this->assertEquals($uses, $this->generator($config)->generateUses($class)); + } + + public function provideGenerateUsesCases(): \Generator + { + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph())); + + yield 'no configuration' => [$class, ['uses' => []], []]; + + $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph())); + + yield 'type configuration' => [ + $class, + ['uses' => ['Symfony\Component\Validator\Constraints' => ['alias' => 'Assert']]], + [new Use_('Symfony\Component\Validator\Constraints', 'Assert')], + ]; + } + + private function generator(array $config = []): ConfigurationAttributeGenerator + { + return new ConfigurationAttributeGenerator( + new PhpTypeConverter(), + new EnglishInflector(), + $config, + [], + ); + } +} diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 9c3a27c6..404b097a 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -266,6 +266,7 @@ interface: null - ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\ConfigurationAttributeGenerator # Directories for custom generator twig templates generatorTemplates: [] diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 51df6f13..5bbb50d8 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -499,8 +499,8 @@ public function testActivityStreams(): void * * @see http://www.w3.org/ns/activitystreams#Page */ -#[ApiResource(types: ['http://www.w3.org/ns/activitystreams#Page'], routePrefix: 'as')] #[ORM\Entity] +#[ApiResource(types: ['http://www.w3.org/ns/activitystreams#Page'], routePrefix: 'as')] class Page extends Object_ PHP , $page); From 424578ecb9ef3e8c8f262646c989a1d39755dec4 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 30 Jun 2022 17:31:29 +0200 Subject: [PATCH 219/258] feat: add Doctrine inheritance support (discriminator) (#382) --- bin/compile | 2 + phpstan.neon | 4 +- .../ApiPlatformCoreAttributeGenerator.php | 2 +- .../DoctrineMongoDBAttributeGenerator.php | 40 ++++++++-------- .../DoctrineOrmAttributeGenerator.php | 42 +++++++++-------- src/ClassMutator/ClassIdAppender.php | 7 ++- src/Model/Class_.php | 2 + src/SchemaGeneratorConfiguration.php | 2 +- src/TypesGenerator.php | 8 +++- .../ApiPlatformCoreAttributeGeneratorTest.php | 6 +-- .../DoctrineMongoDBAttributeGeneratorTest.php | 45 ++++++++++-------- .../DoctrineOrmAttributeGeneratorTest.php | 45 ++++++++++-------- tests/Command/DumpConfigurationTest.php | 6 +-- tests/TypesGeneratorTest.php | 14 +++--- .../App/Schema/Entity/ContactPoint.php | 46 +++++++++++++++++++ .../customized/App/Schema/Entity/Person.php | 13 +----- .../App/Schema/Entity/PostalAddress.php | 12 +---- .../customized/App/Schema/Entity/Thing.php | 17 ++++++- .../App/Schema/Entity/ContactPoint.php | 46 +++++++++++++++++++ .../e2e/original/App/Schema/Entity/Person.php | 11 +---- .../App/Schema/Entity/PostalAddress.php | 12 +---- .../e2e/original/App/Schema/Entity/Thing.php | 17 ++++++- tests/e2e/schema.yml | 4 ++ 23 files changed, 258 insertions(+), 145 deletions(-) create mode 100644 tests/e2e/customized/App/Schema/Entity/ContactPoint.php create mode 100644 tests/e2e/original/App/Schema/Entity/ContactPoint.php diff --git a/bin/compile b/bin/compile index 66318e24..2ef802ab 100755 --- a/bin/compile +++ b/bin/compile @@ -9,6 +9,7 @@ rm -rf tmp/original php schema.phar generate tmp/original tests/e2e/schema.yml -n -vv --ansi; diff tests/e2e/original/App/Schema/Entity/Brand.php tmp/original/App/Schema/Entity/Brand.php; +diff tests/e2e/original/App/Schema/Entity/ContactPoint.php tmp/original/App/Schema/Entity/ContactPoint.php; diff tests/e2e/original/App/Schema/Entity/Person.php tmp/original/App/Schema/Entity/Person.php; diff tests/e2e/original/App/Schema/Entity/PostalAddress.php tmp/original/App/Schema/Entity/PostalAddress.php; diff tests/e2e/original/App/Schema/Entity/Thing.php tmp/original/App/Schema/Entity/Thing.php; @@ -21,6 +22,7 @@ cp -r tests/e2e/customized tmp/ php schema.phar generate tmp/customized tests/e2e/schema.yml -n -vv --ansi; diff tests/e2e/customized/App/Schema/Entity/Brand.php tmp/customized/App/Schema/Entity/Brand.php; +diff tests/e2e/customized/App/Schema/Entity/ContactPoint.php tmp/customized/App/Schema/Entity/ContactPoint.php; diff tests/e2e/customized/App/Schema/Entity/Person.php tmp/customized/App/Schema/Entity/Person.php; diff tests/e2e/customized/App/Schema/Entity/PostalAddress.php tmp/customized/App/Schema/Entity/PostalAddress.php; diff tests/e2e/customized/App/Schema/Entity/Thing.php tmp/customized/App/Schema/Entity/Thing.php; diff --git a/phpstan.neon b/phpstan.neon index dfab95cb..07dc5b3a 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -45,13 +45,13 @@ parameters: relations: string[], debug: boolean, apiPlatformOldAttributes: boolean, - id: array{generate: boolean, generationStrategy: string, writable: boolean, onClass: string}, + id: array{generate: boolean, generationStrategy: string, writable: boolean}, useInterface: boolean, checkIsGoodRelations: boolean, header: ?string, namespaces: array{prefix: ?string, entity: string, enum: string, interface: string}, uses: array, - doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, resolveTargetEntityConfigType: 'XML'|'yaml', inheritanceAttributes: array}, + doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, resolveTargetEntityConfigType: 'XML'|'yaml', inheritanceAttributes: array, inheritanceType: 'JOINED'|'SINGLE_TABLE'|'SINGLE_COLLECTION'|'TABLE_PER_CLASS'|'COLLECTION_PER_CLASS'|'NONE'}, validator: array{assertType: boolean}, author: false|string, fieldVisibility: string, diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 91368a3c..297542c2 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -44,7 +44,7 @@ final class ApiPlatformCoreAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - if ($class->isAbstract || $class->isEnum()) { + if ($class->hasChild || $class->isEnum()) { return []; } diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index 4d77f086..4a4e9d36 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -18,6 +18,8 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; +use Nette\PhpGenerator\Literal; +use function Symfony\Component\String\u; /** * Doctrine MongoDB attribute generator. @@ -36,17 +38,29 @@ public function generateClassAttributes(Class_ $class): array } $attributes = []; - if ($class->isAbstract) { - if ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes']) { - $attributes = []; - foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs); + if ($class->hasChild && ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes'])) { + foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs); + } + } elseif ($class->isAbstract) { + $attributes[] = new Attribute('MongoDB\MappedSuperclass'); + } elseif ($class->hasChild && $class->isReferencedBy) { + $parentNames = [$class->name()]; + $childNames = []; + while (!empty($parentNames)) { + $directChildren = []; + foreach ($parentNames as $parentName) { + $directChildren = array_merge($directChildren, array_filter($this->classes, fn (Class_ $childClass) => $parentName === $childClass->parent())); } - - return $attributes; + $parentNames = array_keys($directChildren); + $childNames = array_merge($childNames, array_keys(array_filter($directChildren, fn (Class_ $childClass) => !$childClass->isAbstract))); } + $mapNames = array_merge([$class->name()], $childNames); - $attributes[] = new Attribute('MongoDB\MappedSuperclass'); + $attributes[] = new Attribute('MongoDB\Document'); + $attributes[] = new Attribute('MongoDB\InheritanceType', [\in_array($this->config['doctrine']['inheritanceType'], ['SINGLE_COLLECTION', 'COLLECTION_PER_CLASS', 'NONE'], true) ? $this->config['doctrine']['inheritanceType'] : 'SINGLE_COLLECTION']); + $attributes[] = new Attribute('MongoDB\DiscriminatorField', ['discr']); + $attributes[] = new Attribute('MongoDB\DiscriminatorMap', [array_reduce($mapNames, fn (array $map, string $mapName) => $map + [u($mapName)->camel()->toString() => new Literal(sprintf('%s::class', $mapName))], [])]); } else { $attributes[] = new Attribute('MongoDB\Document'); } @@ -145,16 +159,6 @@ private function getRelationName(Property $property, string $className): ?string return null; } - if ($reference->isAbstract && !$this->config['doctrine']['inheritanceAttributes']) { - $this->logger ? $this->logger->warning( - <<<'EOD' - Cannot create a relation from the property "{property}" of the class "{class}" to the class "{referenceClass}" because the latter is a Mapped Superclass. - If you want to add a relation anyway, use an inheritance mapping strategy and a discriminator column to do so. - EOD, ['property' => $property->name(), 'class' => $className, 'referenceClass' => $reference->shortName()]) : null; - - return null; - } - return $reference->interfaceName() ?: $reference->name(); } diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 352b2c99..bc663a5b 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -18,6 +18,8 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; +use Nette\PhpGenerator\Literal; +use function Symfony\Component\String\u; /** * Doctrine attribute generator. @@ -51,17 +53,29 @@ public function generateClassAttributes(Class_ $class): array } $attributes = []; - if ($class->isAbstract) { - if ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes']) { - $attributes = []; - foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs); + if ($class->hasChild && ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes'])) { + foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs); + } + } elseif ($class->isAbstract) { + $attributes[] = new Attribute('ORM\MappedSuperclass'); + } elseif ($class->hasChild && $class->isReferencedBy) { + $parentNames = [$class->name()]; + $childNames = []; + while (!empty($parentNames)) { + $directChildren = []; + foreach ($parentNames as $parentName) { + $directChildren = array_merge($directChildren, array_filter($this->classes, fn (Class_ $childClass) => $parentName === $childClass->parent())); } - - return $attributes; + $parentNames = array_keys($directChildren); + $childNames = array_merge($childNames, array_keys(array_filter($directChildren, fn (Class_ $childClass) => !$childClass->isAbstract))); } + $mapNames = array_merge([$class->name()], $childNames); - $attributes[] = new Attribute('ORM\MappedSuperclass'); + $attributes[] = new Attribute('ORM\Entity'); + $attributes[] = new Attribute('ORM\InheritanceType', [\in_array($this->config['doctrine']['inheritanceType'], ['JOINED', 'SINGLE_TABLE', 'TABLE_PER_CLASS', 'NONE'], true) ? $this->config['doctrine']['inheritanceType'] : 'JOINED']); + $attributes[] = new Attribute('ORM\DiscriminatorColumn', ['name' => 'discr']); + $attributes[] = new Attribute('ORM\DiscriminatorMap', [array_reduce($mapNames, fn (array $map, string $mapName) => $map + [u($mapName)->camel()->toString() => new Literal(sprintf('%s::class', $mapName))], [])]); } else { $attributes[] = new Attribute('ORM\Entity'); } @@ -72,8 +86,6 @@ public function generateClassAttributes(Class_ $class): array } $attributes[] = new Attribute('ORM\Table', ['name' => strtolower($class->name())]); - - return $attributes; } return $attributes; @@ -275,16 +287,6 @@ private function getRelationName(Property $property, string $className): ?string return null; } - if ($reference->isAbstract && !$this->config['doctrine']['inheritanceAttributes']) { - $this->logger ? $this->logger->warning( - <<<'EOD' - Cannot create a relation from the property "{property}" of the class "{class}" to the class "{referenceClass}" because the latter is a Mapped Superclass. - If you want to add a relation anyway, use an inheritance mapping strategy and a discriminator column to do so. - EOD, ['property' => $property->name(), 'class' => $className, 'referenceClass' => $reference->shortName()]) : null; - - return null; - } - if (null !== $reference->interfaceName()) { if (isset($this->config['types'][$reference->name()]['namespaces']['interface'])) { return sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['interface'], $reference->interfaceName()); diff --git a/src/ClassMutator/ClassIdAppender.php b/src/ClassMutator/ClassIdAppender.php index 5d1af6ca..14b666a4 100644 --- a/src/ClassMutator/ClassIdAppender.php +++ b/src/ClassMutator/ClassIdAppender.php @@ -37,10 +37,9 @@ public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator, a public function __invoke(Class_ $class, array $context): void { if ( - $class->isEnum() - || $class->isEmbeddable - || ($class->hasParent() && 'parent' === $this->config['id']['onClass']) - || ($class->hasChild && 'child' === $this->config['id']['onClass']) + $class->isEmbeddable + || $class->isEnum() + || $class->hasParent() ) { return; } diff --git a/src/Model/Class_.php b/src/Model/Class_.php index fb5632c0..7827a72c 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -42,6 +42,8 @@ abstract class Class_ private array $constants = []; public bool $hasConstructor = false; public bool $parentHasConstructor = false; + /** @var Class_[] */ + public array $isReferencedBy = []; public bool $isAbstract = false; public bool $hasChild = false; public bool $isEmbeddable = false; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 4c06182e..e19a9f79 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -111,7 +111,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->booleanNode('generate')->defaultTrue()->info('Automatically add an id field to entities')->end() ->enumNode('generationStrategy')->defaultValue('auto')->values(['auto', 'none', 'uuid', 'mongoid'])->info('The ID generation strategy to use ("none" to not let the database generate IDs).')->end() ->booleanNode('writable')->defaultFalse()->info('Is the ID writable? Only applicable if "generationStrategy" is "uuid".')->end() - ->enumNode('onClass')->defaultValue('child')->values(['child', 'parent'])->info('Set to "child" to generate the id on the child class, and "parent" to use the parent class instead.')->end() ->end() ->end() ->booleanNode('useInterface')->defaultFalse()->info('Generate interfaces and use Doctrine\'s Resolve Target Entity feature')->end() @@ -152,6 +151,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->then($transformOmap) ->end() ->end() + ->enumNode('inheritanceType')->defaultValue('JOINED')->values(['JOINED', 'SINGLE_TABLE', 'SINGLE_COLLECTION', 'TABLE_PER_CLASS', 'COLLECTION_PER_CLASS', 'NONE'])->info('The inheritance type to use when an entity is referenced by another and has child')->end() ->end() ->end() ->arrayNode('validator') diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 4a9b2850..be79b4cf 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -136,6 +136,8 @@ public function generate(array $graphs, array $config): array $classes = array_intersect_key($classes, array_flip($typeNamesToGenerate)); $types = array_intersect_key($types, array_flip($typeNamesToGenerate)); + $referencedByClasses = []; + // Second pass foreach ($classes as $class) { /** @var $class SchemaClass */ @@ -154,6 +156,7 @@ public function generate(array $graphs, array $config): array $typeName = $property->rangeName; if (isset($classes[$typeName])) { $property->reference = $classes[$typeName]; + $referencedByClasses[$typeName][$class->name()] = $class; } } @@ -162,8 +165,11 @@ public function generate(array $graphs, array $config): array // Third pass foreach ($classes as $class) { + $class->isReferencedBy = $referencedByClasses[$class->name()] ?? []; /* @var $class SchemaClass */ - $class->isAbstract = $config['types'][$class->name()]['abstract'] ?? $class->hasChild; + $class->isAbstract = $config['types'][$class->name()]['abstract'] + // Class is abstract if it has child and if it is not referenced by a relation + ?? ($class->hasChild && !$class->isReferencedBy); // When including all properties, ignore properties already set on parent if (($config['types'][$class->name()]['allProperties'] ?? true) && isset($classes[$class->parent()])) { diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 7bd2a990..c8dd06ab 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -78,9 +78,9 @@ public function provideGenerateClassAttributesCases(): \Generator ]; yield 'with operations (old)' => [$class, [new Attribute('ApiResource', ['iri' => 'https://schema.org/WithOperations', 'itemOperations' => ['get' => ['route_name' => 'api_about_get']], 'collectionOperations' => []])], true]; - $class = new SchemaClass('Abstract', new RdfResource('https://schema.org/Abstract')); - $class->isAbstract = true; - yield 'abstract' => [$class, []]; + $class = new SchemaClass('HasChild', new RdfResource('https://schema.org/HasChild')); + $class->hasChild = true; + yield 'has child' => [$class, []]; $resource = new RdfResource('https://schema.org/MyEnum', new RdfGraph()); $resource->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 82054983..d386c356 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -23,17 +23,13 @@ use ApiPlatform\SchemaGenerator\TypesGenerator; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use Nette\PhpGenerator\Literal; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Psr\Log\LoggerInterface; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\String\Inflector\EnglishInflector; class DoctrineMongoDBAttributeGeneratorTest extends TestCase { - use ProphecyTrait; - private DoctrineMongoDBAttributeGenerator $generator; private array $classMap = []; @@ -42,11 +38,22 @@ protected function setUp(): void { $graph = new RdfGraph(); - $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph)); - $product->isAbstract = true; + $thing = new SchemaClass('Thing', new RdfResource('https://schema.org/Thing', $graph)); + $thing->isAbstract = true; + $thing->hasChild = true; + $this->classMap[$thing->name()] = $thing; + + $organization = new SchemaClass('Organization', new RdfResource('https://schema.org/Organization', $graph)); + $this->classMap[$organization->name()] = $organization; + + $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph), 'Thing'); + $product->hasChild = true; + $product->isReferencedBy = [$organization]; $this->classMap[$product->name()] = $product; - $vehicle = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); + $vehicle = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph), 'Product'); + $vehicle->hasChild = true; + $vehicle->isAbstract = true; $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; $idProperty->range = new RdfResource('https://schema.org/identifier'); @@ -92,6 +99,9 @@ protected function setUp(): void $this->classMap[$vehicle->name()] = $vehicle; + $car = new SchemaClass('Car', new RdfResource('https://schema.org/Car', $graph), 'Vehicle'); + $this->classMap[$car->name()] = $car; + $myEnum = new RdfResource('https://schema.org/MyEnum', $graph); $myEnum->add('rdfs:subClassOf', ['type' => 'uri', 'value' => TypesGenerator::SCHEMA_ORG_ENUMERATION]); $myEnumClass = new SchemaClass('MyEnum', $myEnum); @@ -118,8 +128,14 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); - $this->assertEquals([new Attribute('MongoDB\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); - $this->assertEquals([new Attribute('MongoDB\Document')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); + $this->assertEquals([new Attribute('MongoDB\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Thing'])); + $this->assertEquals([ + new Attribute('MongoDB\Document'), + new Attribute('MongoDB\InheritanceType', ['SINGLE_COLLECTION']), + new Attribute('MongoDB\DiscriminatorField', ['discr']), + new Attribute('MongoDB\DiscriminatorMap', [['product' => new Literal('Product::class'), 'car' => new Literal('Car::class')]]), + ], $this->generator->generateClassAttributes($this->classMap['Product'])); + $this->assertEquals([new Attribute('MongoDB\Document')], $this->generator->generateClassAttributes($this->classMap['Car'])); } public function testGenerateFieldAttributes(): void @@ -149,13 +165,4 @@ public function testGenerateFieldAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relations'), 'Vehicle') ); } - - public function testGenerateAbstractRelation(): void - { - $loggerProphecy = $this->prophesize(LoggerInterface::class); - $loggerProphecy->warning(Argument::cetera())->shouldBeCalledOnce(); - $this->generator->setLogger($loggerProphecy->reveal()); - - $this->assertSame([], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('product'), 'Vehicle')); - } } diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index f77e4984..d30efa77 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -23,10 +23,8 @@ use ApiPlatform\SchemaGenerator\TypesGenerator; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use Nette\PhpGenerator\Literal; use PHPUnit\Framework\TestCase; -use Prophecy\Argument; -use Prophecy\PhpUnit\ProphecyTrait; -use Psr\Log\LoggerInterface; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\String\Inflector\EnglishInflector; @@ -35,8 +33,6 @@ */ class DoctrineOrmAttributeGeneratorTest extends TestCase { - use ProphecyTrait; - private DoctrineOrmAttributeGenerator $generator; private array $classMap = []; @@ -45,11 +41,22 @@ protected function setUp(): void { $graph = new RdfGraph(); - $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph)); - $product->isAbstract = true; + $thing = new SchemaClass('Thing', new RdfResource('https://schema.org/Thing', $graph)); + $thing->isAbstract = true; + $thing->hasChild = true; + $this->classMap[$thing->name()] = $thing; + + $organization = new SchemaClass('Organization', new RdfResource('https://schema.org/Organization', $graph)); + $this->classMap[$organization->name()] = $organization; + + $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph), 'Thing'); + $product->hasChild = true; + $product->isReferencedBy = [$organization]; $this->classMap[$product->name()] = $product; - $vehicle = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); + $vehicle = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph), 'Product'); + $vehicle->hasChild = true; + $vehicle->isAbstract = true; $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; $idProperty->range = new RdfResource('https://schema.org/identifier'); @@ -134,6 +141,9 @@ protected function setUp(): void $this->classMap[$vehicle->name()] = $vehicle; + $car = new SchemaClass('Car', new RdfResource('https://schema.org/Car', $graph), 'Vehicle'); + $this->classMap[$car->name()] = $car; + $quantitativeValue = new SchemaClass('QuantitativeValue', new RdfResource('https://schema.org/QuantitativeValue', $graph)); $quantitativeValue->isEmbeddable = true; $this->classMap[$quantitativeValue->name()] = $quantitativeValue; @@ -164,8 +174,14 @@ protected function setUp(): void public function testGenerateClassAttributes(): void { $this->assertSame([], $this->generator->generateClassAttributes($this->classMap['MyEnum'])); - $this->assertEquals([new Attribute('ORM\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Product'])); - $this->assertEquals([new Attribute('ORM\Entity')], $this->generator->generateClassAttributes($this->classMap['Vehicle'])); + $this->assertEquals([new Attribute('ORM\MappedSuperclass')], $this->generator->generateClassAttributes($this->classMap['Thing'])); + $this->assertEquals([ + new Attribute('ORM\Entity'), + new Attribute('ORM\InheritanceType', ['JOINED']), + new Attribute('ORM\DiscriminatorColumn', ['name' => 'discr']), + new Attribute('ORM\DiscriminatorMap', [['product' => new Literal('Product::class'), 'car' => new Literal('Car::class')]]), + ], $this->generator->generateClassAttributes($this->classMap['Product'])); + $this->assertEquals([new Attribute('ORM\Entity')], $this->generator->generateClassAttributes($this->classMap['Car'])); $this->assertEquals([new Attribute('ORM\Embeddable')], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); } @@ -220,13 +236,4 @@ public function testGenerateFieldAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle') ); } - - public function testGenerateAbstractRelation(): void - { - $loggerProphecy = $this->prophesize(LoggerInterface::class); - $loggerProphecy->warning(Argument::cetera())->shouldBeCalledOnce(); - $this->generator->setLogger($loggerProphecy->reveal()); - - $this->assertSame([], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('product'), 'Vehicle')); - } } diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 404b097a..c85986b5 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -76,9 +76,6 @@ public function testDumpConfiguration(): void # Is the ID writable? Only applicable if "generationStrategy" is "uuid". writable: false - # Set to "child" to generate the id on the child class, and "parent" to use the parent class instead. - onClass: child # One of "child"; "parent" - # Generate interfaces and use Doctrine's Resolve Target Entity feature useInterface: false @@ -130,6 +127,9 @@ interface: App\Model # Example: App\Model # Doctrine inheritance attributes (if set, no other attributes are generated) inheritanceAttributes: [] + # The inheritance type to use when an entity is referenced by another and has child + inheritanceType: JOINED # One of "JOINED"; "SINGLE_TABLE"; "SINGLE_COLLECTION"; "TABLE_PER_CLASS"; "COLLECTION_PER_CLASS"; "NONE" + # Symfony Validator Component validator: diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 4c203840..91c244fc 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -112,7 +112,7 @@ public function testGenerate(): void $this->assertStringContainsString('public function removeArticleSection(string $articleSection): void', $article); $creativeWork = file_get_contents("$this->outputDir/App/Entity/CreativeWork.php"); - $this->assertStringContainsString('abstract class CreativeWork extends Thing', $creativeWork); + $this->assertStringContainsString('class CreativeWork extends Thing', $creativeWork); $this->assertStringContainsString('private ?Person $author = null;', $creativeWork); $this->assertStringContainsString('private ?\DateTimeInterface $datePublished = null;', $creativeWork); $this->assertStringContainsString('private ?string $headline = null;', $creativeWork); @@ -120,8 +120,6 @@ public function testGenerate(): void $blogPosting = file_get_contents("$this->outputDir/App/Entity/BlogPosting.php"); $this->assertStringContainsString('class BlogPosting extends SocialMediaPosting', $blogPosting); - $this->assertStringContainsString('private ?int $id = null;', $blogPosting); - $this->assertStringContainsString('public function getId(): ?int', $blogPosting); $socialMediaPosting = file_get_contents("$this->outputDir/App/Entity/SocialMediaPosting.php"); $this->assertStringContainsString('abstract class SocialMediaPosting extends Article', $socialMediaPosting); @@ -142,15 +140,19 @@ public function getSharedContent(): ?CreativeWork $person = file_get_contents("$this->outputDir/App/Entity/Person.php"); $this->assertStringContainsString('class Person extends Thing', $person); - $this->assertStringContainsString('private ?int $id = null;', $person); - $this->assertStringContainsString('public function getId(): ?int', $person); $thing = file_get_contents("$this->outputDir/App/Entity/Thing.php"); $this->assertStringContainsString(<<<'PHP' abstract class Thing { + private ?int $id = null; private ?string $name = null; + public function getId(): ?int + { + return $this->id; + } + public function setName(?string $name): void { $this->name = $name; @@ -173,9 +175,7 @@ public function testGenerateAllResolveTypes(): void $competencyWorldEntity = file_get_contents("$this->outputDir/App/Entity/CompetencyWorldEntity.php"); $this->assertStringContainsString('class CompetencyWorldEntity extends Thing', $competencyWorldEntity); - $this->assertStringContainsString('private ?int $id = null;', $competencyWorldEntity); $this->assertStringContainsString('private string $hasAppellation;', $competencyWorldEntity); - $this->assertStringContainsString('public function getId(): ?int', $competencyWorldEntity); $this->assertStringContainsString('public function setHasAppellation(string $hasAppellation): void', $competencyWorldEntity); $this->assertStringContainsString('public function getHasAppellation(): string', $competencyWorldEntity); } diff --git a/tests/e2e/customized/App/Schema/Entity/ContactPoint.php b/tests/e2e/customized/App/Schema/Entity/ContactPoint.php new file mode 100644 index 00000000..a74dce5b --- /dev/null +++ b/tests/e2e/customized/App/Schema/Entity/ContactPoint.php @@ -0,0 +1,46 @@ +id; + } + + public function setTelephone(?string $telephone): void + { + $this->telephone = $telephone; + } + + public function getTelephone(): ?string + { + return $this->telephone; + } +} diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 5e4ef86c..3d79ddf4 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -43,17 +43,12 @@ class Person extends MyCustomClass implements MyCustomInterface private string $myProperty = 'foo'; - #[MyCustomAttribute] - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'AUTO')] - #[ORM\Column(type: 'integer')] - private ?int $id = null; - /** * Family name. In the U.S., the last name of a Person. * * @see https://schema.org/familyName */ + #[MyCustomAttribute] #[ORM\Column(type: 'text', nullable: true)] #[ApiProperty(types: ['https://schema.org/familyName'])] private ?string $familyName = null; @@ -150,6 +145,7 @@ class Person extends MyCustomClass implements MyCustomInterface * * @see https://schema.org/knowsAbout */ + #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\Thing')] #[ApiProperty(types: ['https://schema.org/knowsAbout'])] private ?Thing $knowsAbout = null; @@ -167,11 +163,6 @@ public function getMyProperty(): string return $this->myProperty; } - public function getId(): ?int - { - return $this->id; - } - public function setFamilyName(?string $familyName): void { $this->familyName = $familyName; diff --git a/tests/e2e/customized/App/Schema/Entity/PostalAddress.php b/tests/e2e/customized/App/Schema/Entity/PostalAddress.php index 5e1437ac..8aa1616c 100644 --- a/tests/e2e/customized/App/Schema/Entity/PostalAddress.php +++ b/tests/e2e/customized/App/Schema/Entity/PostalAddress.php @@ -15,13 +15,8 @@ */ #[ORM\Entity] #[ApiResource(types: ['https://schema.org/PostalAddress'])] -class PostalAddress +class PostalAddress extends ContactPoint { - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'AUTO')] - #[ORM\Column(type: 'integer')] - private ?int $id = null; - /** * The country. For example, USA. You can also provide the two-letter \[ISO 3166-1 alpha-2 country code\](http://en.wikipedia.org/wiki/ISO\_3166-1). * @@ -67,11 +62,6 @@ class PostalAddress #[ApiProperty(types: ['https://schema.org/streetAddress'])] private ?string $streetAddress = null; - public function getId(): ?int - { - return $this->id; - } - public function setAddressCountry(?string $addressCountry): void { $this->addressCountry = $addressCountry; diff --git a/tests/e2e/customized/App/Schema/Entity/Thing.php b/tests/e2e/customized/App/Schema/Entity/Thing.php index d273b9f3..93dfb3fa 100644 --- a/tests/e2e/customized/App/Schema/Entity/Thing.php +++ b/tests/e2e/customized/App/Schema/Entity/Thing.php @@ -12,9 +12,17 @@ * * @see https://schema.org/Thing */ -#[ORM\MappedSuperclass] -abstract class Thing +#[ORM\Entity] +#[ORM\InheritanceType('JOINED')] +#[ORM\DiscriminatorColumn(name: 'discr')] +#[ORM\DiscriminatorMap(['thing' => Thing::class, 'person' => Person::class])] +class Thing { + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + /** * The name of the item. * @@ -24,6 +32,11 @@ abstract class Thing #[ApiProperty(types: ['https://schema.org/name'])] private ?string $name = null; + public function getId(): ?int + { + return $this->id; + } + public function setName(?string $name): void { $this->name = $name; diff --git a/tests/e2e/original/App/Schema/Entity/ContactPoint.php b/tests/e2e/original/App/Schema/Entity/ContactPoint.php new file mode 100644 index 00000000..a74dce5b --- /dev/null +++ b/tests/e2e/original/App/Schema/Entity/ContactPoint.php @@ -0,0 +1,46 @@ +id; + } + + public function setTelephone(?string $telephone): void + { + $this->telephone = $telephone; + } + + public function getTelephone(): ?string + { + return $this->telephone; + } +} diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 7985f9d6..3dbd0612 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -35,11 +35,6 @@ #[UniqueEntity('email')] class Person extends Thing { - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'AUTO')] - #[ORM\Column(type: 'integer')] - private ?int $id = null; - /** * Family name. In the U.S., the last name of a Person. * @@ -141,6 +136,7 @@ class Person extends Thing * * @see https://schema.org/knowsAbout */ + #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\Thing')] #[ApiProperty(types: ['https://schema.org/knowsAbout'])] private ?Thing $knowsAbout = null; @@ -155,11 +151,6 @@ public function __construct() $this->siblings = new ArrayCollection(); } - public function getId(): ?int - { - return $this->id; - } - public function setFamilyName(?string $familyName): void { $this->familyName = $familyName; diff --git a/tests/e2e/original/App/Schema/Entity/PostalAddress.php b/tests/e2e/original/App/Schema/Entity/PostalAddress.php index 5e1437ac..8aa1616c 100644 --- a/tests/e2e/original/App/Schema/Entity/PostalAddress.php +++ b/tests/e2e/original/App/Schema/Entity/PostalAddress.php @@ -15,13 +15,8 @@ */ #[ORM\Entity] #[ApiResource(types: ['https://schema.org/PostalAddress'])] -class PostalAddress +class PostalAddress extends ContactPoint { - #[ORM\Id] - #[ORM\GeneratedValue(strategy: 'AUTO')] - #[ORM\Column(type: 'integer')] - private ?int $id = null; - /** * The country. For example, USA. You can also provide the two-letter \[ISO 3166-1 alpha-2 country code\](http://en.wikipedia.org/wiki/ISO\_3166-1). * @@ -67,11 +62,6 @@ class PostalAddress #[ApiProperty(types: ['https://schema.org/streetAddress'])] private ?string $streetAddress = null; - public function getId(): ?int - { - return $this->id; - } - public function setAddressCountry(?string $addressCountry): void { $this->addressCountry = $addressCountry; diff --git a/tests/e2e/original/App/Schema/Entity/Thing.php b/tests/e2e/original/App/Schema/Entity/Thing.php index d273b9f3..93dfb3fa 100644 --- a/tests/e2e/original/App/Schema/Entity/Thing.php +++ b/tests/e2e/original/App/Schema/Entity/Thing.php @@ -12,9 +12,17 @@ * * @see https://schema.org/Thing */ -#[ORM\MappedSuperclass] -abstract class Thing +#[ORM\Entity] +#[ORM\InheritanceType('JOINED')] +#[ORM\DiscriminatorColumn(name: 'discr')] +#[ORM\DiscriminatorMap(['thing' => Thing::class, 'person' => Person::class])] +class Thing { + #[ORM\Id] + #[ORM\GeneratedValue(strategy: 'AUTO')] + #[ORM\Column(type: 'integer')] + private ?int $id = null; + /** * The name of the item. * @@ -24,6 +32,11 @@ abstract class Thing #[ApiProperty(types: ['https://schema.org/name'])] private ?string $name = null; + public function getId(): ?int + { + return $this->id; + } + public function setName(?string $name): void { $this->name = $name; diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 693e329e..107688b7 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -40,7 +40,11 @@ types: properties: name: ~ slogan: ~ + ContactPoint: + properties: + telephone: ~ PostalAddress: + parent: ~ properties: addressCountry: { range: https://schema.org/Text } addressLocality: ~ From 262f5b265787493bdb542693ef6aa5d19e237f5e Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 30 Jun 2022 17:58:50 +0200 Subject: [PATCH 220/258] feat: add defaultCardinality configuration for relations (#383) --- phpstan.neon | 2 +- src/Schema/Generator.php | 2 +- .../PropertyGenerator/PropertyGenerator.php | 2 +- src/SchemaGeneratorConfiguration.php | 15 +++++++++++---- tests/Command/DumpConfigurationTest.php | 14 ++++++++++---- 5 files changed, 24 insertions(+), 11 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index 07dc5b3a..60b4ce18 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -42,7 +42,7 @@ parameters: array{ vocabularies: array{uri: string, format: string, allTypes: ?boolean, attributes: array}[], vocabularyNamespace: string, - relations: string[], + relations: array{uris: string[], defaultCardinality: string}, debug: boolean, apiPlatformOldAttributes: boolean, id: array{generate: boolean, generationStrategy: string, writable: boolean}, diff --git a/src/Schema/Generator.php b/src/Schema/Generator.php index aa0a5bee..6ef9ce04 100644 --- a/src/Schema/Generator.php +++ b/src/Schema/Generator.php @@ -46,7 +46,7 @@ public function generate(array $configuration, OutputInterface $output, SymfonyS } $relations = []; - foreach ($configuration['relations'] as $relation) { + foreach ($configuration['relations']['uris'] as $relation) { $relations[] = new \SimpleXMLElement($relation, 0, true); } diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 3d20a98a..781892aa 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -71,7 +71,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $cardinality = $propertyConfig['cardinality'] ?? false; if (!$cardinality || CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { - $cardinality = $cardinalities[$propertyUri] ?? CardinalitiesExtractor::CARDINALITY_1_1; + $cardinality = $cardinalities[$propertyUri] ?? $config['relations']['defaultCardinality']; } $isArray = \in_array($cardinality, [ diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index e19a9f79..aa679f89 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -97,10 +97,17 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->scalarNode('vocabularyNamespace')->defaultValue(self::SCHEMA_ORG_NAMESPACE)->info('Namespace of the vocabulary to import')->example('http://www.w3.org/ns/activitystreams#')->end() ->arrayNode('relations') - ->info('OWL relation files containing cardinality information in the GoodRelations format') - ->example(self::GOOD_RELATIONS_URI) - ->defaultValue([self::GOOD_RELATIONS_URI]) - ->scalarPrototype()->end() + ->addDefaultsIfNotSet() + ->info('Relations configuration') + ->children() + ->arrayNode('uris') + ->info('OWL relation URIs containing cardinality information in the GoodRelations format') + ->example(self::GOOD_RELATIONS_URI) + ->defaultValue([self::GOOD_RELATIONS_URI]) + ->scalarPrototype()->end() + ->end() + ->enumNode('defaultCardinality')->defaultValue('(1..1)')->values(['(0..1)', '(0..*)', '(1..1)', '(1..*)', '(*..0)', '(*..1)', '(*..*)'])->info('The default cardinality to use when it cannot be extracted')->end() + ->end() ->end() ->booleanNode('debug')->defaultFalse()->info('Debug mode')->end() ->booleanNode('apiPlatformOldAttributes')->defaultFalse()->info('Use old API Platform attributes (API Platform < 2.7)')->end() diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index c85986b5..61249f97 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -52,11 +52,17 @@ public function testDumpConfiguration(): void # Namespace of the vocabulary to import vocabularyNamespace: 'https://schema.org/' # Example: 'http://www.w3.org/ns/activitystreams#' - # OWL relation files containing cardinality information in the GoodRelations format - relations: # Example: 'https://archive.org/services/purl/goodrelations/v1.owl' + # Relations configuration + relations: - # Default: - - https://archive.org/services/purl/goodrelations/v1.owl + # OWL relation URIs containing cardinality information in the GoodRelations format + uris: # Example: 'https://archive.org/services/purl/goodrelations/v1.owl' + + # Default: + - https://archive.org/services/purl/goodrelations/v1.owl + + # The default cardinality to use when it cannot be extracted + defaultCardinality: (1..1) # One of "(0..1)"; "(0..*)"; "(1..1)"; "(1..*)"; "(*..0)"; "(*..1)"; "(*..*)" # Debug mode debug: false From 5c7bb2f03640be1917f05e4cd40259cfb5e15ec6 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 30 Jun 2022 20:32:14 +0200 Subject: [PATCH 221/258] fix: make sure the default cardinality is used (#384) --- .../PropertyGenerator/PropertyGenerator.php | 53 ++++++++++--------- src/SchemaGeneratorConfiguration.php | 2 +- .../ClassPropertiesAppenderTest.php | 10 ++-- tests/Command/DumpConfigurationTest.php | 4 +- tests/Command/GenerateCommandTest.php | 1 + tests/TypesGeneratorTest.php | 12 ++--- .../customized/App/Schema/Entity/Person.php | 36 +++++++------ .../e2e/original/App/Schema/Entity/Person.php | 36 +++++++------ 8 files changed, 86 insertions(+), 68 deletions(-) diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 781892aa..fb2a0e2e 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -69,26 +69,6 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $propertyConfig = $typeConfig['properties'][$name] ?? null; - $cardinality = $propertyConfig['cardinality'] ?? false; - if (!$cardinality || CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { - $cardinality = $cardinalities[$propertyUri] ?? $config['relations']['defaultCardinality']; - } - - $isArray = \in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_0_N, - CardinalitiesExtractor::CARDINALITY_1_N, - CardinalitiesExtractor::CARDINALITY_N_N, - ], true); - - $schemaProperty = new SchemaProperty($name); - $schemaProperty->isArray = $isArray; - - $schemaProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $schemaProperty); - - if (!$schemaProperty instanceof SchemaProperty) { - throw new \LogicException(sprintf('Property has to be an instance of "%s".', SchemaProperty::class)); - } - // Warn when property are not part of GoodRelations if ($config['checkIsGoodRelations'] && !$this->goodRelationsBridge->exists($name)) { $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyUri, $typeUri)) : null; @@ -135,10 +115,35 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont return null; } + $type = $this->typeConverter->getType($range); + + $cardinality = $propertyConfig['cardinality'] ?? CardinalitiesExtractor::CARDINALITY_UNKNOWN; + if (CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { + $cardinality = $cardinalities[$propertyUri] ?? CardinalitiesExtractor::CARDINALITY_UNKNOWN; + } + if (!$type && CardinalitiesExtractor::CARDINALITY_UNKNOWN === $cardinality) { + $cardinality = $config['relations']['defaultCardinality']; + } + + $isArray = \in_array($cardinality, [ + CardinalitiesExtractor::CARDINALITY_0_N, + CardinalitiesExtractor::CARDINALITY_1_N, + CardinalitiesExtractor::CARDINALITY_N_N, + ], true); + + $schemaProperty = new SchemaProperty($name); + $schemaProperty->isArray = $isArray; + + $schemaProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $schemaProperty); + + if (!$schemaProperty instanceof SchemaProperty) { + throw new \LogicException(sprintf('Property has to be an instance of "%s".', SchemaProperty::class)); + } + $isNullable = (bool) ($propertyConfig['nullable'] ?? !\in_array($cardinality, [ - CardinalitiesExtractor::CARDINALITY_1_1, - CardinalitiesExtractor::CARDINALITY_1_N, - ], true)); + CardinalitiesExtractor::CARDINALITY_1_1, + CardinalitiesExtractor::CARDINALITY_1_N, + ], true)); $columnPrefix = false; $isEmbedded = $propertyConfig['embedded'] ?? false; @@ -150,7 +155,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->resource = $typeProperty; $schemaProperty->range = $range; $schemaProperty->rangeName = $rangeName; - $schemaProperty->type = $this->typeConverter->getType($range); + $schemaProperty->type = $type; $schemaProperty->cardinality = $cardinality; $schemaProperty->ormColumn = $propertyConfig['ormColumn'] ?? null; $schemaProperty->isReadable = $propertyConfig['readable'] ?? true; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index aa679f89..56ee77cc 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -245,7 +245,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->scalarNode('inversedBy')->defaultNull()->info('The doctrine inversed by attribute')->example('episodes')->end() ->booleanNode('readable')->defaultTrue()->info('Is the property readable?')->end() ->booleanNode('writable')->defaultTrue()->info('Is the property writable?')->end() - ->booleanNode('nullable')->defaultTrue()->info('Is the property nullable?')->end() + ->booleanNode('nullable')->defaultNull()->info('Is the property nullable? (if null, cardinality will be used: will be true if no cardinality found)')->end() ->booleanNode('required')->defaultTrue()->info('Is the property required?')->end() ->booleanNode('unique')->defaultFalse()->info('The property unique')->end() ->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end() diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index bedd045c..ccbcf376 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -101,25 +101,25 @@ public function provideInvokeTestCases(): \Generator $article = new SchemaClass('Article', new RdfResource('https://schema.org/Article')); $graph = new RdfGraph(); $expectedArticleBodyProperty = new Property('articleBody'); - $expectedArticleBodyProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $expectedArticleBodyProperty->cardinality = CardinalitiesExtractor::CARDINALITY_UNKNOWN; $expectedArticleBodyProperty->resource = new RdfResource('https://schema.org/articleBody', $graph); $expectedArticleBodyProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedArticleBodyProperty->rangeName = 'Text'; $expectedArticleBodyProperty->type = 'string'; - $expectedArticleBodyProperty->isNullable = false; + $expectedArticleBodyProperty->isNullable = true; $expectedArticleSectionProperty = new Property('articleSection'); - $expectedArticleSectionProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $expectedArticleSectionProperty->cardinality = CardinalitiesExtractor::CARDINALITY_UNKNOWN; $expectedArticleSectionProperty->resource = new RdfResource('https://schema.org/articleSection', $graph); $expectedArticleSectionProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedArticleSectionProperty->rangeName = 'Text'; $expectedArticleSectionProperty->type = 'string'; - $expectedArticleSectionProperty->isNullable = false; + $expectedArticleSectionProperty->isNullable = true; yield 'no configuration' => [clone $article, (clone $article)->addProperty($expectedArticleBodyProperty)->addProperty($expectedArticleSectionProperty), $graph]; $graph = new RdfGraph(); $person = new SchemaClass('Person', new RdfResource('https://schema.org/Person', $graph)); $expectedGivenNameProperty = new Property('givenName'); - $expectedGivenNameProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; + $expectedGivenNameProperty->cardinality = CardinalitiesExtractor::CARDINALITY_UNKNOWN; $expectedGivenNameProperty->resource = new RdfResource('https://schema.org/givenName', $graph); $expectedGivenNameProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedGivenNameProperty->rangeName = 'Text'; diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 61249f97..8692f3f3 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -240,8 +240,8 @@ interface: null # Is the property writable? writable: true - # Is the property nullable? - nullable: true + # Is the property nullable? (if null, cardinality will be used: will be true if no cardinality found) + nullable: null # Is the property required? required: true diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 5bbb50d8..caae7740 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -93,6 +93,7 @@ public function testCustomAttributes(): void use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; +use Symfony\Component\Validator\Constraints as Assert; /** * A book. diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 91c244fc..0be943e8 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -123,16 +123,16 @@ public function testGenerate(): void $socialMediaPosting = file_get_contents("$this->outputDir/App/Entity/SocialMediaPosting.php"); $this->assertStringContainsString('abstract class SocialMediaPosting extends Article', $socialMediaPosting); - $this->assertStringContainsString('private ?CreativeWork $sharedContent = null;', $socialMediaPosting); + $this->assertStringContainsString('private CreativeWork $sharedContent;', $socialMediaPosting); $this->assertStringContainsString(<<<'PHP' - public function setSharedContent(?CreativeWork $sharedContent): void + public function setSharedContent(CreativeWork $sharedContent): void { $this->sharedContent = $sharedContent; } PHP, $socialMediaPosting); $this->assertStringContainsString(<<<'PHP' - public function getSharedContent(): ?CreativeWork + public function getSharedContent(): CreativeWork { return $this->sharedContent; } @@ -175,9 +175,9 @@ public function testGenerateAllResolveTypes(): void $competencyWorldEntity = file_get_contents("$this->outputDir/App/Entity/CompetencyWorldEntity.php"); $this->assertStringContainsString('class CompetencyWorldEntity extends Thing', $competencyWorldEntity); - $this->assertStringContainsString('private string $hasAppellation;', $competencyWorldEntity); - $this->assertStringContainsString('public function setHasAppellation(string $hasAppellation): void', $competencyWorldEntity); - $this->assertStringContainsString('public function getHasAppellation(): string', $competencyWorldEntity); + $this->assertStringContainsString('private ?string $hasAppellation = null;', $competencyWorldEntity); + $this->assertStringContainsString('public function setHasAppellation(?string $hasAppellation): void', $competencyWorldEntity); + $this->assertStringContainsString('public function getHasAppellation(): ?string', $competencyWorldEntity); } public function testGenerateVocabAllTypes(): void diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 3d79ddf4..f4d74c16 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -77,19 +77,22 @@ class Person extends MyCustomClass implements MyCustomInterface * * @see https://schema.org/gender */ - #[ORM\Column(nullable: true)] + #[ORM\Column] #[ApiProperty(types: ['https://schema.org/gender'])] + #[Assert\NotNull] #[Assert\Choice(callback: [GenderType::class, 'toArray'])] - private ?string $gender = null; + private string $gender; /** * Physical address of the item. * * @see https://schema.org/address */ - #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] + #[ORM\OneToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] + #[ORM\JoinColumn(nullable: false)] #[ApiProperty(types: ['https://schema.org/address'])] - private ?PostalAddress $address = null; + #[Assert\NotNull] + private PostalAddress $address; /** * Date of birth. @@ -145,13 +148,16 @@ class Person extends MyCustomClass implements MyCustomInterface * * @see https://schema.org/knowsAbout */ - #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\Thing')] + #[ORM\OneToOne(targetEntity: 'App\Schema\Entity\Thing')] + #[ORM\JoinColumn(nullable: false)] #[ApiProperty(types: ['https://schema.org/knowsAbout'])] - private ?Thing $knowsAbout = null; + #[Assert\NotNull] + private Thing $knowsAbout; /** @see _:customColumn */ #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] - private ?Person $customColumn = null; + #[Assert\NotNull] + private Person $customColumn; public function __construct() { @@ -193,22 +199,22 @@ public function getAdditionalName(): ?string return $this->additionalName; } - public function setGender(?string $gender): void + public function setGender(string $gender): void { $this->gender = $gender; } - public function getGender(): ?string + public function getGender(): string { return $this->gender; } - public function setAddress(?PostalAddress $address): void + public function setAddress(PostalAddress $address): void { $this->address = $address; } - public function getAddress(): ?PostalAddress + public function getAddress(): PostalAddress { return $this->address; } @@ -271,22 +277,22 @@ public function getSiblings(): Collection return $this->siblings; } - public function setKnowsAbout(?Thing $knowsAbout): void + public function setKnowsAbout(Thing $knowsAbout): void { $this->knowsAbout = $knowsAbout; } - public function getKnowsAbout(): ?Thing + public function getKnowsAbout(): Thing { return $this->knowsAbout; } - public function setCustomColumn(?Person $customColumn): void + public function setCustomColumn(Person $customColumn): void { $this->customColumn = $customColumn; } - public function getCustomColumn(): ?Person + public function getCustomColumn(): Person { return $this->customColumn; } diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 3dbd0612..d922a66a 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -68,19 +68,22 @@ class Person extends Thing * * @see https://schema.org/gender */ - #[ORM\Column(nullable: true)] + #[ORM\Column] #[ApiProperty(types: ['https://schema.org/gender'])] + #[Assert\NotNull] #[Assert\Choice(callback: [GenderType::class, 'toArray'])] - private ?string $gender = null; + private string $gender; /** * Physical address of the item. * * @see https://schema.org/address */ - #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] + #[ORM\OneToOne(targetEntity: 'App\Schema\Entity\PostalAddress')] + #[ORM\JoinColumn(nullable: false)] #[ApiProperty(types: ['https://schema.org/address'])] - private ?PostalAddress $address = null; + #[Assert\NotNull] + private PostalAddress $address; /** * Date of birth. @@ -136,15 +139,18 @@ class Person extends Thing * * @see https://schema.org/knowsAbout */ - #[ORM\ManyToOne(targetEntity: 'App\Schema\Entity\Thing')] + #[ORM\OneToOne(targetEntity: 'App\Schema\Entity\Thing')] + #[ORM\JoinColumn(nullable: false)] #[ApiProperty(types: ['https://schema.org/knowsAbout'])] - private ?Thing $knowsAbout = null; + #[Assert\NotNull] + private Thing $knowsAbout; /** * @see _:customColumn */ #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] - private ?Person $customColumn = null; + #[Assert\NotNull] + private Person $customColumn; public function __construct() { @@ -181,22 +187,22 @@ public function getAdditionalName(): ?string return $this->additionalName; } - public function setGender(?string $gender): void + public function setGender(string $gender): void { $this->gender = $gender; } - public function getGender(): ?string + public function getGender(): string { return $this->gender; } - public function setAddress(?PostalAddress $address): void + public function setAddress(PostalAddress $address): void { $this->address = $address; } - public function getAddress(): ?PostalAddress + public function getAddress(): PostalAddress { return $this->address; } @@ -259,22 +265,22 @@ public function getSiblings(): Collection return $this->siblings; } - public function setKnowsAbout(?Thing $knowsAbout): void + public function setKnowsAbout(Thing $knowsAbout): void { $this->knowsAbout = $knowsAbout; } - public function getKnowsAbout(): ?Thing + public function getKnowsAbout(): Thing { return $this->knowsAbout; } - public function setCustomColumn(?Person $customColumn): void + public function setCustomColumn(Person $customColumn): void { $this->customColumn = $customColumn; } - public function getCustomColumn(): ?Person + public function getCustomColumn(): Person { return $this->customColumn; } From e5caafec333bee7efc1957337705e4ec33274a2a Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 7 Jul 2022 16:28:26 +0200 Subject: [PATCH 222/258] feat: manage association overrides for Doctrine (#385) --- phpstan.neon | 11 +- .../AbstractAttributeGenerator.php | 8 ++ .../ApiPlatformCoreAttributeGenerator.php | 8 +- .../AttributeGeneratorInterface.php | 9 +- ...mAssociationOverrideAttributeGenerator.php | 76 +++++++++++++ .../DoctrineOrmAttributeGenerator.php | 38 +++---- .../GenerateIdentifierNameTrait.php | 38 +++++++ src/ClassMutator/AttributeAppender.php | 14 +++ src/Model/AddAttributeTrait.php | 13 ++- src/Model/Property.php | 3 - src/OpenApi/ClassGenerator.php | 6 +- src/PropertyGenerator/IdPropertyGenerator.php | 1 - .../PropertyGenerator/PropertyGenerator.php | 1 - src/SchemaGeneratorConfiguration.php | 9 +- src/TypesGenerator.php | 6 +- .../ApiPlatformCoreAttributeGeneratorTest.php | 2 +- .../DoctrineMongoDBAttributeGeneratorTest.php | 2 +- ...ociationOverrideAttributeGeneratorTest.php | 101 ++++++++++++++++++ .../DoctrineOrmAttributeGeneratorTest.php | 8 +- .../ClassPropertiesAppenderTest.php | 1 - tests/Command/DumpConfigurationTest.php | 10 +- tests/config/address-book.yaml | 11 +- tests/config/fluent-mutators.yaml | 11 +- tests/config/mongodb/address-book.yaml | 7 +- tests/config/public-properties.yaml | 11 +- .../customized/App/Schema/Entity/Person.php | 10 +- .../e2e/original/App/OpenApi/Entity/Book.php | 1 + .../e2e/original/App/Schema/Entity/Person.php | 10 +- tests/e2e/schema.yml | 2 +- 29 files changed, 332 insertions(+), 96 deletions(-) create mode 100644 src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php create mode 100644 src/AttributeGenerator/GenerateIdentifierNameTrait.php create mode 100644 tests/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGeneratorTest.php diff --git a/phpstan.neon b/phpstan.neon index 60b4ce18..dd18a773 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -7,9 +7,7 @@ parameters: array{ exclude: boolean, range: ?string, - relationTableName: ?string, cardinality: string, - ormColumn: array, groups: string[], mappedBy: ?string, inversedBy: ?string, @@ -51,7 +49,14 @@ parameters: header: ?string, namespaces: array{prefix: ?string, entity: string, enum: string, interface: string}, uses: array, - doctrine: array{useCollection: boolean, resolveTargetEntityConfigPath: ?string, resolveTargetEntityConfigType: 'XML'|'yaml', inheritanceAttributes: array, inheritanceType: 'JOINED'|'SINGLE_TABLE'|'SINGLE_COLLECTION'|'TABLE_PER_CLASS'|'COLLECTION_PER_CLASS'|'NONE'}, + doctrine: array{ + useCollection: boolean, + resolveTargetEntityConfigPath: ?string, + resolveTargetEntityConfigType: 'XML'|'yaml', + inheritanceAttributes: array, + inheritanceType: 'JOINED'|'SINGLE_TABLE'|'SINGLE_COLLECTION'|'TABLE_PER_CLASS'|'COLLECTION_PER_CLASS'|'NONE', + maxIdentifierLength: integer + }, validator: array{assertType: boolean}, author: false|string, fieldVisibility: string, diff --git a/src/AttributeGenerator/AbstractAttributeGenerator.php b/src/AttributeGenerator/AbstractAttributeGenerator.php index b72d22fc..622e60d4 100644 --- a/src/AttributeGenerator/AbstractAttributeGenerator.php +++ b/src/AttributeGenerator/AbstractAttributeGenerator.php @@ -63,6 +63,14 @@ public function generatePropertyAttributes(Property $property, string $className return []; } + /** + * {@inheritdoc} + */ + public function generateLateClassAttributes(Class_ $class): array + { + return []; + } + /** * {@inheritdoc} */ diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 297542c2..c9afbf79 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -81,13 +81,9 @@ public function generateClassAttributes(Class_ $class): array } else { $arguments['operations'] = []; foreach ($class->operations as $operationMetadataClass => $methodConfig) { - $arguments['operations'][] = new Literal(sprintf('new %s(%s)', + $arguments['operations'][] = new Literal(sprintf('new %s(...?:)', $operationMetadataClass, - implode(', ', array_map( - fn ($k, $v) => sprintf('%s: %s', $k, (\is_string($v) ? sprintf("'%s'", addslashes($v)) : (\is_scalar($v) ? $v : ''))), - array_keys($methodConfig ?? []), array_values($methodConfig ?? []) - )) - )); + ), [$methodConfig ?? []]); } } } diff --git a/src/AttributeGenerator/AttributeGeneratorInterface.php b/src/AttributeGenerator/AttributeGeneratorInterface.php index b5ae2b5d..bbf8ea8c 100644 --- a/src/AttributeGenerator/AttributeGeneratorInterface.php +++ b/src/AttributeGenerator/AttributeGeneratorInterface.php @@ -19,8 +19,6 @@ use ApiPlatform\SchemaGenerator\Model\Use_; /** - * Attribute Generator Interface. - * * @author Kévin Dunglas */ interface AttributeGeneratorInterface @@ -39,6 +37,13 @@ public function generateClassAttributes(Class_ $class): array; */ public function generatePropertyAttributes(Property $property, string $className): array; + /** + * Generates class attributes once class and properties attributes for all classes have been generated. + * + * @return Attribute[] + */ + public function generateLateClassAttributes(Class_ $class): array; + /** * Generates uses. * diff --git a/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php new file mode 100644 index 00000000..72a81fc2 --- /dev/null +++ b/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php @@ -0,0 +1,76 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\Model\Class_; +use Nette\PhpGenerator\Literal; + +final class DoctrineOrmAssociationOverrideAttributeGenerator extends AbstractAttributeGenerator +{ + use GenerateIdentifierNameTrait; + + /** + * {@inheritdoc} + */ + public function generateLateClassAttributes(Class_ $class): array + { + if ($class->isAbstract || !($parentName = $class->parent())) { + return []; + } + + $attributes = []; + $associationOverrides = []; + + while ($parentName) { + $parent = $this->classes[$parentName] ?? null; + if (!$parent || !$parent->isAbstract) { + $parentName = null; + + continue; + } + + foreach ($parent->properties() as $property) { + if (( + $joinTableAttribute = $property->getAttributeWithName('ORM\JoinTable')) + && \is_string($joinTableName = $joinTableAttribute->args()['name'])) { + $overrideJoinTableName = $this->generateIdentifierName($joinTableName.$class->name(), 'join_table', $this->config); + $overrideArgs = [ + 'name' => $property->name(), + 'joinTable' => new Literal("new ORM\JoinTable(...?:)", [['name' => $overrideJoinTableName]]), + ]; + + $joinColumnAttribute = $property->getAttributeWithName('ORM\JoinColumn'); + $overrideArgs['joinColumns'] = [new Literal("new ORM\JoinColumn(...?:)", [$joinColumnAttribute ? $joinColumnAttribute->args() : []])]; + + $inverseJoinColumnAttribute = $property->getAttributeWithName('ORM\InverseJoinColumn'); + $overrideArgs['inverseJoinColumns'] = [new Literal("new ORM\InverseJoinColumn(...?:)", [$inverseJoinColumnAttribute ? $inverseJoinColumnAttribute->args() : []])]; + + $associationOverrides[] = new Literal( + "new ORM\AssociationOverride(...?:)", + [$overrideArgs] + ); + } + } + + $parentName = $parent->parent(); + } + + if ($associationOverrides) { + $attributes[] = new Attribute('ORM\AssociationOverrides', [$associationOverrides]); + } + + return $attributes; + } +} diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index bc663a5b..3d9978a4 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -28,6 +28,8 @@ */ final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator { + use GenerateIdentifierNameTrait; + private const RESERVED_KEYWORDS = [ 'add', 'create', @@ -85,7 +87,7 @@ public function generateClassAttributes(Class_ $class): array continue; } - $attributes[] = new Attribute('ORM\Table', ['name' => strtolower($class->name())]); + $attributes[] = new Attribute('ORM\Table', ['name' => $this->generateIdentifierName($class->name(), 'table', $this->config)]); } return $attributes; @@ -100,18 +102,10 @@ public function generatePropertyAttributes(Property $property, string $className return []; } - if ($property->ormColumn) { - return [new Attribute('ORM\Column', $property->ormColumn)]; - } - if ($property->isId) { return $this->generateIdAttributes(); } - if (isset($this->config['types'][$className]['properties'][$property->name()])) { - $property->relationTableName = $this->config['types'][$className]['properties'][$property->name()]['relationTableName']; - } - $type = null; if ($property->isEnum) { $type = $property->isArray ? 'simple_array' : 'string'; @@ -173,7 +167,13 @@ public function generatePropertyAttributes(Property $property, string $className return [new Attribute('ORM\Column', $args)]; } - if (null === $relationName = $this->getRelationName($property, $className)) { + if (!$property->reference) { + $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; + + return []; + } + + if (null === $relationName = $this->getRelationName($property)) { return []; } @@ -181,6 +181,8 @@ public function generatePropertyAttributes(Property $property, string $className return [new Attribute('ORM\Embedded', ['class' => $relationName, 'columnPrefix' => $property->columnPrefix])]; } + $relationTableName = $this->generateIdentifierName($className.ucfirst($property->reference->name()).ucfirst($property->name()), 'join_table', $this->config); + $attributes = []; switch ($property->cardinality) { case CardinalitiesExtractor::CARDINALITY_0_1: @@ -212,9 +214,7 @@ public function generatePropertyAttributes(Property $property, string $className } else { $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); } - if ($property->relationTableName) { - $attributes[] = new Attribute('ORM\JoinTable', ['name' => $property->relationTableName]); - } + $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); $attributes[] = new Attribute('ORM\InverseJoinColumn', ['unique' => true]); break; case CardinalitiesExtractor::CARDINALITY_1_N: @@ -223,16 +223,12 @@ public function generatePropertyAttributes(Property $property, string $className } else { $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); } - if ($property->relationTableName) { - $attributes[] = new Attribute('ORM\JoinTable', ['name' => $property->relationTableName]); - } + $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); $attributes[] = new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true]); break; case CardinalitiesExtractor::CARDINALITY_N_N: $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); - if ($property->relationTableName) { - $attributes[] = new Attribute('ORM\JoinTable', ['name' => $property->relationTableName]); - } + $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); break; } @@ -277,13 +273,11 @@ private function generateIdAttributes(): array /** * Gets class or interface name to use in relations. */ - private function getRelationName(Property $property, string $className): ?string + private function getRelationName(Property $property): ?string { $reference = $property->reference; if (!$reference) { - $this->logger ? $this->logger->error('There is no reference for the property "{property}" from the class "{class}"', ['property' => $property->name(), 'class' => $className]) : null; - return null; } diff --git a/src/AttributeGenerator/GenerateIdentifierNameTrait.php b/src/AttributeGenerator/GenerateIdentifierNameTrait.php new file mode 100644 index 00000000..a638cbf8 --- /dev/null +++ b/src/AttributeGenerator/GenerateIdentifierNameTrait.php @@ -0,0 +1,38 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\AttributeGenerator; + +use function Symfony\Component\String\u; + +trait GenerateIdentifierNameTrait +{ + /** + * @param Configuration $config + */ + public function generateIdentifierName(string $name, string $defaultName, array $config): string + { + $maxIdentifierLength = $config['doctrine']['maxIdentifierLength']; + + $identifierName = u($name)->snake()->toString(); + + if (\strlen($identifierName) > $maxIdentifierLength) { + $identifierName = $defaultName.'_'.hash('adler32', $name); + if (\strlen($identifierName) > $maxIdentifierLength) { + throw new \RuntimeException('Identifier name with default name exceeds maximum identifier length.'); + } + } + + return $identifierName; + } +} diff --git a/src/ClassMutator/AttributeAppender.php b/src/ClassMutator/AttributeAppender.php index 8c7c99cb..ce3ac08a 100644 --- a/src/ClassMutator/AttributeAppender.php +++ b/src/ClassMutator/AttributeAppender.php @@ -44,6 +44,11 @@ public function __invoke(Class_ $class, array $context): void $this->generatePropertiesAttributes($class); } + public function appendLate(Class_ $class): void + { + $this->generateLateClassAttributes($class); + } + private function generateClassUses(Class_ $class): void { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; @@ -87,4 +92,13 @@ private function generatePropertiesAttributes(Class_ $class): void } } } + + private function generateLateClassAttributes(Class_ $class): void + { + foreach ($this->attributeGenerators as $generator) { + foreach ($generator->generateLateClassAttributes($class) as $attribute) { + $class->addAttribute($attribute); + } + } + } } diff --git a/src/Model/AddAttributeTrait.php b/src/Model/AddAttributeTrait.php index 76c0a390..8d92f530 100644 --- a/src/Model/AddAttributeTrait.php +++ b/src/Model/AddAttributeTrait.php @@ -18,10 +18,7 @@ trait AddAttributeTrait public function addAttribute(Attribute $attribute): self { if (!\in_array($attribute, $this->attributes, true)) { - if (empty(array_filter( - $this->attributes, - fn (Attribute $attr) => $attr->name() === $attribute->name() - ))) { + if (!$this->getAttributeWithName($attribute->name())) { if ($attribute->append) { $this->attributes[] = $attribute; } @@ -37,4 +34,12 @@ public function addAttribute(Attribute $attribute): self return $this; } + + public function getAttributeWithName(string $name): ?Attribute + { + return array_values(array_filter( + $this->attributes, + fn (Attribute $attr) => $attr->name() === $name + ))[0] ?? null; + } } diff --git a/src/Model/Property.php b/src/Model/Property.php index 5de420e2..ca956151 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -32,8 +32,6 @@ abstract class Property /** @var bool can be true and array type false if the property is an array of references */ public bool $isArray = false; public ?Class_ $reference = null; - /** @var array */ - public ?array $ormColumn = null; public bool $isReadable = true; public bool $isWritable = true; public bool $isRequired = false; @@ -47,7 +45,6 @@ abstract class Property public $columnPrefix = false; public bool $isId = false; public ?string $typeHint = null; - public ?string $relationTableName = null; public bool $isEnum = false; public ?string $adderRemoverTypeHint = null; /** @var string[] */ diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 2c026763..f3e31458 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -196,9 +196,13 @@ public function generate(OpenApi $openApi, array $config): array $attributeGenerators[] = $generator; } + $attributeAppender = new AttributeAppender($classes, $attributeGenerators); foreach ($classes as $class) { (new AnnotationsAppender($classes, $annotationGenerators, []))($class, []); - (new AttributeAppender($classes, $attributeGenerators))($class, []); + $attributeAppender($class, []); + } + foreach ($classes as $class) { + $attributeAppender->appendLate($class); } return $classes; diff --git a/src/PropertyGenerator/IdPropertyGenerator.php b/src/PropertyGenerator/IdPropertyGenerator.php index 98aafcbb..8208ffea 100644 --- a/src/PropertyGenerator/IdPropertyGenerator.php +++ b/src/PropertyGenerator/IdPropertyGenerator.php @@ -52,7 +52,6 @@ public function __invoke(string $generationStrategy, bool $supportsWritableId, ? } $property->cardinality = CardinalitiesExtractor::CARDINALITY_1_1; - $property->ormColumn = null; $property->isWritable = $writable; $property->isNullable = $nullable; $property->isUnique = false; diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index fb2a0e2e..de2c83d8 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -157,7 +157,6 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->rangeName = $rangeName; $schemaProperty->type = $type; $schemaProperty->cardinality = $cardinality; - $schemaProperty->ormColumn = $propertyConfig['ormColumn'] ?? null; $schemaProperty->isReadable = $propertyConfig['readable'] ?? true; $schemaProperty->isWritable = $propertyConfig['writable'] ?? true; $schemaProperty->isNullable = $isNullable; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 56ee77cc..c9c0f115 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -17,6 +17,7 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\ConfigurationAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; +use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAssociationOverrideAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; use Symfony\Component\Config\Definition\Builder\NodeBuilder; @@ -159,6 +160,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->end() ->end() ->enumNode('inheritanceType')->defaultValue('JOINED')->values(['JOINED', 'SINGLE_TABLE', 'SINGLE_COLLECTION', 'TABLE_PER_CLASS', 'COLLECTION_PER_CLASS', 'NONE'])->info('The inheritance type to use when an entity is referenced by another and has child')->end() + ->integerNode('maxIdentifierLength')->defaultValue(63)->info('Maximum length of any given database identifier, like tables or column names')->end() ->end() ->end() ->arrayNode('validator') @@ -221,7 +223,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->children() ->booleanNode('exclude')->defaultFalse()->info('Exclude this property, even if "allProperties" is set to true"')->end() ->scalarNode('range')->defaultNull()->info('The property range')->example('Offer')->end() - ->scalarNode('relationTableName')->defaultNull()->info('The relation table name')->example('organization_member')->end() ->enumNode('cardinality')->defaultValue(CardinalitiesExtractor::CARDINALITY_UNKNOWN)->values([ CardinalitiesExtractor::CARDINALITY_0_1, CardinalitiesExtractor::CARDINALITY_0_N, @@ -232,11 +233,6 @@ public function getConfigTreeBuilder(): TreeBuilder CardinalitiesExtractor::CARDINALITY_N_N, CardinalitiesExtractor::CARDINALITY_UNKNOWN, ])->end() - ->arrayNode('ormColumn') - ->info('The doctrine column attribute content') - ->example('{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}') - ->variablePrototype()->end() - ->end() ->arrayNode('groups') ->info('Symfony Serialization Groups') ->scalarPrototype()->end() @@ -268,6 +264,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->info('Attribute generators to use') ->defaultValue([ DoctrineOrmAttributeGenerator::class, + DoctrineOrmAssociationOverrideAttributeGenerator::class, ApiPlatformCoreAttributeGenerator::class, ConstraintAttributeGenerator::class, SerializerGroupsAttributeGenerator::class, diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index be79b4cf..ebad9102 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -226,9 +226,13 @@ public function generate(array $graphs, array $config): array $attributeGenerators[] = $generator; } + $attributeAppender = new AttributeAppender($classes, $attributeGenerators); foreach ($classes as $class) { (new AnnotationsAppender($classes, $annotationGenerators, $types))($class, []); - (new AttributeAppender($classes, $attributeGenerators))($class, []); + $attributeAppender($class, []); + } + foreach ($classes as $class) { + $attributeAppender->appendLate($class); } return $classes; diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index c8dd06ab..d556b590 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -69,7 +69,7 @@ public function provideGenerateClassAttributesCases(): \Generator $class->operations = [ 'Get' => ['routeName' => 'api_about_get'], ]; - yield 'with operations' => [$class, [new Attribute('ApiResource', ['types' => ['https://schema.org/WithOperations'], 'operations' => [new Literal("new Get(routeName: 'api_about_get')")]])]]; + yield 'with operations' => [$class, [new Attribute('ApiResource', ['types' => ['https://schema.org/WithOperations'], 'operations' => [new Literal('new Get(...?:)', [['routeName' => 'api_about_get']])]])]]; $class = new SchemaClass('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); $class->operations = [ diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index d386c356..2c1c2be6 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -138,7 +138,7 @@ public function testGenerateClassAttributes(): void $this->assertEquals([new Attribute('MongoDB\Document')], $this->generator->generateClassAttributes($this->classMap['Car'])); } - public function testGenerateFieldAttributes(): void + public function testGeneratePropertyAttributes(): void { $this->assertEquals( [new Attribute('MongoDB\Id', ['strategy' => 'INCREMENT'])], diff --git a/tests/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGeneratorTest.php new file mode 100644 index 00000000..072cc266 --- /dev/null +++ b/tests/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGeneratorTest.php @@ -0,0 +1,101 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; + +use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAssociationOverrideAttributeGenerator; +use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\PhpTypeConverter; +use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; +use EasyRdf\Graph as RdfGraph; +use EasyRdf\Resource as RdfResource; +use Nette\PhpGenerator\Literal; +use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Processor; +use Symfony\Component\String\Inflector\EnglishInflector; + +class DoctrineOrmAssociationOverrideAttributeGeneratorTest extends TestCase +{ + private DoctrineOrmAssociationOverrideAttributeGenerator $generator; + + private array $classMap = []; + + protected function setUp(): void + { + $graph = new RdfGraph(); + + $thing = new SchemaClass('Thing', new RdfResource('https://schema.org/Thing', $graph)); + $thing->isAbstract = true; + $thing->hasChild = true; + $imageProperty = new Property('image'); + $imageProperty->addAttribute(new Attribute('ORM\JoinTable', ['name' => 'thing_image'])); + $imageProperty->addAttribute(new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true])); + $thing->addProperty($imageProperty); + $this->classMap[$thing->name()] = $thing; + + $creativeWork = new SchemaClass('CreativeWork', new RdfResource('https://schema.org/CreativeWork', $graph), 'Thing'); + $creativeWork->hasChild = true; + $this->classMap[$creativeWork->name()] = $creativeWork; + + $article = new SchemaClass('Article', new RdfResource('htts://schema.org/Article', $graph), 'CreativeWork'); + $article->hasChild = true; + $article->isAbstract = true; + $speakableProperty = new Property('speakable'); + $speakableProperty->addAttribute(new Attribute('ORM\JoinTable', ['name' => 'article_speakable'])); + $speakableProperty->addAttribute(new Attribute('ORM\JoinColumn', ['nullable' => false])); + $article->addProperty($speakableProperty); + $this->classMap[$article->name()] = $article; + + $newsArticle = new SchemaClass('NewsArticle', new RdfResource('https://schema.org/NewsArticle', $graph), 'Article'); + $newsArticle->hasChild = true; + $newsArticle->isAbstract = true; + $printSectionProperty = new Property('printSection'); + $printSectionProperty->addAttribute(new Attribute('ORM\JoinTable', ['name' => 'news_article_print_section'])); + $newsArticle->addProperty($printSectionProperty); + $this->classMap[$newsArticle->name()] = $newsArticle; + + $opinionNewsArticle = new SchemaClass('OpinionNewsArticle', new RdfResource('https://schema.org/OpinionNewsArticle', $graph), 'NewsArticle'); + $this->classMap[$opinionNewsArticle->name()] = $opinionNewsArticle; + + $configuration = new SchemaGeneratorConfiguration(); + /** @var Configuration $processedConfiguration */ + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ + 'doctrine' => [ + 'maxIdentifierLength' => 40, + ], + ]]); + + $this->generator = new DoctrineOrmAssociationOverrideAttributeGenerator( + new PhpTypeConverter(), + new EnglishInflector(), + $processedConfiguration, + $this->classMap + ); + } + + public function testGenerateLateClassAttributes(): void + { + $this->assertEquals([new Attribute('ORM\AssociationOverrides', [[ + new Literal("new ORM\AssociationOverride(...?:)", [['name' => 'printSection', 'joinTable' => new Literal('new ORM\JoinTable(...?:)', [['name' => 'join_table_9aff121e']]), 'joinColumns' => [new Literal('new ORM\JoinColumn(...?:)', [[]])], 'inverseJoinColumns' => [new Literal('new ORM\InverseJoinColumn(...?:)', [[]])]]]), + new Literal("new ORM\AssociationOverride(...?:)", [['name' => 'speakable', 'joinTable' => new Literal('new ORM\JoinTable(...?:)', [['name' => 'article_speakable_opinion_news_article']]), 'joinColumns' => [new Literal('new ORM\JoinColumn(...?:)', [['nullable' => false]])], 'inverseJoinColumns' => [new Literal('new ORM\InverseJoinColumn(...?:)', [[]])]]]), + ]])], $this->generator->generateLateClassAttributes($this->classMap['OpinionNewsArticle'])); + $this->assertEquals([new Attribute('ORM\AssociationOverrides', [[ + new Literal("new ORM\AssociationOverride(...?:)", [['name' => 'image', 'joinTable' => new Literal('new ORM\JoinTable(...?:)', [['name' => 'thing_image_creative_work']]), 'joinColumns' => [new Literal('new ORM\JoinColumn(...?:)', [[]])], 'inverseJoinColumns' => [new Literal('new ORM\InverseJoinColumn(...?:)', [['nullable' => false, 'unique' => true]])]]]), + ]])], $this->generator->generateLateClassAttributes($this->classMap['CreativeWork'])); + $this->assertEquals([], $this->generator->generateLateClassAttributes($this->classMap['Thing'])); + $this->assertEquals([], $this->generator->generateLateClassAttributes($this->classMap['Article'])); + $this->assertEquals([], $this->generator->generateLateClassAttributes($this->classMap['NewsArticle'])); + } +} diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index d30efa77..be721441 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -185,7 +185,7 @@ public function testGenerateClassAttributes(): void $this->assertEquals([new Attribute('ORM\Embeddable')], $this->generator->generateClassAttributes($this->classMap['QuantitativeValue'])); } - public function testGenerateFieldAttributes(): void + public function testGeneratePropertyAttributes(): void { $this->assertEquals( [new Attribute('ORM\Id'), new Attribute('ORM\Column', ['type' => 'integer'])], @@ -224,15 +224,15 @@ public function testGenerateFieldAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_1'), 'Vehicle') ); $this->assertEquals( - [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\InverseJoinColumn', ['unique' => true])], + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_quantitative_value_relation0_n']), new Attribute('ORM\InverseJoinColumn', ['unique' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation0_N'), 'Vehicle') ); $this->assertEquals( - [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true])], + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_quantitative_value_relation1_n']), new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N'), 'Vehicle') ); $this->assertEquals( - [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue'])], + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_quantitative_value_relation_nn'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle') ); } diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index ccbcf376..6f78d3f6 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -126,7 +126,6 @@ public function provideInvokeTestCases(): \Generator $expectedGivenNameProperty->type = 'string'; $expectedGivenNameProperty->isNullable = true; $expectedGivenNameProperty->isRequired = true; - $expectedGivenNameProperty->ormColumn = []; yield 'with configuration' => [clone $person, (clone $person)->addProperty($expectedGivenNameProperty), $graph]; } } diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 8692f3f3..10accbf5 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -136,6 +136,9 @@ interface: App\Model # Example: App\Model # The inheritance type to use when an entity is referenced by another and has child inheritanceType: JOINED # One of "JOINED"; "SINGLE_TABLE"; "SINGLE_COLLECTION"; "TABLE_PER_CLASS"; "COLLECTION_PER_CLASS"; "NONE" + # Maximum length of any given database identifier, like tables or column names + maxIdentifierLength: 63 + # Symfony Validator Component validator: @@ -217,14 +220,8 @@ interface: null # The property range range: null # Example: Offer - - # The relation table name - relationTableName: null # Example: organization_member cardinality: unknown # One of "(0..1)"; "(0..*)"; "(1..1)"; "(1..*)"; "(*..0)"; "(*..1)"; "(*..*)"; "unknown" - # The doctrine column attribute content - ormColumn: [] # Example: '{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}' - # Symfony Serialization Groups groups: [] @@ -269,6 +266,7 @@ interface: null # Defaults: - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator + - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAssociationOverrideAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator diff --git a/tests/config/address-book.yaml b/tests/config/address-book.yaml index 86d2d773..df61c20a 100644 --- a/tests/config/address-book.yaml +++ b/tests/config/address-book.yaml @@ -12,15 +12,14 @@ types: gender: ~ address: { range: PostalAddress } # Custom range and custom ORM\Column content - birthDate: { range: DateTime, ormColumn: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } + birthDate: { range: DateTime, attributes: { ORM\Column: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } } telephone: ~ email: ~ jobTitle: ~ - # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ - brand: { relationTableName: "person_brand"} - memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof" } - worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor" } + brand: { attributes: { ORM\JoinTable: { name: "person_brand" } } } + memberOf: { range: "Organization", cardinality: (1..*), attributes: { ORM\JoinTable: { name: "person_memberof" } } } + worksFor: { range: "Organization", cardinality: (0..*), attributes: { ORM\JoinTable: { name: "person_worksfor" } } } # url field is a custom one without definition, it should render error url: ~ friends: { range: "Person", cardinality: (0..*) } @@ -37,4 +36,4 @@ types: properties: name: ~ # Custom property with custom ORM\Column content - adminCode: { range: https://schema.org/Text, ormColumn: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } + adminCode: { range: https://schema.org/Text, attributes: { ORM\Column: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } } diff --git a/tests/config/fluent-mutators.yaml b/tests/config/fluent-mutators.yaml index 5a162430..36b435f7 100644 --- a/tests/config/fluent-mutators.yaml +++ b/tests/config/fluent-mutators.yaml @@ -9,15 +9,14 @@ types: gender: ~ address: { range: PostalAddress } # Custom range and custom ORM\Column content - birthDate: { range: DateTime, ormColumn: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } + birthDate: { range: DateTime, attributes: { ORM\Column: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } } telephone: ~ email: ~ jobTitle: ~ - # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ - brand: { relationTableName: "person_brand"} - memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof" } - worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor" } + brand: { attributes: { ORM\JoinTable: { name: "person_brand" } } } + memberOf: { range: "Organization", cardinality: (1..*), attributes: { ORM\JoinTable: { name: "person_memberof" } } } + worksFor: { range: "Organization", cardinality: (0..*), attributes: { ORM\JoinTable: { name: "person_worksfor" } } } # url field is a custom one without definition, it should render error url: ~ friends: { range: "Person", cardinality: (0..*) } @@ -34,4 +33,4 @@ types: properties: name: ~ # Custom property with custom ORM\Column content - adminCode: { range: https://schema.org/Text, ormColumn: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } + adminCode: { range: https://schema.org/Text, attributes: { ORM\Column: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } } diff --git a/tests/config/mongodb/address-book.yaml b/tests/config/mongodb/address-book.yaml index fabde6fc..89c3a46a 100644 --- a/tests/config/mongodb/address-book.yaml +++ b/tests/config/mongodb/address-book.yaml @@ -22,11 +22,10 @@ types: telephone: ~ email: ~ jobTitle: ~ - # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ - brand: { relationTableName: "person_brand"} - memberOf: { range: "https://schema.org/Organization", cardinality: (1..*), relationTableName: "person_memberof"} - worksFor: { range: "https://schema.org/Organization", cardinality: (0..*), relationTableName: "person_worksfor"} + brand: ~ + memberOf: { range: "https://schema.org/Organization", cardinality: (1..*) } + worksFor: { range: "https://schema.org/Organization", cardinality: (0..*) } # url field is a custom one without definition, it should render error url: ~ friends: { range: "https://schema.org/Person", cardinality: (0..*) } diff --git a/tests/config/public-properties.yaml b/tests/config/public-properties.yaml index 00022979..fb5cfd40 100644 --- a/tests/config/public-properties.yaml +++ b/tests/config/public-properties.yaml @@ -10,15 +10,14 @@ types: gender: ~ address: { range: PostalAddress } # Custom range and custom ORM\Column content - birthDate: { range: DateTime, ormColumn: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } + birthDate: { range: DateTime, attributes: { ORM\Column: { type: "datetimetz", nullable: true, options: { comment: "Birthdate with timezone." } } } } telephone: ~ email: ~ jobTitle: ~ - # Default relation table name would be "person_organization" for all following fields, but we customize them affiliation: ~ - brand: { relationTableName: "person_brand"} - memberOf: { range: "Organization", cardinality: (1..*), relationTableName: "person_memberof" } - worksFor: { range: "Organization", cardinality: (0..*), relationTableName: "person_worksfor" } + brand: { attributes: { ORM\JoinTable: { name: "person_brand" } } } + memberOf: { range: "Organization", cardinality: (1..*), attributes: { ORM\JoinTable: { name: "person_memberof" } } } + worksFor: { range: "Organization", cardinality: (0..*), attributes: { ORM\JoinTable: { name: "person_worksfor" } } } # url field is a custom one without definition, it should render error url: ~ friends: { range: "Person", cardinality: (0..*) } @@ -35,4 +34,4 @@ types: properties: name: ~ # Custom property with custom ORM\Column content - adminCode: { range: https://schema.org/Text, ormColumn: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } + adminCode: { range: https://schema.org/Text, attributes: { ORM\Column: { type: "string", length: 3, unique: true, nullable: false, options: { comment: "A code for central administration." } } } } diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index f4d74c16..966aa41f 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -139,6 +139,7 @@ class Person extends MyCustomClass implements MyCustomInterface * @see https://schema.org/siblings */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] + #[ORM\JoinTable(name: 'person_person_siblings')] #[ORM\InverseJoinColumn(unique: true)] #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; @@ -155,9 +156,8 @@ class Person extends MyCustomClass implements MyCustomInterface private Thing $knowsAbout; /** @see _:customColumn */ - #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] - #[Assert\NotNull] - private Person $customColumn; + #[ORM\Column(type: 'decimal', nullable: true, precision: 5, scale: 1, options: ['comment' => 'my comment'])] + private ?string $customColumn = null; public function __construct() { @@ -287,12 +287,12 @@ public function getKnowsAbout(): Thing return $this->knowsAbout; } - public function setCustomColumn(Person $customColumn): void + public function setCustomColumn(?string $customColumn): void { $this->customColumn = $customColumn; } - public function getCustomColumn(): Person + public function getCustomColumn(): ?string { return $this->customColumn; } diff --git a/tests/e2e/original/App/OpenApi/Entity/Book.php b/tests/e2e/original/App/OpenApi/Entity/Book.php index 06786d7e..218ecc53 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Book.php +++ b/tests/e2e/original/App/OpenApi/Entity/Book.php @@ -88,6 +88,7 @@ class Book * @see https://schema.org/reviews */ #[ORM\OneToMany(targetEntity: 'App\OpenApi\Entity\Review', mappedBy: 'book')] + #[ORM\JoinTable(name: 'book_review_reviews')] #[ORM\InverseJoinColumn(nullable: false, unique: true)] #[ApiProperty(types: ['https://schema.org/reviews'])] #[Assert\NotNull] diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index d922a66a..dd49a518 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -130,6 +130,7 @@ class Person extends Thing * @see https://schema.org/siblings */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] + #[ORM\JoinTable(name: 'person_person_siblings')] #[ORM\InverseJoinColumn(unique: true)] #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; @@ -148,9 +149,8 @@ class Person extends Thing /** * @see _:customColumn */ - #[ORM\Column(type: 'decimal', precision: 5, scale: 1, options: ['comment' => 'my comment'])] - #[Assert\NotNull] - private Person $customColumn; + #[ORM\Column(type: 'decimal', nullable: true, precision: 5, scale: 1, options: ['comment' => 'my comment'])] + private ?string $customColumn = null; public function __construct() { @@ -275,12 +275,12 @@ public function getKnowsAbout(): Thing return $this->knowsAbout; } - public function setCustomColumn(Person $customColumn): void + public function setCustomColumn(?string $customColumn): void { $this->customColumn = $customColumn; } - public function getCustomColumn(): Person + public function getCustomColumn(): ?string { return $this->customColumn; } diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 107688b7..e7496884 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -35,7 +35,7 @@ types: url: ~ siblings: { cardinality: "(0..*)" } knowsAbout: { range: https://schema.org/Thing } - customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} } + customColumn: { range: https://schema.org/Text, attributes: { ORM\Column: { type: "decimal", precision: 5, scale: 1, options: { comment: "my comment" } } } } Brand: properties: name: ~ From 1febaf080c2d814d8e0f7d60cec08715761205bb Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 7 Jul 2022 19:21:14 +0200 Subject: [PATCH 223/258] fix: various range issues (#386) --- .../PhpDocAnnotationGenerator.php | 4 +- src/PhpTypeConverter.php | 16 +++--- .../PropertyGenerator/PropertyGenerator.php | 7 ++- .../PhpDocAnnotationGeneratorTest.php | 51 ++++++++++++++++++- tests/TypesGeneratorTest.php | 20 ++++++++ 5 files changed, 81 insertions(+), 17 deletions(-) diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index 5462f746..2924cf95 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -76,8 +76,8 @@ public function generatePropertyAnnotations(Property $property, string $classNam $description = $this->formatDoc((string) $property->description(), true); $annotations = []; - if ($this->isDocUseful($property)) { - $annotations[] = sprintf('@var %s %s', $this->toPhpDocType($property), $this->escapePhpDoc($description[0])); + if ($this->isDocUseful($property) && $phpDocType = $this->toPhpDocType($property)) { + $annotations[] = sprintf('@var %s %s', $phpDocType, $this->escapePhpDoc($description[0])); } else { $annotations = $description; $annotations[] = ''; diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index 340d2a21..68cbbfa3 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -16,25 +16,21 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; -use ApiPlatform\SchemaGenerator\Schema\TypeConverter; final class PhpTypeConverter implements PhpTypeConverterInterface { - private TypeConverter $typeConverter; - - public function __construct() - { - $this->typeConverter = new TypeConverter(); - } - public function getPhpType(Property $property, array $config = [], array $classes = []): ?string { if (!$property instanceof SchemaProperty) { throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); } - if ($property->isArray && $property->range) { - return ($config['doctrine']['useCollection'] ?? false) && !$this->typeConverter->getType($property->range) ? 'Collection' : 'array'; + if ($property->isArray && $property->reference) { + return ($config['doctrine']['useCollection'] ?? false) ? 'Collection' : 'array'; + } + + if ($property->isArray) { + return 'array'; } return $this->getNonArrayType($property, $classes); diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index de2c83d8..bdf73257 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -181,8 +181,7 @@ private function getRanges(RdfResource $range, ?array $propertyConfig, array $co { $localName = $range->localName(); $dataType = (bool) $this->typeConverter->getType($range); - $ranges = []; - if (!$dataType && $range->isBNode()) { + if (!$dataType) { if (null !== ($unionOf = $range->get('owl:unionOf'))) { return $this->getRanges($unionOf, $propertyConfig, $config); } @@ -192,9 +191,9 @@ private function getRanges(RdfResource $range, ?array $propertyConfig, array $co if (null !== ($rdfRest = $range->get('rdf:rest'))) { $ranges = array_merge($ranges, $this->getRanges($rdfRest, $propertyConfig, $config)); } - } - return $ranges; + return $ranges; + } } if ( diff --git a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php index 6d85ee22..5c262729 100644 --- a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php @@ -16,11 +16,15 @@ use ApiPlatform\SchemaGenerator\AnnotationGenerator\PhpDocAnnotationGenerator; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Interface_; +use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; +use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Definition\Processor; use Symfony\Component\String\Inflector\EnglishInflector; class PhpDocAnnotationGeneratorTest extends TestCase @@ -29,10 +33,15 @@ class PhpDocAnnotationGeneratorTest extends TestCase protected function setUp(): void { + $configuration = new SchemaGeneratorConfiguration(); + $processedConfiguration = (new Processor())->processConfiguration($configuration, [[ + 'author' => 'Bill', + ]]); + $this->generator = new PhpDocAnnotationGenerator( new PhpTypeConverter(), new EnglishInflector(), - ['author' => 'Bill'], + $processedConfiguration, [], ); } @@ -54,4 +63,44 @@ public function provideGenerateClassAnnotationsCases(): \Generator $graph = new RdfGraph(); yield 'with resource' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', $graph)), ['@see https://schema.org/Res', '@author Bill']]; } + + /** + * @dataProvider provideGeneratePropertyAnnotationsCases + */ + public function testGeneratePropertyAnnotations(Property $property, string $className, array $annotations): void + { + $this->assertSame($annotations, $this->generator->generatePropertyAnnotations($property, $className)); + } + + public function provideGeneratePropertyAnnotationsCases(): \Generator + { + $property = new SchemaProperty('telephone'); + $graph = new RdfGraph(); + $resource = new RdfResource('https://schema.org/telephone', $graph); + $resource->addResource('rdfs:comment', 'The telephone number.
@number'); + $property->resource = $resource; + + yield 'property with description' => [$property, 'Place', ['The telephone **number**. ', ' \@number', '', '@see https://schema.org/telephone', '']]; + + $property = new SchemaProperty('review'); + $graph = new RdfGraph(); + $resource = new RdfResource('https://schema.org/review', $graph); + $resource->addResource('rdfs:comment', 'A review of the item.'); + $property->resource = $resource; + $property->isArray = true; + $property->typeHint = 'array'; + $property->type = 'string'; + $property->range = new RdfResource('https://schema.org/Text'); + + yield 'array of strings property' => [$property, 'Place', ['@var string[]|null A review of the item.', '@see https://schema.org/review', '']]; + + $property = new SchemaProperty('address'); + $graph = new RdfGraph(); + $property->isNullable = false; + $property->isArray = true; + $property->typeHint = 'array'; + $property->reference = new SchemaClass('PostalAddress', new RdfResource('https://schema.org/PostalAddress', $graph)); + + yield 'reference property' => [$property, 'Place', ['@var Collection ', '']]; + } } diff --git a/tests/TypesGeneratorTest.php b/tests/TypesGeneratorTest.php index 0be943e8..beb07316 100644 --- a/tests/TypesGeneratorTest.php +++ b/tests/TypesGeneratorTest.php @@ -176,6 +176,8 @@ public function testGenerateAllResolveTypes(): void $competencyWorldEntity = file_get_contents("$this->outputDir/App/Entity/CompetencyWorldEntity.php"); $this->assertStringContainsString('class CompetencyWorldEntity extends Thing', $competencyWorldEntity); $this->assertStringContainsString('private ?string $hasAppellation = null;', $competencyWorldEntity); + $this->assertStringContainsString('private ?string $hasDescription = null;', $competencyWorldEntity); + $this->assertStringContainsString('private array $intendedOccupation = [];', $competencyWorldEntity); $this->assertStringContainsString('public function setHasAppellation(?string $hasAppellation): void', $competencyWorldEntity); $this->assertStringContainsString('public function getHasAppellation(): ?string', $competencyWorldEntity); } @@ -239,6 +241,23 @@ private function getGraphs(): array $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'); $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasAppellation', 'schema:rangeIncludes', 'https://schema.org/Text'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasDescription', 'rdf:type', 'rdf:Property'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasDescription', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/hasDescription', 'schema:rangeIncludes', 'https://gitlab.com/mmorg/nodefr-2/n3-5'); + + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-5', 'rdf:type', 'rdfs:Class'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-5', 'owl:unionOf', 'https://gitlab.com/mmorg/nodefr-2/n3-6'); + + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-6', 'rdf:first', 'http://www.w3.org/2001/XMLSchema#language'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-6', 'rdf:rest', 'https://gitlab.com/mmorg/nodefr-2/n3-7'); + + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-7', 'rdf:first', 'http://www.w3.org/2001/XMLSchema#string'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/n3-7', 'rdf:rest', 'http://www.w3.org/1999/02/22-rdf-syntax-ns#langString'); + + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/intendedOccupation', 'rdf:type', 'rdf:Property'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/intendedOccupation', 'schema:domainIncludes', 'https://gitlab.com/mmorg/nodefr-2/CompetencyWorldEntity'); + $nodeGraph->addResource('https://gitlab.com/mmorg/nodefr-2/intendedOccupation', 'schema:rangeIncludes', 'https://gitlab.com/mmorg/nodefr-2/specialCase'); + $graph = new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI); $graph->addResource('https://schema.org/Article', 'rdf:type', 'rdfs:Class'); @@ -397,6 +416,7 @@ private function getAllResolveTypesConfig(): array ], 'attributeGenerators' => [ ], + 'relations' => ['defaultCardinality' => '(1..*)'], 'allTypes' => true, 'resolveTypes' => true, ]; From 52ca83549dbba5cb60aa99b2a40025b52ec629cf Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Fri, 8 Jul 2022 18:25:52 +0200 Subject: [PATCH 224/258] fix: remove columnPrefix (replaced by attributes) (#387) --- phpstan.neon | 1 - .../DoctrineOrmAttributeGenerator.php | 2 +- src/Model/Property.php | 2 -- src/Schema/PropertyGenerator/PropertyGenerator.php | 10 +--------- src/SchemaGeneratorConfiguration.php | 1 - .../DoctrineOrmAttributeGeneratorTest.php | 3 +-- tests/Command/DumpConfigurationTest.php | 3 --- 7 files changed, 3 insertions(+), 19 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index dd18a773..b343dcd8 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -17,7 +17,6 @@ parameters: required: ?boolean, unique: boolean, embedded: boolean, - columnPrefix: false|string, attributes: array } ''' diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 3d9978a4..04a3dd68 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -178,7 +178,7 @@ public function generatePropertyAttributes(Property $property, string $className } if ($property->isEmbedded) { - return [new Attribute('ORM\Embedded', ['class' => $relationName, 'columnPrefix' => $property->columnPrefix])]; + return [new Attribute('ORM\Embedded', ['class' => $relationName])]; } $relationTableName = $this->generateIdentifierName($className.ucfirst($property->reference->name()).ucfirst($property->name()), 'join_table', $this->config); diff --git a/src/Model/Property.php b/src/Model/Property.php index ca956151..865ab646 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -41,8 +41,6 @@ abstract class Property public bool $isEmbedded = false; public ?string $mappedBy = null; public ?string $inversedBy = null; - /** @var string|bool */ - public $columnPrefix = false; public bool $isId = false; public ?string $typeHint = null; public bool $isEnum = false; diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index bdf73257..efa3a252 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -145,13 +145,6 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont CardinalitiesExtractor::CARDINALITY_1_N, ], true)); - $columnPrefix = false; - $isEmbedded = $propertyConfig['embedded'] ?? false; - - if (true === $isEmbedded) { - $columnPrefix = $propertyConfig['columnPrefix'] ?? false; - } - $schemaProperty->resource = $typeProperty; $schemaProperty->range = $range; $schemaProperty->rangeName = $rangeName; @@ -162,8 +155,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->isNullable = $isNullable; $schemaProperty->isRequired = $propertyConfig['required'] ?? false; $schemaProperty->isUnique = $propertyConfig['unique'] ?? false; - $schemaProperty->isEmbedded = $isEmbedded; - $schemaProperty->columnPrefix = $columnPrefix; + $schemaProperty->isEmbedded = $propertyConfig['embedded'] ?? false; $schemaProperty->mappedBy = $propertyConfig['mappedBy'] ?? null; $schemaProperty->inversedBy = $propertyConfig['inversedBy'] ?? null; $schemaProperty->groups = $propertyConfig['groups'] ?? []; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index c9c0f115..b64599bd 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -245,7 +245,6 @@ public function getConfigTreeBuilder(): TreeBuilder ->booleanNode('required')->defaultTrue()->info('Is the property required?')->end() ->booleanNode('unique')->defaultFalse()->info('The property unique')->end() ->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end() - ->scalarNode('columnPrefix')->defaultFalse()->info('The property columnPrefix')->end() ->append($attributesNode()) ->end() ->end() diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index be721441..ee11e86b 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -82,7 +82,6 @@ protected function setUp(): void $weightProperty->type = 'nonPositiveInteger'; $vehicle->addProperty($weightProperty); $prefixedWeightProperty = new Property('prefixedWeight'); - $prefixedWeightProperty->columnPrefix = 'weight_'; $prefixedWeightProperty->isEmbedded = true; $prefixedWeightProperty->rangeName = 'QuantitativeValue'; $prefixedWeightProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); @@ -204,7 +203,7 @@ public function testGeneratePropertyAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('weight'), 'Vehicle') ); $this->assertEquals( - [new Attribute('ORM\Embedded', ['class' => 'App\Entity\QuantitativeValue', 'columnPrefix' => 'weight_'])], + [new Attribute('ORM\Embedded', ['class' => 'App\Entity\QuantitativeValue'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('prefixedWeight'), 'Vehicle') ); $this->assertEquals( diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 10accbf5..d02e41ec 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -249,9 +249,6 @@ interface: null # Is the property embedded? embedded: false - # The property columnPrefix - columnPrefix: false - # Attributes (merged with generated attributes) attributes: [] From 09324b947ea9de2cd130f4596ad3d7b3cdbd2a54 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Fri, 8 Jul 2022 18:37:56 +0200 Subject: [PATCH 225/258] fix: remove SerializerGroupsAttributeGenerator (replaced by attributes) (#388) --- .../SerializerGroupsAttributeGenerator.php | 51 ------------------- src/SchemaGeneratorConfiguration.php | 2 - .../SerializerGroupAttributeGeneratorTest.php | 45 ---------------- tests/Command/DumpConfigurationTest.php | 1 - .../customized/App/Schema/Entity/Person.php | 2 - .../e2e/original/App/Schema/Entity/Person.php | 2 - tests/e2e/schema.yml | 2 +- 7 files changed, 1 insertion(+), 104 deletions(-) delete mode 100644 src/AttributeGenerator/SerializerGroupsAttributeGenerator.php delete mode 100644 tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php diff --git a/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php b/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php deleted file mode 100644 index aa3c4817..00000000 --- a/src/AttributeGenerator/SerializerGroupsAttributeGenerator.php +++ /dev/null @@ -1,51 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace ApiPlatform\SchemaGenerator\AttributeGenerator; - -use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\Model\Class_; -use ApiPlatform\SchemaGenerator\Model\Property; -use ApiPlatform\SchemaGenerator\Model\Use_; -use Symfony\Component\Serializer\Annotation\Groups; - -/** - * Symfony Serializer Groups attribute generator. - * - * @author Youssef El Montaser - * @author Kévin Dunglas - * - * @see https://symfony.com/doc/master/components/serializer.html - */ -final class SerializerGroupsAttributeGenerator extends AbstractAttributeGenerator -{ - /** - * {@inheritdoc} - */ - public function generatePropertyAttributes(Property $property, string $className): array - { - if (false === $property->isId && $property->groups) { - return [new Attribute('Groups', [$property->groups])]; - } - - return []; - } - - /** - * {@inheritdoc} - */ - public function generateUses(Class_ $class): array - { - return [new Use_(Groups::class)]; - } -} diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index b64599bd..9eafd762 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -19,7 +19,6 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAssociationOverrideAttributeGenerator; use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; -use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; use Symfony\Component\Config\Definition\Builder\NodeBuilder; use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; @@ -266,7 +265,6 @@ public function getConfigTreeBuilder(): TreeBuilder DoctrineOrmAssociationOverrideAttributeGenerator::class, ApiPlatformCoreAttributeGenerator::class, ConstraintAttributeGenerator::class, - SerializerGroupsAttributeGenerator::class, // Configuration attribute generator needs to be last to merge its attributes with previously generated ones. ConfigurationAttributeGenerator::class, ]) diff --git a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php b/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php deleted file mode 100644 index 9e527b10..00000000 --- a/tests/AttributeGenerator/SerializerGroupAttributeGeneratorTest.php +++ /dev/null @@ -1,45 +0,0 @@ - - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -declare(strict_types=1); - -namespace ApiPlatform\SchemaGenerator\Tests\AttributeGenerator; - -use ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator; -use ApiPlatform\SchemaGenerator\Model\Attribute; -use ApiPlatform\SchemaGenerator\PhpTypeConverter; -use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; -use PHPUnit\Framework\TestCase; -use Symfony\Component\String\Inflector\EnglishInflector; - -class SerializerGroupAttributeGeneratorTest extends TestCase -{ - private SerializerGroupsAttributeGenerator $generator; - - protected function setUp(): void - { - $this->generator = new SerializerGroupsAttributeGenerator( - new PhpTypeConverter(), - new EnglishInflector(), - [], - [], - ); - } - - public function testGeneratePropertyAttributes(): void - { - $property = new SchemaProperty('prop'); - $property->isId = false; - $property->groups = ['group']; - - $this->assertEquals([new Attribute('Groups', [['group']])], $this->generator->generatePropertyAttributes($property, 'Res')); - } -} diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index d02e41ec..fe0e5039 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -266,7 +266,6 @@ interface: null - ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAssociationOverrideAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\ApiPlatformCoreAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator - - ApiPlatform\SchemaGenerator\AttributeGenerator\SerializerGroupsAttributeGenerator - ApiPlatform\SchemaGenerator\AttributeGenerator\ConfigurationAttributeGenerator # Directories for custom generator twig templates diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 966aa41f..49206e67 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -17,7 +17,6 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; -use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; /** @@ -69,7 +68,6 @@ class Person extends MyCustomClass implements MyCustomInterface */ #[ORM\Column(type: 'text', nullable: true)] #[ApiProperty(types: ['https://schema.org/additionalName'])] - #[Groups(['extra'])] private ?string $additionalName = null; /** diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index dd49a518..a254e017 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -14,7 +14,6 @@ use Doctrine\Common\Collections\Collection; use Doctrine\ORM\Mapping as ORM; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; -use Symfony\Component\Serializer\Annotation\Groups; use Symfony\Component\Validator\Constraints as Assert; /** @@ -60,7 +59,6 @@ class Person extends Thing */ #[ORM\Column(type: 'text', nullable: true)] #[ApiProperty(types: ['https://schema.org/additionalName'])] - #[Groups(['extra'])] private ?string $additionalName = null; /** diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index e7496884..74a0aa77 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -26,7 +26,7 @@ types: properties: familyName: ~ givenName: ~ - additionalName: { groups: ['extra'] } + additionalName: ~ gender: { range: https://schema.org/GenderType } address: { range: https://schema.org/PostalAddress } birthDate: ~ From 7da2132758cd7e322eec547e1e1af1559eea35ab Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 1 Sep 2022 16:57:16 +0200 Subject: [PATCH 226/258] fix: self-referencing relations (#390) Self-referencing relations needs to use another name for the inverse join column than the default one. --- .../DoctrineMongoDBAttributeGenerator.php | 1 + .../DoctrineOrmAttributeGenerator.php | 24 +++++++++++++------ src/OpenApi/ClassGenerator.php | 1 + src/OpenApi/ClassMutator/EnumClassMutator.php | 1 + .../PropertyGenerator/PropertyGenerator.php | 1 + .../ApiPlatformCoreAttributeGeneratorTest.php | 2 +- .../DoctrineOrmAttributeGeneratorTest.php | 11 +++++++++ tests/Command/DumpConfigurationTest.php | 2 +- .../ExtractCardinalitiesCommandTest.php | 2 +- tests/Command/GenerateCommandTest.php | 14 +++++------ .../customized/App/Schema/Entity/Person.php | 2 +- .../e2e/original/App/Schema/Entity/Person.php | 2 +- 12 files changed, 44 insertions(+), 19 deletions(-) diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index 4a4e9d36..981067d6 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -19,6 +19,7 @@ use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; use Nette\PhpGenerator\Literal; + use function Symfony\Component\String\u; /** diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 04a3dd68..3fc2eddc 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -19,6 +19,7 @@ use ApiPlatform\SchemaGenerator\Model\Property; use ApiPlatform\SchemaGenerator\Model\Use_; use Nette\PhpGenerator\Literal; + use function Symfony\Component\String\u; /** @@ -125,8 +126,7 @@ public function generatePropertyAttributes(Property $property, string $className case 'bool': $type = 'boolean'; break; - // TODO: use more precise types for int (smallint, bigint...) - case 'int': + case 'int': // TODO: use more precise types for int (smallint, bigint...) $type = 'integer'; break; case 'string': @@ -215,7 +215,12 @@ public function generatePropertyAttributes(Property $property, string $className $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); } $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); - $attributes[] = new Attribute('ORM\InverseJoinColumn', ['unique' => true]); + // Self-referencing relation + if ($className === $property->reference->name()) { + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['name' => $this->generateIdentifierName($this->inflector->singularize($property->name())[0].ucfirst($property->reference->name()).'Id', 'inverse_join_column', $this->config)]); + } else { + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['unique' => true]); + } break; case CardinalitiesExtractor::CARDINALITY_1_N: if (null !== $property->mappedBy) { @@ -224,7 +229,12 @@ public function generatePropertyAttributes(Property $property, string $className $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); } $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); - $attributes[] = new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true]); + // Self-referencing relation + if ($className === $property->reference->name()) { + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['name' => $this->generateIdentifierName($this->inflector->singularize($property->name())[0].ucfirst($property->reference->name()).'Id', 'inverse_join_column', $this->config), 'nullable' => false]); + } else { + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true]); + } break; case CardinalitiesExtractor::CARDINALITY_N_N: $attributes[] = new Attribute('ORM\ManyToMany', ['targetEntity' => $relationName]); @@ -256,13 +266,13 @@ private function generateIdAttributes(): array switch ($this->config['id']['generationStrategy']) { case 'uuid': $type = 'guid'; - break; + break; case 'auto': $type = 'integer'; - break; + break; default: $type = 'string'; - break; + break; } $attributes[] = new Attribute('ORM\Column', ['type' => $type]); diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index f3e31458..62008fc5 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -34,6 +34,7 @@ use Doctrine\Common\Collections\Collection; use Psr\Log\LoggerAwareTrait; use Symfony\Component\String\Inflector\InflectorInterface; + use function Symfony\Component\String\u; final class ClassGenerator diff --git a/src/OpenApi/ClassMutator/EnumClassMutator.php b/src/OpenApi/ClassMutator/EnumClassMutator.php index b862dff3..caf45d90 100644 --- a/src/OpenApi/ClassMutator/EnumClassMutator.php +++ b/src/OpenApi/ClassMutator/EnumClassMutator.php @@ -17,6 +17,7 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\OpenApi\Model\Constant as OpenApiConstant; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; + use function Symfony\Component\String\u; final class EnumClassMutator extends BaseEnumClassMutator diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index 9dac3e44..1eae587f 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -19,6 +19,7 @@ use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator as CommonPropertyGenerator; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; use cebe\openapi\spec\Schema; + use function Symfony\Component\String\u; final class PropertyGenerator implements PropertyGeneratorInterface diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index d556b590..0f46ca1b 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -87,7 +87,7 @@ public function provideGenerateClassAttributesCases(): \Generator $class = new SchemaClass('Enum', $resource); yield 'enum' => [$class, []]; - yield 'with short name' => [(new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph()))), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'types' => ['https://schema.org/DifferentLocalName']])]]; + yield 'with short name' => [new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph())), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'types' => ['https://schema.org/DifferentLocalName']])]]; } /** diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index ee11e86b..8cb93aa7 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -130,6 +130,13 @@ protected function setUp(): void $relation1NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; $relation1NProperty->isArray = true; $vehicle->addProperty($relation1NProperty); + $relation1NSelfReferencingProperty = new Property('relation1_N_self_referencing'); + $relation1NSelfReferencingProperty->rangeName = 'Vehicle'; + $relation1NSelfReferencingProperty->range = new RdfResource('https://schema.org/Vehicle'); + $relation1NSelfReferencingProperty->reference = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); + $relation1NSelfReferencingProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; + $relation1NSelfReferencingProperty->isArray = true; + $vehicle->addProperty($relation1NSelfReferencingProperty); $relationNNProperty = new Property('relationN_N'); $relationNNProperty->rangeName = 'QuantitativeValue'; $relationNNProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); @@ -230,6 +237,10 @@ public function testGeneratePropertyAttributes(): void [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_quantitative_value_relation1_n']), new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N'), 'Vehicle') ); + $this->assertEquals( + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\Vehicle']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_vehicle_relation1_n_self_referencing']), new Attribute('ORM\InverseJoinColumn', ['name' => 'relation1_n_self_referencing_vehicle_id', 'nullable' => false])], + $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N_self_referencing'), 'Vehicle') + ); $this->assertEquals( [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\QuantitativeValue']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_quantitative_value_relation_nn'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relationN_N'), 'Vehicle') diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index fe0e5039..994df78e 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -273,7 +273,7 @@ interface: null YAML - , + , $commandTester->getDisplay() ); } diff --git a/tests/Command/ExtractCardinalitiesCommandTest.php b/tests/Command/ExtractCardinalitiesCommandTest.php index 325ac335..8ef3c115 100644 --- a/tests/Command/ExtractCardinalitiesCommandTest.php +++ b/tests/Command/ExtractCardinalitiesCommandTest.php @@ -1476,6 +1476,6 @@ public function testExtractCardinalities(): void } JSON -, $commandTester->getDisplay()); + , $commandTester->getDisplay()); } } diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index caae7740..898f9c74 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -72,7 +72,7 @@ public function getFriends(): Collection return $this->friends; } PHP - , $person); + , $person); } public function testCustomAttributes(): void @@ -106,17 +106,17 @@ public function testCustomAttributes(): void class Book { PHP - , $book); + , $book); // Attributes given as unordered map. $this->assertStringContainsString(<<<'PHP' #[ORM\OneToMany(targetEntity: 'App\Entity\Review', mappedBy: 'book', cascade: ['persist', 'remove'])] PHP - , $book); + , $book); $this->assertStringContainsString(<<<'PHP' #[ORM\OrderBy(name: 'ASC')] PHP - , $book); + , $book); } public function testFluentMutators(): void @@ -136,7 +136,7 @@ public function setUrl(?string $url): self return $this; } PHP - , $person); + , $person); $this->assertStringContainsString(<<<'PHP' public function addFriend(Person $friend): self @@ -255,7 +255,7 @@ public function getId(): ?int return $this->id; } PHP - , $person); + , $person); $this->assertStringNotContainsString('setId(', $person); } @@ -363,7 +363,7 @@ public function setId(string $id): void } PHP - , $person); + , $person); } public function testDoNotGenerateId(): void diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 49206e67..6b0106f1 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -138,7 +138,7 @@ class Person extends MyCustomClass implements MyCustomInterface */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\JoinTable(name: 'person_person_siblings')] - #[ORM\InverseJoinColumn(unique: true)] + #[ORM\InverseJoinColumn(name: 'sibling_person_id')] #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index a254e017..3f5cf8ba 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -129,7 +129,7 @@ class Person extends Thing */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\JoinTable(name: 'person_person_siblings')] - #[ORM\InverseJoinColumn(unique: true)] + #[ORM\InverseJoinColumn(name: 'sibling_person_id')] #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; From ed297c7e7c7670c23102176b22667efcaab8dcac Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 1 Sep 2022 18:22:48 +0200 Subject: [PATCH 227/258] fix: update reserved keywords (#391) --- .../DoctrineOrmAttributeGenerator.php | 13 ++----------- src/PhpTypeConverterInterface.php | 2 +- .../DoctrineOrmAttributeGeneratorTest.php | 2 +- tests/Command/GenerateCommandTest.php | 2 +- tests/e2e/original/App/OpenApi/Entity/Book.php | 2 +- tests/e2e/original/App/OpenApi/Entity/Order.php | 1 + tests/e2e/original/App/OpenApi/Entity/Parchment.php | 2 +- tests/e2e/original/App/OpenApi/Entity/TopBook.php | 4 ++-- tests/e2e/original/App/OpenApi/Entity/User.php | 3 ++- 9 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 3fc2eddc..42939fc6 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -31,16 +31,7 @@ final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator { use GenerateIdentifierNameTrait; - private const RESERVED_KEYWORDS = [ - 'add', - 'create', - 'delete', - 'group', - 'join', - 'like', - 'update', - 'to', - ]; + private const RESERVED_KEYWORDS = ['ABORT', 'ABORTSESSION', 'ABS', 'ABSOLUTE', 'ACCESS', 'ACCESSIBLE', 'ACCESS_LOCK', 'ACCOUNT', 'ACOS', 'ACOSH', 'ACTION', 'ADD', 'ADD_MONTHS', 'ADMIN', 'AFTER', 'AGGREGATE', 'ALIAS', 'ALL', 'ALLOCATE', 'ALLOW', 'ALTER', 'ALTERAND', 'AMP', 'ANALYSE', 'ANALYZE', 'AND', 'ANSIDATE', 'ANY', 'ARE', 'ARRAY', 'ARRAY_AGG', 'ARRAY_EXISTS', 'ARRAY_MAX_CARDINALITY', 'AS', 'ASC', 'ASENSITIVE', 'ASIN', 'ASINH', 'ASSERTION', 'ASSOCIATE', 'ASUTIME', 'ASYMMETRIC', 'AT', 'ATAN', 'ATAN2', 'ATANH', 'ATOMIC', 'AUDIT', 'AUTHORIZATION', 'AUX', 'AUXILIARY', 'AVE', 'AVERAGE', 'AVG', 'BACKUP', 'BEFORE', 'BEGIN', 'BEGIN_FRAME', 'BEGIN_PARTITION', 'BETWEEN', 'BIGINT', 'BINARY', 'BIT', 'BLOB', 'BOOLEAN', 'BOTH', 'BREADTH', 'BREAK', 'BROWSE', 'BT', 'BUFFERPOOL', 'BULK', 'BUT', 'BY', 'BYTE', 'BYTEINT', 'BYTES', 'CALL', 'CALLED', 'CAPTURE', 'CARDINALITY', 'CASCADE', 'CASCADED', 'CASE', 'CASESPECIFIC', 'CASE_N', 'CAST', 'CATALOG', 'CCSID', 'CD', 'CEIL', 'CEILING', 'CHANGE', 'CHAR', 'CHAR2HEXINT', 'CHARACTER', 'CHARACTERS', 'CHARACTER_LENGTH', 'CHARS', 'CHAR_LENGTH', 'CHECK', 'CHECKPOINT', 'CLASS', 'CLASSIFIER', 'CLOB', 'CLONE', 'CLOSE', 'CLUSTER', 'CLUSTERED', 'CM', 'COALESCE', 'COLLATE', 'COLLATION', 'COLLECT', 'COLLECTION', 'COLLID', 'COLUMN', 'COLUMN_VALUE', 'COMMENT', 'COMMIT', 'COMPLETION', 'COMPRESS', 'COMPUTE', 'CONCAT', 'CONCURRENTLY', 'CONDITION', 'CONNECT', 'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONSTRUCTOR', 'CONTAINS', 'CONTAINSTABLE', 'CONTENT', 'CONTINUE', 'CONVERT', 'CONVERT_TABLE_HEADER', 'COPY', 'CORR', 'CORRESPONDING', 'COS', 'COSH', 'COUNT', 'COVAR_POP', 'COVAR_SAMP', 'CREATE', 'CROSS', 'CS', 'CSUM', 'CT', 'CUBE', 'CUME_DIST', 'CURRENT', 'CURRENT_CATALOG', 'CURRENT_DATE', 'CURRENT_DEFAULT_TRANSFORM_GROUP', 'CURRENT_LC_CTYPE', 'CURRENT_PATH', 'CURRENT_ROLE', 'CURRENT_ROW', 'CURRENT_SCHEMA', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_TRANSFORM_GROUP_FOR_TYPE', 'CURRENT_USER', 'CURRVAL', 'CURSOR', 'CV', 'CYCLE', 'DATA', 'DATABASE', 'DATABASES', 'DATABLOCKSIZE', 'DATE', 'DATEFORM', 'DAY', 'DAYS', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DBCC', 'DBINFO', 'DEALLOCATE', 'DEC', 'DECFLOAT', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DEFERRABLE', 'DEFERRED', 'DEFINE', 'DEGREES', 'DEL', 'DELAYED', 'DELETE', 'DENSE_RANK', 'DENY', 'DEPTH', 'DEREF', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DESTROY', 'DESTRUCTOR', 'DETERMINISTIC', 'DIAGNOSTIC', 'DIAGNOSTICS', 'DICTIONARY', 'DISABLE', 'DISABLED', 'DISALLOW', 'DISCONNECT', 'DISK', 'DISTINCT', 'DISTINCTROW', 'DISTRIBUTED', 'DIV', 'DO', 'DOCUMENT', 'DOMAIN', 'DOUBLE', 'DROP', 'DSSIZE', 'DUAL', 'DUMP', 'DYNAMIC', 'EACH', 'ECHO', 'EDITPROC', 'ELEMENT', 'ELSE', 'ELSEIF', 'EMPTY', 'ENABLED', 'ENCLOSED', 'ENCODING', 'ENCRYPTION', 'END', 'END-EXEC', 'ENDING', 'END_FRAME', 'END_PARTITION', 'EQ', 'EQUALS', 'ERASE', 'ERRLVL', 'ERROR', 'ERRORFILES', 'ERRORTABLES', 'ESCAPE', 'ESCAPED', 'ET', 'EVERY', 'EXCEPT', 'EXCEPTION', 'EXCLUSIVE', 'EXEC', 'EXECUTE', 'EXISTS', 'EXIT', 'EXP', 'EXPLAIN', 'EXTERNAL', 'EXTRACT', 'FALLBACK', 'FALSE', 'FASTEXPORT', 'FENCED', 'FETCH', 'FIELDPROC', 'FILE', 'FILLFACTOR', 'FILTER', 'FINAL', 'FIRST', 'FIRST_VALUE', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FLOOR', 'FOR', 'FORCE', 'FOREIGN', 'FORMAT', 'FOUND', 'FRAME_ROW', 'FREE', 'FREESPACE', 'FREETEXT', 'FREETEXTTABLE', 'FREEZE', 'FROM', 'FULL', 'FULLTEXT', 'FUNCTION', 'FUSION', 'GE', 'GENERAL', 'GENERATED', 'GET', 'GIVE', 'GLOBAL', 'GO', 'GOTO', 'GRANT', 'GRAPHIC', 'GROUP', 'GROUPING', 'GROUPS', 'GT', 'HANDLER', 'HASH', 'HASHAMP', 'HASHBAKAMP', 'HASHBUCKET', 'HASHROW', 'HAVING', 'HELP', 'HIGH_PRIORITY', 'HOLD', 'HOLDLOCK', 'HOST', 'HOUR', 'HOURS', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IDENTIFIED', 'IDENTITY', 'IDENTITYCOL', 'IDENTITY_INSERT', 'IF', 'IGNORE', 'ILIKE', 'IMMEDIATE', 'IN', 'INCLUSIVE', 'INCONSISTENT', 'INCREMENT', 'INDEX', 'INDICATOR', 'INFILE', 'INHERIT', 'INITIAL', 'INITIALIZE', 'INITIALLY', 'INITIATE', 'INNER', 'INOUT', 'INPUT', 'INS', 'INSENSITIVE', 'INSERT', 'INSTEAD', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTEGERDATE', 'INTERSECT', 'INTERSECTION', 'INTERVAL', 'INTO', 'IO_AFTER_GTIDS', 'IO_BEFORE_GTIDS', 'IS', 'ISNULL', 'ISOBID', 'ISOLATION', 'ITERATE', 'JAR', 'JOIN', 'JOURNAL', 'JSON_ARRAY', 'JSON_ARRAYAGG', 'JSON_EXISTS', 'JSON_OBJECT', 'JSON_OBJECTAGG', 'JSON_QUERY', 'JSON_TABLE', 'JSON_TABLE_PRIMITIVE', 'JSON_VALUE', 'KEEP', 'KEY', 'KEYS', 'KILL', 'KURTOSIS', 'LABEL', 'LAG', 'LANGUAGE', 'LARGE', 'LAST', 'LAST_VALUE', 'LATERAL', 'LC_CTYPE', 'LE', 'LEAD', 'LEADING', 'LEAVE', 'LEFT', 'LESS', 'LEVEL', 'LIKE', 'LIKE_REGEX', 'LIMIT', 'LINEAR', 'LINENO', 'LINES', 'LISTAGG', 'LN', 'LOAD', 'LOADING', 'LOCAL', 'LOCALE', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATOR', 'LOCATORS', 'LOCK', 'LOCKING', 'LOCKMAX', 'LOCKSIZE', 'LOG', 'LOG10', 'LOGGING', 'LOGON', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOWER', 'LOW_PRIORITY', 'LT', 'MACRO', 'MAINTAINED', 'MAP', 'MASTER_BIND', 'MASTER_SSL_VERIFY_SERVER_CERT', 'MATCH', 'MATCHES', 'MATCH_NUMBER', 'MATCH_RECOGNIZE', 'MATERIALIZED', 'MAVG', 'MAX', 'MAXEXTENTS', 'MAXIMUM', 'MAXVALUE', 'MCHARACTERS', 'MDIFF', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MEMBER', 'MERGE', 'METHOD', 'MICROSECOND', 'MICROSECONDS', 'MIDDLEINT', 'MIN', 'MINDEX', 'MINIMUM', 'MINUS', 'MINUTE', 'MINUTES', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MLINREG', 'MLOAD', 'MLSLABEL', 'MOD', 'MODE', 'MODIFIES', 'MODIFY', 'MODULE', 'MONITOR', 'MONRESOURCE', 'MONSESSION', 'MONTH', 'MONTHS', 'MSUBSTR', 'MSUM', 'MULTISET', 'NAMED', 'NAMES', 'NATIONAL', 'NATURAL', 'NCHAR', 'NCLOB', 'NE', 'NESTED_TABLE_ID', 'NEW', 'NEW_TABLE', 'NEXT', 'NEXTVAL', 'NO', 'NOAUDIT', 'NOCHECK', 'NOCOMPRESS', 'NONCLUSTERED', 'NONE', 'NORMALIZE', 'NOT', 'NOTNULL', 'NOWAIT', 'NO_WRITE_TO_BINLOG', 'NTH_VALUE', 'NTILE', 'NULL', 'NULLIF', 'NULLIFZERO', 'NULLS', 'NUMBER', 'NUMERIC', 'NUMPARTS', 'OBID', 'OBJECT', 'OBJECTS', 'OCCURRENCES_REGEX', 'OCTET_LENGTH', 'OF', 'OFF', 'OFFLINE', 'OFFSET', 'OFFSETS', 'OLD', 'OLD_TABLE', 'OMIT', 'ON', 'ONE', 'ONLINE', 'ONLY', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPERATION', 'OPTIMIZATION', 'OPTIMIZE', 'OPTIMIZER_COSTS', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'ORDINALITY', 'ORGANIZATION', 'OUT', 'OUTER', 'OUTFILE', 'OUTPUT', 'OVER', 'OVERLAPS', 'OVERLAY', 'OVERRIDE', 'PACKAGE', 'PAD', 'PADDED', 'PARAMETER', 'PARAMETERS', 'PART', 'PARTIAL', 'PARTITION', 'PARTITIONED', 'PARTITIONING', 'PASSWORD', 'PATH', 'PATTERN', 'PCTFREE', 'PER', 'PERCENT', 'PERCENTILE_CONT', 'PERCENTILE_DISC', 'PERCENT_RANK', 'PERIOD', 'PERM', 'PERMANENT', 'PIECESIZE', 'PIVOT', 'PLACING', 'PLAN', 'PORTION', 'POSITION', 'POSITION_REGEX', 'POSTFIX', 'POWER', 'PRECEDES', 'PRECISION', 'PREFIX', 'PREORDER', 'PREPARE', 'PRESERVE', 'PREVVAL', 'PRIMARY', 'PRINT', 'PRIOR', 'PRIQTY', 'PRIVATE', 'PRIVILEGES', 'PROC', 'PROCEDURE', 'PROFILE', 'PROGRAM', 'PROPORTIONAL', 'PROTECTION', 'PSID', 'PTF', 'PUBLIC', 'PURGE', 'QUALIFIED', 'QUALIFY', 'QUANTILE', 'QUERY', 'QUERYNO', 'RADIANS', 'RAISERROR', 'RANDOM', 'RANGE', 'RANGE_N', 'RANK', 'RAW', 'READ', 'READS', 'READTEXT', 'READ_WRITE', 'REAL', 'RECONFIGURE', 'RECURSIVE', 'REF', 'REFERENCES', 'REFERENCING', 'REFRESH', 'REGEXP', 'REGR_AVGX', 'REGR_AVGY', 'REGR_COUNT', 'REGR_INTERCEPT', 'REGR_R2', 'REGR_SLOPE', 'REGR_SXX', 'REGR_SXY', 'REGR_SYY', 'RELATIVE', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REPLICATION', 'REPOVERRIDE', 'REQUEST', 'REQUIRE', 'RESIGNAL', 'RESOURCE', 'RESTART', 'RESTORE', 'RESTRICT', 'RESULT', 'RESULT_SET_LOCATOR', 'RESUME', 'RET', 'RETRIEVE', 'RETURN', 'RETURNING', 'RETURNS', 'REVALIDATE', 'REVERT', 'REVOKE', 'RIGHT', 'RIGHTS', 'RLIKE', 'ROLE', 'ROLLBACK', 'ROLLFORWARD', 'ROLLUP', 'ROUND_CEILING', 'ROUND_DOWN', 'ROUND_FLOOR', 'ROUND_HALF_DOWN', 'ROUND_HALF_EVEN', 'ROUND_HALF_UP', 'ROUND_UP', 'ROUTINE', 'ROW', 'ROWCOUNT', 'ROWGUIDCOL', 'ROWID', 'ROWNUM', 'ROWS', 'ROWSET', 'ROW_NUMBER', 'RULE', 'RUN', 'RUNNING', 'SAMPLE', 'SAMPLEID', 'SAVE', 'SAVEPOINT', 'SCHEMA', 'SCHEMAS', 'SCOPE', 'SCRATCHPAD', 'SCROLL', 'SEARCH', 'SECOND', 'SECONDS', 'SECOND_MICROSECOND', 'SECQTY', 'SECTION', 'SECURITY', 'SECURITYAUDIT', 'SEEK', 'SEL', 'SELECT', 'SEMANTICKEYPHRASETABLE', 'SEMANTICSIMILARITYDETAILSTABLE', 'SEMANTICSIMILARITYTABLE', 'SENSITIVE', 'SEPARATOR', 'SEQUENCE', 'SESSION', 'SESSION_USER', 'SET', 'SETRESRATE', 'SETS', 'SETSESSRATE', 'SETUSER', 'SHARE', 'SHOW', 'SHUTDOWN', 'SIGNAL', 'SIMILAR', 'SIMPLE', 'SIN', 'SINH', 'SIZE', 'SKEW', 'SKIP', 'SMALLINT', 'SOME', 'SOUNDEX', 'SOURCE', 'SPACE', 'SPATIAL', 'SPECIFIC', 'SPECIFICTYPE', 'SPOOL', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLTEXT', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SQRT', 'SS', 'SSL', 'STANDARD', 'START', 'STARTING', 'STARTUP', 'STATE', 'STATEMENT', 'STATIC', 'STATISTICS', 'STAY', 'STDDEV_POP', 'STDDEV_SAMP', 'STEPINFO', 'STOGROUP', 'STORED', 'STORES', 'STRAIGHT_JOIN', 'STRING_CS', 'STRUCTURE', 'STYLE', 'SUBMULTISET', 'SUBSCRIBER', 'SUBSET', 'SUBSTR', 'SUBSTRING', 'SUBSTRING_REGEX', 'SUCCEEDS', 'SUCCESSFUL', 'SUM', 'SUMMARY', 'SUSPEND', 'SYMMETRIC', 'SYNONYM', 'SYSDATE', 'SYSTEM', 'SYSTEM_TIME', 'SYSTEM_USER', 'SYSTIMESTAMP', 'TABLE', 'TABLESAMPLE', 'TABLESPACE', 'TAN', 'TANH', 'TBL_CS', 'TEMPORARY', 'TERMINATE', 'TERMINATED', 'TEXTSIZE', 'THAN', 'THEN', 'THRESHOLD', 'TIME', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TITLE', 'TO', 'TOP', 'TRACE', 'TRAILING', 'TRAN', 'TRANSACTION', 'TRANSLATE', 'TRANSLATE_CHK', 'TRANSLATE_REGEX', 'TRANSLATION', 'TREAT', 'TRIGGER', 'TRIM', 'TRIM_ARRAY', 'TRUE', 'TRUNCATE', 'TRY_CONVERT', 'TSEQUAL', 'TYPE', 'UC', 'UESCAPE', 'UID', 'UNDEFINED', 'UNDER', 'UNDO', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNLOCK', 'UNNEST', 'UNPIVOT', 'UNSIGNED', 'UNTIL', 'UPD', 'UPDATE', 'UPDATETEXT', 'UPPER', 'UPPERCASE', 'USAGE', 'USE', 'USER', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALIDATE', 'VALIDPROC', 'VALUE', 'VALUES', 'VALUE_OF', 'VARBINARY', 'VARBYTE', 'VARCHAR', 'VARCHAR2', 'VARCHARACTER', 'VARGRAPHIC', 'VARIABLE', 'VARIADIC', 'VARIANT', 'VARYING', 'VAR_POP', 'VAR_SAMP', 'VCAT', 'VERBOSE', 'VERSIONING', 'VIEW', 'VIRTUAL', 'VOLATILE', 'VOLUMES', 'WAIT', 'WAITFOR', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WIDTH_BUCKET', 'WINDOW', 'WITH', 'WITHIN', 'WITHIN_GROUP', 'WITHOUT', 'WLM', 'WORK', 'WRITE', 'WRITETEXT', 'XMLCAST', 'XMLEXISTS', 'XMLNAMESPACES', 'XOR', 'YEAR', 'YEARS', 'YEAR_MONTH', 'ZEROFILL', 'ZEROIFNULL', 'ZONE']; /** * {@inheritdoc} @@ -88,7 +79,7 @@ public function generateClassAttributes(Class_ $class): array continue; } - $attributes[] = new Attribute('ORM\Table', ['name' => $this->generateIdentifierName($class->name(), 'table', $this->config)]); + $attributes[] = new Attribute('ORM\Table', ['name' => sprintf('`%s`', $this->generateIdentifierName($class->name(), 'table', $this->config))]); } return $attributes; diff --git a/src/PhpTypeConverterInterface.php b/src/PhpTypeConverterInterface.php index 5d280bcb..3e492725 100644 --- a/src/PhpTypeConverterInterface.php +++ b/src/PhpTypeConverterInterface.php @@ -22,7 +22,7 @@ interface PhpTypeConverterInterface * @internal */ public const RESERVED_KEYWORDS = [ - '__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'object', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', // PHP + '__halt_compiler', 'abstract', 'and', 'array', 'as', 'break', 'callable', 'case', 'catch', 'class', 'clone', 'const', 'continue', 'declare', 'default', 'die', 'do', 'echo', 'else', 'elseif', 'empty', 'enddeclare', 'endfor', 'endforeach', 'endif', 'endswitch', 'endwhile', 'eval', 'exit', 'extends', 'final', 'finally', 'fn', 'for', 'foreach', 'function', 'global', 'goto', 'if', 'implements', 'include', 'include_once', 'instanceof', 'insteadof', 'interface', 'isset', 'list', 'namespace', 'new', 'object', 'or', 'print', 'private', 'protected', 'public', 'require', 'require_once', 'return', 'static', 'switch', 'throw', 'trait', 'try', 'unset', 'use', 'var', 'while', 'xor', 'yield', // PHP 'collection', // Doctrine ]; diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index 8cb93aa7..6f635c5c 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -202,7 +202,7 @@ public function testGeneratePropertyAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('enum'), 'Vehicle') ); $this->assertEquals( - [new Attribute('ORM\Column', ['type' => 'json', 'nullable' => true])], + [new Attribute('ORM\Column', ['type' => 'json', 'nullable' => true, 'name' => '`collection`'])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('collection'), 'Vehicle') ); $this->assertEquals( diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 898f9c74..c4a1645e 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -486,7 +486,7 @@ public function testActivityStreams(): void * * @see http://www.w3.org/ns/activitystreams#content */ - #[ORM\Column(type: 'text', nullable: true)] + #[ORM\Column(type: 'text', nullable: true, name: '`content`')] #[ApiProperty(types: ['http://www.w3.org/ns/activitystreams#content'])] private ?string $content = null; PHP diff --git a/tests/e2e/original/App/OpenApi/Entity/Book.php b/tests/e2e/original/App/OpenApi/Entity/Book.php index 218ecc53..98866007 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Book.php +++ b/tests/e2e/original/App/OpenApi/Entity/Book.php @@ -46,7 +46,7 @@ class Book * * @see https://schema.org/name */ - #[ORM\Column(type: 'text')] + #[ORM\Column(type: 'text', name: '`title`')] #[ApiProperty(types: ['https://schema.org/name'])] #[Assert\NotNull] private string $title; diff --git a/tests/e2e/original/App/OpenApi/Entity/Order.php b/tests/e2e/original/App/OpenApi/Entity/Order.php index 52d7523d..5626eca8 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Order.php +++ b/tests/e2e/original/App/OpenApi/Entity/Order.php @@ -13,6 +13,7 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] +#[ORM\Table(name: '`order`')] #[ApiResource(operations: [new Get(), new Delete()])] class Order { diff --git a/tests/e2e/original/App/OpenApi/Entity/Parchment.php b/tests/e2e/original/App/OpenApi/Entity/Parchment.php index 50a41110..df60b915 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Parchment.php +++ b/tests/e2e/original/App/OpenApi/Entity/Parchment.php @@ -27,7 +27,7 @@ class Parchment /** * The title of the book. */ - #[ORM\Column(type: 'text')] + #[ORM\Column(type: 'text', name: '`title`')] #[ApiProperty] #[Assert\NotNull] private string $title; diff --git a/tests/e2e/original/App/OpenApi/Entity/TopBook.php b/tests/e2e/original/App/OpenApi/Entity/TopBook.php index a551030f..4e4bfab5 100644 --- a/tests/e2e/original/App/OpenApi/Entity/TopBook.php +++ b/tests/e2e/original/App/OpenApi/Entity/TopBook.php @@ -23,7 +23,7 @@ class TopBook #[ORM\Column(type: 'integer')] private ?int $id = null; - #[ORM\Column(type: 'text')] + #[ORM\Column(type: 'text', name: '`title`')] #[ApiProperty] #[Assert\NotNull] private string $title; @@ -33,7 +33,7 @@ class TopBook #[Assert\NotNull] private string $author; - #[ORM\Column(type: 'text')] + #[ORM\Column(type: 'text', name: '`part`')] #[ApiProperty] #[Assert\NotNull] private string $part; diff --git a/tests/e2e/original/App/OpenApi/Entity/User.php b/tests/e2e/original/App/OpenApi/Entity/User.php index 8b97ef65..b5f3c01d 100644 --- a/tests/e2e/original/App/OpenApi/Entity/User.php +++ b/tests/e2e/original/App/OpenApi/Entity/User.php @@ -13,6 +13,7 @@ use Symfony\Component\Validator\Constraints as Assert; #[ORM\Entity] +#[ORM\Table(name: '`user`')] #[ApiResource(operations: [new Get(), new Put(), new Delete()])] class User { @@ -41,7 +42,7 @@ class User #[Assert\NotNull] private string $email; - #[ORM\Column(type: 'text')] + #[ORM\Column(type: 'text', name: '`password`')] #[ApiProperty] #[Assert\NotNull] private string $password; From 9dcb97e34494e6acce9ab0153909539976f92983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Suwi=C5=84ski?= Date: Tue, 6 Sep 2022 12:02:31 +0200 Subject: [PATCH 228/258] feat: default value (#389) --- composer.json | 2 +- composer.lock | 727 ++++++++---------- phpstan.neon | 1 + src/Model/Property.php | 6 +- src/OpenApi/ClassGenerator.php | 6 +- src/Schema/Generator.php | 3 +- .../PropertyGenerator/PropertyGenerator.php | 1 + src/SchemaGeneratorConfiguration.php | 1 + tests/Command/DumpConfigurationTest.php | 3 + tests/Command/GenerateCommandTest.php | 16 + tests/config/property-default.yaml | 7 + 11 files changed, 379 insertions(+), 394 deletions(-) create mode 100644 tests/config/property-default.yaml diff --git a/composer.json b/composer.json index 66e33803..9592efab 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "symfony/string": "^5.2 || ^6.0" }, "require-dev": { - "api-platform/core": "^v2.7.0-beta.1", + "api-platform/core": "^v2.7.0-rc.1", "doctrine/orm": "^2.7", "myclabs/php-enum": "^1.7", "symfony/doctrine-bridge": "^5.2 || ^6.0", diff --git a/composer.lock b/composer.lock index 693456ce..96ee10db 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5fd1addf87a1b017576c7b5ad28e846a", + "content-hash": "90af9c60c6d77f881ef527556f6cc865", "packages": [ { "name": "cebe/php-openapi", @@ -295,16 +295,16 @@ }, { "name": "doctrine/annotations", - "version": "1.13.2", + "version": "1.13.3", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08" + "reference": "648b0343343565c4a056bfc8392201385e8d89f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/5b668aef16090008790395c02c893b1ba13f7e08", - "reference": "5b668aef16090008790395c02c893b1ba13f7e08", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", + "reference": "648b0343343565c4a056bfc8392201385e8d89f0", "shasum": "" }, "require": { @@ -316,9 +316,10 @@ "require-dev": { "doctrine/cache": "^1.11 || ^2.0", "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", + "phpstan/phpstan": "^1.4.10 || ^1.8.0", "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2" + "symfony/cache": "^4.4 || ^5.2", + "vimeo/psalm": "^4.10" }, "type": "library", "autoload": { @@ -361,9 +362,9 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.2" + "source": "https://github.com/doctrine/annotations/tree/1.13.3" }, - "time": "2021-08-05T19:00:23+00:00" + "time": "2022-07-02T10:48:51+00:00" }, { "name": "doctrine/inflector", @@ -609,16 +610,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.8.0", + "version": "v3.11.0", "source": { "type": "git", "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3" + "reference": "7dcdea3f2f5f473464e835be9be55283ff8cfdc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", - "reference": "cbad1115aac4b5c3c5540e7210d3c9fba2f81fa3", + "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/7dcdea3f2f5f473464e835be9be55283ff8cfdc3", + "reference": "7dcdea3f2f5f473464e835be9be55283ff8cfdc3", "shasum": "" }, "require": { @@ -628,7 +629,7 @@ "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", - "php-cs-fixer/diff": "^2.0", + "sebastian/diff": "^4.0", "symfony/console": "^5.4 || ^6.0", "symfony/event-dispatcher": "^5.4 || ^6.0", "symfony/filesystem": "^5.4 || ^6.0", @@ -686,7 +687,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.8.0" + "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.11.0" }, "funding": [ { @@ -694,7 +695,7 @@ "type": "github" } ], - "time": "2022-03-18T17:20:59+00:00" + "time": "2022-09-01T18:24:51+00:00" }, { "name": "justinrainbow/json-schema", @@ -857,16 +858,16 @@ }, { "name": "nette/php-generator", - "version": "v4.0.1", + "version": "v4.0.2", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "23110ddbcdc7723f5ae06e94a535bbd01b72bfdc" + "reference": "f19b7975c7c4d729be5b64fce7eb72f0d4aac6fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/23110ddbcdc7723f5ae06e94a535bbd01b72bfdc", - "reference": "23110ddbcdc7723f5ae06e94a535bbd01b72bfdc", + "url": "https://api.github.com/repos/nette/php-generator/zipball/f19b7975c7c4d729be5b64fce7eb72f0d4aac6fc", + "reference": "f19b7975c7c4d729be5b64fce7eb72f0d4aac6fc", "shasum": "" }, "require": { @@ -919,9 +920,9 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.0.1" + "source": "https://github.com/nette/php-generator/tree/v4.0.2" }, - "time": "2022-03-10T02:24:09+00:00" + "time": "2022-06-17T12:20:08+00:00" }, { "name": "nette/utils", @@ -929,16 +930,16 @@ "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "fb7403eecc701e1932d6e9b213342c5957cf4e3f" + "reference": "52db62bc9605d7778f0190d8fde0d5db3787be24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/fb7403eecc701e1932d6e9b213342c5957cf4e3f", - "reference": "fb7403eecc701e1932d6e9b213342c5957cf4e3f", + "url": "https://api.github.com/repos/nette/utils/zipball/52db62bc9605d7778f0190d8fde0d5db3787be24", + "reference": "52db62bc9605d7778f0190d8fde0d5db3787be24", "shasum": "" }, "require": { - "php": ">=8.0 <8.2" + "php": ">=8.0 <8.3" }, "conflict": { "nette/di": "<3.0.6" @@ -1007,20 +1008,20 @@ "issues": "https://github.com/nette/utils/issues", "source": "https://github.com/nette/utils/tree/master" }, - "time": "2022-06-02T11:43:37+00:00" + "time": "2022-09-06T01:00:53+00:00" }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -1061,61 +1062,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" - }, - "time": "2022-05-31T20:59:12+00:00" - }, - { - "name": "php-cs-fixer/diff", - "version": "v2.0.2", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "reference": "29dc0d507e838c4580d018bd8b5cb412474f7ec3", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", - "symfony/process": "^3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "sebastian/diff v3 backport support for PHP 5.6+", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "support": { - "issues": "https://github.com/PHP-CS-Fixer/diff/issues", - "source": "https://github.com/PHP-CS-Fixer/diff/tree/v2.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2020-10-14T08:32:19+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "psr/cache", @@ -1319,18 +1268,84 @@ }, "time": "2021-07-14T16:46:02+00:00" }, + { + "name": "sebastian/diff", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T13:10:38+00:00" + }, { "name": "symfony/config", - "version": "v6.0.9", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "9c40f44bc38d91aeefbcdd1d42609033984ce062" + "reference": "956d4ec5df274dda91a4cedfccc2bfd063f6f649" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/9c40f44bc38d91aeefbcdd1d42609033984ce062", - "reference": "9c40f44bc38d91aeefbcdd1d42609033984ce062", + "url": "https://api.github.com/repos/symfony/config/zipball/956d4ec5df274dda91a4cedfccc2bfd063f6f649", + "reference": "956d4ec5df274dda91a4cedfccc2bfd063f6f649", "shasum": "" }, "require": { @@ -1379,7 +1394,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v6.0.9" + "source": "https://github.com/symfony/config/tree/v6.0.11" }, "funding": [ { @@ -1395,20 +1410,20 @@ "type": "tidelift" } ], - "time": "2022-05-17T12:08:13+00:00" + "time": "2022-06-27T17:10:44+00:00" }, { "name": "symfony/console", - "version": "v6.0.9", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9b190bc7a19d19add1dbb3382721973836e59b50" + "reference": "c5c2e313aa682530167c25077d6bdff36346251e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9b190bc7a19d19add1dbb3382721973836e59b50", - "reference": "9b190bc7a19d19add1dbb3382721973836e59b50", + "url": "https://api.github.com/repos/symfony/console/zipball/c5c2e313aa682530167c25077d6bdff36346251e", + "reference": "c5c2e313aa682530167c25077d6bdff36346251e", "shasum": "" }, "require": { @@ -1474,7 +1489,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.9" + "source": "https://github.com/symfony/console/tree/v6.0.12" }, "funding": [ { @@ -1490,11 +1505,11 @@ "type": "tidelift" } ], - "time": "2022-05-27T06:40:13+00:00" + "time": "2022-08-23T20:52:30+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -1541,7 +1556,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" }, "funding": [ { @@ -1644,7 +1659,7 @@ }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", @@ -1703,7 +1718,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.2" }, "funding": [ { @@ -1723,16 +1738,16 @@ }, { "name": "symfony/filesystem", - "version": "v6.0.9", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "bf7b9d2ee692b6df2a41017d6023a2fe732d240c" + "reference": "a36b782dc19dce3ab7e47d4b92b13cefb3511da3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/bf7b9d2ee692b6df2a41017d6023a2fe732d240c", - "reference": "bf7b9d2ee692b6df2a41017d6023a2fe732d240c", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/a36b782dc19dce3ab7e47d4b92b13cefb3511da3", + "reference": "a36b782dc19dce3ab7e47d4b92b13cefb3511da3", "shasum": "" }, "require": { @@ -1766,7 +1781,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.9" + "source": "https://github.com/symfony/filesystem/tree/v6.0.12" }, "funding": [ { @@ -1782,20 +1797,20 @@ "type": "tidelift" } ], - "time": "2022-05-21T13:33:31+00:00" + "time": "2022-08-02T16:01:06+00:00" }, { "name": "symfony/finder", - "version": "v6.0.8", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f" + "reference": "09cb683ba5720385ea6966e5e06be2a34f2568b1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/af7edab28d17caecd1f40a9219fc646ae751c21f", - "reference": "af7edab28d17caecd1f40a9219fc646ae751c21f", + "url": "https://api.github.com/repos/symfony/finder/zipball/09cb683ba5720385ea6966e5e06be2a34f2568b1", + "reference": "09cb683ba5720385ea6966e5e06be2a34f2568b1", "shasum": "" }, "require": { @@ -1827,7 +1842,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.8" + "source": "https://github.com/symfony/finder/tree/v6.0.11" }, "funding": [ { @@ -1843,7 +1858,7 @@ "type": "tidelift" } ], - "time": "2022-04-15T08:07:58+00:00" + "time": "2022-07-29T07:39:48+00:00" }, { "name": "symfony/options-resolver", @@ -2406,16 +2421,16 @@ }, { "name": "symfony/process", - "version": "v6.0.8", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9" + "reference": "44270a08ccb664143dede554ff1c00aaa2247a43" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/d074154ea8b1443a96391f6e39f9e547b2dd01b9", - "reference": "d074154ea8b1443a96391f6e39f9e547b2dd01b9", + "url": "https://api.github.com/repos/symfony/process/zipball/44270a08ccb664143dede554ff1c00aaa2247a43", + "reference": "44270a08ccb664143dede554ff1c00aaa2247a43", "shasum": "" }, "require": { @@ -2447,7 +2462,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v6.0.8" + "source": "https://github.com/symfony/process/tree/v6.0.11" }, "funding": [ { @@ -2463,20 +2478,20 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:11:42+00:00" + "time": "2022-06-27T17:10:44+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c" + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e517458f278c2131ca9f262f8fbaf01410f2c65c", - "reference": "e517458f278c2131ca9f262f8fbaf01410f2c65c", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", "shasum": "" }, "require": { @@ -2529,7 +2544,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" }, "funding": [ { @@ -2545,7 +2560,7 @@ "type": "tidelift" } ], - "time": "2022-03-13T20:10:05+00:00" + "time": "2022-05-30T19:17:58+00:00" }, { "name": "symfony/stopwatch", @@ -2611,16 +2626,16 @@ }, { "name": "symfony/string", - "version": "v6.0.9", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc" + "reference": "3a975ba1a1508ad97df45f4590f55b7cc4c1a0a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/df9f03d595aa2d446498ba92fe803a519b2c43cc", - "reference": "df9f03d595aa2d446498ba92fe803a519b2c43cc", + "url": "https://api.github.com/repos/symfony/string/zipball/3a975ba1a1508ad97df45f4590f55b7cc4c1a0a0", + "reference": "3a975ba1a1508ad97df45f4590f55b7cc4c1a0a0", "shasum": "" }, "require": { @@ -2676,7 +2691,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.9" + "source": "https://github.com/symfony/string/tree/v6.0.12" }, "funding": [ { @@ -2692,20 +2707,20 @@ "type": "tidelift" } ], - "time": "2022-04-22T08:18:02+00:00" + "time": "2022-08-12T18:05:20+00:00" }, { "name": "symfony/yaml", - "version": "v6.0.3", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "e77f3ea0b21141d771d4a5655faa54f692b34af5" + "reference": "8c68efb08b038ec02753da6f16e1601a6ed4ef17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/e77f3ea0b21141d771d4a5655faa54f692b34af5", - "reference": "e77f3ea0b21141d771d4a5655faa54f692b34af5", + "url": "https://api.github.com/repos/symfony/yaml/zipball/8c68efb08b038ec02753da6f16e1601a6ed4ef17", + "reference": "8c68efb08b038ec02753da6f16e1601a6ed4ef17", "shasum": "" }, "require": { @@ -2750,7 +2765,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.0.3" + "source": "https://github.com/symfony/yaml/tree/v6.0.12" }, "funding": [ { @@ -2766,20 +2781,20 @@ "type": "tidelift" } ], - "time": "2022-01-26T17:23:29+00:00" + "time": "2022-08-02T16:01:06+00:00" }, { "name": "twig/twig", - "version": "v3.4.1", + "version": "v3.4.2", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e939eae92386b69b49cfa4599dd9bead6bf4a342" + "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e939eae92386b69b49cfa4599dd9bead6bf4a342", - "reference": "e939eae92386b69b49cfa4599dd9bead6bf4a342", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", + "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", "shasum": "" }, "require": { @@ -2830,7 +2845,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.1" + "source": "https://github.com/twigphp/Twig/tree/v3.4.2" }, "funding": [ { @@ -2842,22 +2857,22 @@ "type": "tidelift" } ], - "time": "2022-05-17T05:48:52+00:00" + "time": "2022-08-12T06:47:24+00:00" } ], "packages-dev": [ { "name": "api-platform/core", - "version": "v2.7.0-beta.1", + "version": "v2.7.0-rc.2", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "4c16efe1f39c8aadd20e8e08b0b57a4d33034cd8" + "reference": "f2c8a6113d2e004eefe10f95671a8822ce307733" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/4c16efe1f39c8aadd20e8e08b0b57a4d33034cd8", - "reference": "4c16efe1f39c8aadd20e8e08b0b57a4d33034cd8", + "url": "https://api.github.com/repos/api-platform/core/zipball/f2c8a6113d2e004eefe10f95671a8822ce307733", + "reference": "f2c8a6113d2e004eefe10f95671a8822ce307733", "shasum": "" }, "require": { @@ -3003,7 +3018,7 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v2.7.0-beta.1" + "source": "https://github.com/api-platform/core/tree/v2.7.0-rc.2" }, "funding": [ { @@ -3011,7 +3026,7 @@ "type": "tidelift" } ], - "time": "2022-05-31T14:59:40+00:00" + "time": "2022-07-25T08:58:06+00:00" }, { "name": "doctrine/cache", @@ -3108,26 +3123,27 @@ }, { "name": "doctrine/collections", - "version": "1.6.8", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "1958a744696c6bb3bb0d28db2611dc11610e78af" + "reference": "3fe77330f5591108bbf1315da7377a7e704ed8a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/1958a744696c6bb3bb0d28db2611dc11610e78af", - "reference": "1958a744696c6bb3bb0d28db2611dc11610e78af", + "url": "https://api.github.com/repos/doctrine/collections/zipball/3fe77330f5591108bbf1315da7377a7e704ed8a0", + "reference": "3fe77330f5591108bbf1315da7377a7e704ed8a0", "shasum": "" }, "require": { + "doctrine/deprecations": "^0.5.3 || ^1", "php": "^7.1.3 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", - "phpstan/phpstan": "^0.12", + "doctrine/coding-standard": "^9.0 || ^10.0", + "phpstan/phpstan": "^1.4.8", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", - "vimeo/psalm": "^4.2.1" + "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { @@ -3171,22 +3187,22 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/1.6.8" + "source": "https://github.com/doctrine/collections/tree/1.7.2" }, - "time": "2021-08-10T18:51:53+00:00" + "time": "2022-08-27T16:08:58+00:00" }, { "name": "doctrine/common", - "version": "3.3.0", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "c824e95d4c83b7102d8bc60595445a6f7d540f96" + "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/c824e95d4c83b7102d8bc60595445a6f7d540f96", - "reference": "c824e95d4c83b7102d8bc60595445a6f7d540f96", + "url": "https://api.github.com/repos/doctrine/common/zipball/e09556bbdf95b8420e649162b19ae9da2d1a80f3", + "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3", "shasum": "" }, "require": { @@ -3195,6 +3211,7 @@ }, "require-dev": { "doctrine/coding-standard": "^9.0", + "doctrine/collections": "^1", "phpstan/phpstan": "^1.4.1", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", @@ -3205,7 +3222,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3247,7 +3264,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.3.0" + "source": "https://github.com/doctrine/common/tree/3.4.0" }, "funding": [ { @@ -3263,20 +3280,20 @@ "type": "tidelift" } ], - "time": "2022-02-05T18:28:51+00:00" + "time": "2022-08-23T19:46:56+00:00" }, { "name": "doctrine/dbal", - "version": "3.3.6", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21" + "reference": "4cbbe6e4b9ef6c69d5f4c968c637476f47bb54f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/9e7f76dd1cde81c62574fdffa5a9c655c847ad21", - "reference": "9e7f76dd1cde81c62574fdffa5a9c655c847ad21", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/4cbbe6e4b9ef6c69d5f4c968c637476f47bb54f5", + "reference": "4cbbe6e4b9ef6c69d5f4c968c637476f47bb54f5", "shasum": "" }, "require": { @@ -3284,21 +3301,21 @@ "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", "doctrine/event-manager": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2022.1", - "phpstan/phpstan": "1.6.3", - "phpstan/phpstan-strict-rules": "^1.2", - "phpunit/phpunit": "9.5.20", - "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.6.2", - "symfony/cache": "^5.2|^6.0", - "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0", - "vimeo/psalm": "4.23.0" + "doctrine/coding-standard": "10.0.0", + "jetbrains/phpstorm-stubs": "2022.2", + "phpstan/phpstan": "1.8.3", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "9.5.24", + "psalm/plugin-phpunit": "0.17.0", + "squizlabs/php_codesniffer": "3.7.1", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.27.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -3358,7 +3375,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.3.6" + "source": "https://github.com/doctrine/dbal/tree/3.4.4" }, "funding": [ { @@ -3374,7 +3391,7 @@ "type": "tidelift" } ], - "time": "2022-05-02T17:21:01+00:00" + "time": "2022-09-01T21:26:42+00:00" }, { "name": "doctrine/deprecations", @@ -3421,34 +3438,31 @@ }, { "name": "doctrine/event-manager", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" + "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", - "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "conflict": { - "doctrine/common": "<2.9@dev" + "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpunit/phpunit": "^7.0" + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "~1.4.10 || ^1.5.4", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" @@ -3495,7 +3509,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + "source": "https://github.com/doctrine/event-manager/tree/1.1.2" }, "funding": [ { @@ -3511,7 +3525,7 @@ "type": "tidelift" } ], - "time": "2020-05-29T18:28:51+00:00" + "time": "2022-07-27T22:18:11+00:00" }, { "name": "doctrine/instantiator", @@ -3585,16 +3599,16 @@ }, { "name": "doctrine/orm", - "version": "2.12.2", + "version": "2.13.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "8291a7f09b12d14783ed6537b4586583d155869e" + "reference": "35c44a56677adb3ce796138b6e4934ce93ec6811" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/8291a7f09b12d14783ed6537b4586583d155869e", - "reference": "8291a7f09b12d14783ed6537b4586583d155869e", + "url": "https://api.github.com/repos/doctrine/orm/zipball/35c44a56677adb3ce796138b6e4934ce93ec6811", + "reference": "35c44a56677adb3ce796138b6e4934ce93ec6811", "shasum": "" }, "require": { @@ -3623,15 +3637,16 @@ "doctrine/annotations": "^1.13", "doctrine/coding-standard": "^9.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.6.3", + "phpstan/phpstan": "~1.4.10 || 1.8.2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/log": "^1 || ^2 || ^3", - "squizlabs/php_codesniffer": "3.6.2", + "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.23.0" + "vimeo/psalm": "4.26.0" }, "suggest": { + "ext-dom": "Provides support for XSD validation for XML mapping files", "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" }, @@ -3678,26 +3693,25 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.12.2" + "source": "https://github.com/doctrine/orm/tree/2.13.1" }, - "time": "2022-05-02T19:10:07+00:00" + "time": "2022-08-08T09:00:16+00:00" }, { "name": "doctrine/persistence", - "version": "3.0.2", + "version": "3.0.3", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "25ec98a8cbd1f850e60fdb62c0ef77c162da8704" + "reference": "ac6fce61f037d7e54dbb2435f5b5648d86548e23" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/25ec98a8cbd1f850e60fdb62c0ef77c162da8704", - "reference": "25ec98a8cbd1f850e60fdb62c0ef77c162da8704", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/ac6fce61f037d7e54dbb2435f5b5648d86548e23", + "reference": "ac6fce61f037d7e54dbb2435f5b5648d86548e23", "shasum": "" }, "require": { - "doctrine/collections": "^1.0", "doctrine/event-manager": "^1.0", "php": "^7.2 || ^8.0", "psr/cache": "^1.0 || ^2.0 || ^3.0" @@ -3765,7 +3779,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.0.2" + "source": "https://github.com/doctrine/persistence/tree/3.0.3" }, "funding": [ { @@ -3781,7 +3795,7 @@ "type": "tidelift" } ], - "time": "2022-05-06T06:10:05+00:00" + "time": "2022-08-04T21:14:21+00:00" }, { "name": "fig/link-util", @@ -3905,16 +3919,16 @@ }, { "name": "myclabs/php-enum", - "version": "1.8.3", + "version": "1.8.4", "source": { "type": "git", "url": "https://github.com/myclabs/php-enum.git", - "reference": "b942d263c641ddb5190929ff840c68f78713e937" + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/b942d263c641ddb5190929ff840c68f78713e937", - "reference": "b942d263c641ddb5190929ff840c68f78713e937", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", + "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", "shasum": "" }, "require": { @@ -3930,7 +3944,10 @@ "autoload": { "psr-4": { "MyCLabs\\Enum\\": "src/" - } + }, + "classmap": [ + "stubs/Stringable.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -3949,7 +3966,7 @@ ], "support": { "issues": "https://github.com/myclabs/php-enum/issues", - "source": "https://github.com/myclabs/php-enum/tree/1.8.3" + "source": "https://github.com/myclabs/php-enum/tree/1.8.4" }, "funding": [ { @@ -3961,7 +3978,7 @@ "type": "tidelift" } ], - "time": "2021-07-05T08:18:36+00:00" + "time": "2022-08-04T09:53:51+00:00" }, { "name": "phar-io/manifest", @@ -4355,16 +4372,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.7.11", + "version": "1.8.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "62fcadcde81b4037e42ad2489119d31c46f00191" + "reference": "eed4c9da531f6ebb4787235b6fb486e2c20f34e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/62fcadcde81b4037e42ad2489119d31c46f00191", - "reference": "62fcadcde81b4037e42ad2489119d31c46f00191", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/eed4c9da531f6ebb4787235b6fb486e2c20f34e5", + "reference": "eed4c9da531f6ebb4787235b6fb486e2c20f34e5", "shasum": "" }, "require": { @@ -4388,9 +4405,13 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.7.11" + "source": "https://github.com/phpstan/phpstan/tree/1.8.4" }, "funding": [ { @@ -4401,36 +4422,32 @@ "url": "https://github.com/phpstan", "type": "github" }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", "type": "tidelift" } ], - "time": "2022-06-07T08:47:03+00:00" + "time": "2022-09-03T13:08:04+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.15", + "version": "9.2.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.14", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4479,7 +4496,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" }, "funding": [ { @@ -4487,7 +4504,7 @@ "type": "github" } ], - "time": "2022-03-07T09:28:20+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4732,16 +4749,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.20", + "version": "9.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba" + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/12bc8879fb65aef2138b26fc633cb1e3620cffba", - "reference": "12bc8879fb65aef2138b26fc633cb1e3620cffba", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", "shasum": "" }, "require": { @@ -4756,7 +4773,6 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", @@ -4771,13 +4787,9 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.1", "sebastian/version": "^3.0.2" }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" @@ -4819,7 +4831,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.20" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" }, "funding": [ { @@ -4831,7 +4843,7 @@ "type": "github" } ], - "time": "2022-04-01T12:37:26+00:00" + "time": "2022-08-30T07:42:16+00:00" }, { "name": "psr/link", @@ -5187,72 +5199,6 @@ ], "time": "2020-10-26T15:52:27+00:00" }, - { - "name": "sebastian/diff", - "version": "4.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "support": { - "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-10-26T13:10:38+00:00" - }, { "name": "sebastian/environment", "version": "5.1.4", @@ -5746,16 +5692,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb44e1cc6e557418387ad815780360057e40753e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb44e1cc6e557418387ad815780360057e40753e", + "reference": "fb44e1cc6e557418387ad815780360057e40753e", "shasum": "" }, "require": { @@ -5767,7 +5713,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -5790,7 +5736,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.1.0" }, "funding": [ { @@ -5798,7 +5744,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-08-29T06:55:37+00:00" }, { "name": "sebastian/version", @@ -5855,16 +5801,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.0.9", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "34599e7deb63ec68ad72e206c2401a5448249783" + "reference": "203153a2596e7e2b3eb28a7e0d4e301955d64b2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/34599e7deb63ec68ad72e206c2401a5448249783", - "reference": "34599e7deb63ec68ad72e206c2401a5448249783", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/203153a2596e7e2b3eb28a7e0d4e301955d64b2e", + "reference": "203153a2596e7e2b3eb28a7e0d4e301955d64b2e", "shasum": "" }, "require": { @@ -5950,7 +5896,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.0.9" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.0.11" }, "funding": [ { @@ -5966,20 +5912,20 @@ "type": "tidelift" } ], - "time": "2022-05-27T06:30:15+00:00" + "time": "2022-07-29T07:39:48+00:00" }, { "name": "symfony/error-handler", - "version": "v6.0.9", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "732ca203b3222cde3378d5ddf5e2883211acc53e" + "reference": "cb302377e1b862540436f22be9ff07079a5836ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/732ca203b3222cde3378d5ddf5e2883211acc53e", - "reference": "732ca203b3222cde3378d5ddf5e2883211acc53e", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/cb302377e1b862540436f22be9ff07079a5836ae", + "reference": "cb302377e1b862540436f22be9ff07079a5836ae", "shasum": "" }, "require": { @@ -6021,7 +5967,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.0.9" + "source": "https://github.com/symfony/error-handler/tree/v6.0.11" }, "funding": [ { @@ -6037,20 +5983,20 @@ "type": "tidelift" } ], - "time": "2022-05-23T10:32:42+00:00" + "time": "2022-07-29T07:39:48+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.0.9", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "05abe9aab47decfd793632787d0c6a25268e2a5b" + "reference": "d50ee4795c981638369dfa0b281107365fab2429" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/05abe9aab47decfd793632787d0c6a25268e2a5b", - "reference": "05abe9aab47decfd793632787d0c6a25268e2a5b", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d50ee4795c981638369dfa0b281107365fab2429", + "reference": "d50ee4795c981638369dfa0b281107365fab2429", "shasum": "" }, "require": { @@ -6061,8 +6007,11 @@ "require-dev": { "predis/predis": "~1.0", "symfony/cache": "^5.4|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0" + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^5.4|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" }, "suggest": { "symfony/mime": "To use the file extension guesser" @@ -6093,7 +6042,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.0.9" + "source": "https://github.com/symfony/http-foundation/tree/v6.0.12" }, "funding": [ { @@ -6109,20 +6058,20 @@ "type": "tidelift" } ], - "time": "2022-05-21T13:33:31+00:00" + "time": "2022-08-19T14:25:15+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.0.9", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "e78407f2a7b683fd1269057aa39355d77ddbcff9" + "reference": "8f3563e4518cfee24a5cc724434cc60e0818abec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/e78407f2a7b683fd1269057aa39355d77ddbcff9", - "reference": "e78407f2a7b683fd1269057aa39355d77ddbcff9", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8f3563e4518cfee24a5cc724434cc60e0818abec", + "reference": "8f3563e4518cfee24a5cc724434cc60e0818abec", "shasum": "" }, "require": { @@ -6202,7 +6151,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.0.9" + "source": "https://github.com/symfony/http-kernel/tree/v6.0.12" }, "funding": [ { @@ -6218,20 +6167,20 @@ "type": "tidelift" } ], - "time": "2022-05-27T07:14:30+00:00" + "time": "2022-08-26T14:45:39+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.1.0", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "092ccc3b364925cd8ed6046bc31dcf3a022bd5a4" + "reference": "75c2fa71d049c1f48e39d208c0cefba97e66335a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/092ccc3b364925cd8ed6046bc31dcf3a022bd5a4", - "reference": "092ccc3b364925cd8ed6046bc31dcf3a022bd5a4", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/75c2fa71d049c1f48e39d208c0cefba97e66335a", + "reference": "75c2fa71d049c1f48e39d208c0cefba97e66335a", "shasum": "" }, "require": { @@ -6285,7 +6234,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.1.0" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.1.3" }, "funding": [ { @@ -6301,7 +6250,7 @@ "type": "tidelift" } ], - "time": "2022-04-12T16:22:53+00:00" + "time": "2022-07-28T13:40:41+00:00" }, { "name": "symfony/polyfill-php72", @@ -6381,16 +6330,16 @@ }, { "name": "symfony/property-access", - "version": "v6.0.8", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "e5ac708a97933e9680b81b92eb90a5e301490d72" + "reference": "8299bd756989ef04be53e2099e6b6fd5154a03ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/e5ac708a97933e9680b81b92eb90a5e301490d72", - "reference": "e5ac708a97933e9680b81b92eb90a5e301490d72", + "url": "https://api.github.com/repos/symfony/property-access/zipball/8299bd756989ef04be53e2099e6b6fd5154a03ed", + "reference": "8299bd756989ef04be53e2099e6b6fd5154a03ed", "shasum": "" }, "require": { @@ -6440,7 +6389,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.0.8" + "source": "https://github.com/symfony/property-access/tree/v6.0.11" }, "funding": [ { @@ -6456,20 +6405,20 @@ "type": "tidelift" } ], - "time": "2022-04-20T15:01:42+00:00" + "time": "2022-06-27T17:10:44+00:00" }, { "name": "symfony/property-info", - "version": "v6.0.9", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "f6ca518cee8cac7e1e1a3f922a5731ab866b9b0b" + "reference": "518f172491b9c09afd5d963f783909b80c4b0308" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/f6ca518cee8cac7e1e1a3f922a5731ab866b9b0b", - "reference": "f6ca518cee8cac7e1e1a3f922a5731ab866b9b0b", + "url": "https://api.github.com/repos/symfony/property-info/zipball/518f172491b9c09afd5d963f783909b80c4b0308", + "reference": "518f172491b9c09afd5d963f783909b80c4b0308", "shasum": "" }, "require": { @@ -6529,7 +6478,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.0.9" + "source": "https://github.com/symfony/property-info/tree/v6.0.11" }, "funding": [ { @@ -6545,20 +6494,20 @@ "type": "tidelift" } ], - "time": "2022-05-17T09:49:29+00:00" + "time": "2022-07-19T08:33:44+00:00" }, { "name": "symfony/serializer", - "version": "v6.0.9", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "cd209717fce097ed002a218cbd9be9d56ed53e78" + "reference": "18c9a8101edd84f383f440727052a1926d1e3639" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/cd209717fce097ed002a218cbd9be9d56ed53e78", - "reference": "cd209717fce097ed002a218cbd9be9d56ed53e78", + "url": "https://api.github.com/repos/symfony/serializer/zipball/18c9a8101edd84f383f440727052a1926d1e3639", + "reference": "18c9a8101edd84f383f440727052a1926d1e3639", "shasum": "" }, "require": { @@ -6630,7 +6579,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.0.9" + "source": "https://github.com/symfony/serializer/tree/v6.0.12" }, "funding": [ { @@ -6646,20 +6595,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T09:19:38+00:00" + "time": "2022-08-26T10:32:20+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.0.1", + "version": "v3.0.2", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9" + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", - "reference": "c4183fc3ef0f0510893cbeedc7718fb5cafc9ac9", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/acbfbb274e730e5a0236f619b6168d9dedb3e282", + "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", "shasum": "" }, "require": { @@ -6708,7 +6657,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.0.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.0.2" }, "funding": [ { @@ -6724,20 +6673,20 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-06-27T17:10:44+00:00" }, { "name": "symfony/validator", - "version": "v6.0.8", + "version": "v6.0.12", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "d8f47eea936014e9e9d1cd3248f8c73d57dc248b" + "reference": "0987eb0c390d5686768ea2bb388c81494ea4508f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/d8f47eea936014e9e9d1cd3248f8c73d57dc248b", - "reference": "d8f47eea936014e9e9d1cd3248f8c73d57dc248b", + "url": "https://api.github.com/repos/symfony/validator/zipball/0987eb0c390d5686768ea2bb388c81494ea4508f", + "reference": "0987eb0c390d5686768ea2bb388c81494ea4508f", "shasum": "" }, "require": { @@ -6816,7 +6765,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.0.8" + "source": "https://github.com/symfony/validator/tree/v6.0.12" }, "funding": [ { @@ -6832,20 +6781,20 @@ "type": "tidelift" } ], - "time": "2022-04-15T08:07:58+00:00" + "time": "2022-08-12T13:08:57+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.0.9", + "version": "v6.0.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "ac81072464221e73ee994d12f0b8a2af4a9ed798" + "reference": "2672bdc01c1971e3d8879ce153ec4c3621be5f07" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/ac81072464221e73ee994d12f0b8a2af4a9ed798", - "reference": "ac81072464221e73ee994d12f0b8a2af4a9ed798", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2672bdc01c1971e3d8879ce153ec4c3621be5f07", + "reference": "2672bdc01c1971e3d8879ce153ec4c3621be5f07", "shasum": "" }, "require": { @@ -6904,7 +6853,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.0.9" + "source": "https://github.com/symfony/var-dumper/tree/v6.0.11" }, "funding": [ { @@ -6920,7 +6869,7 @@ "type": "tidelift" } ], - "time": "2022-05-21T13:33:31+00:00" + "time": "2022-07-20T13:45:53+00:00" }, { "name": "symfony/web-link", @@ -7177,7 +7126,7 @@ "minimum-stability": "stable", "stability-flags": { "nette/utils": 20, - "api-platform/core": 10 + "api-platform/core": 5 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/phpstan.neon b/phpstan.neon index b343dcd8..529d82ba 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -14,6 +14,7 @@ parameters: readable: boolean, writable: boolean, nullable: boolean, + defaultValue: mixed, required: ?boolean, unique: boolean, embedded: boolean, diff --git a/src/Model/Property.php b/src/Model/Property.php index 865ab646..58221496 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -27,6 +27,8 @@ abstract class Property public string $cardinality; /** @var ?string the data type (array and object are not one) */ public ?string $type = null; + /** @var mixed */ + public $defaultValue = null; /** @var ?string the array data type (object is not one) */ public ?string $arrayType = null; /** @var bool can be true and array type false if the property is an array of references */ @@ -148,7 +150,9 @@ public function toNetteProperty(PhpNamespace $namespace, string $visibility = nu $property->setNullable($this->isNullable); } - if (($default = $this->guessDefaultGeneratedValue($useDoctrineCollections)) !== -1) { + if (null !== $default = $this->defaultValue) { + $property->setValue($default); + } elseif (-1 !== $default = $this->guessDefaultGeneratedValue($useDoctrineCollections)) { $property->setValue($default); } diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 62008fc5..9f42ea9d 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -137,12 +137,14 @@ public function generate(OpenApi $openApi, array $config): array } // Second pass + $useInterface = $config['useInterface']; + $generateId = $config['id']['generate']; foreach ($classes as $class) { - if ($config['useInterface']) { + if ($useInterface) { (new ClassInterfaceMutator($config['namespaces']['interface']))($class, []); } - if ($config['id']['generate']) { + if ($generateId) { (new ClassIdAppender(new IdPropertyGenerator(), $config))($class, []); } diff --git a/src/Schema/Generator.php b/src/Schema/Generator.php index 6ef9ce04..ce34b1a6 100644 --- a/src/Schema/Generator.php +++ b/src/Schema/Generator.php @@ -45,8 +45,9 @@ public function generate(array $configuration, OutputInterface $output, SymfonyS $graphs[] = $graph; } + $relationsUris = $configuration['relations']['uris']; $relations = []; - foreach ($configuration['relations']['uris'] as $relation) { + foreach ($relationsUris as $relation) { $relations[] = new \SimpleXMLElement($relation, 0, true); } diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index efa3a252..1363063a 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -149,6 +149,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->range = $range; $schemaProperty->rangeName = $rangeName; $schemaProperty->type = $type; + $schemaProperty->defaultValue = $propertyConfig['defaultValue'] ?? null; $schemaProperty->cardinality = $cardinality; $schemaProperty->isReadable = $propertyConfig['readable'] ?? true; $schemaProperty->isWritable = $propertyConfig['writable'] ?? true; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 9eafd762..3ffe04bd 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -241,6 +241,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->booleanNode('readable')->defaultTrue()->info('Is the property readable?')->end() ->booleanNode('writable')->defaultTrue()->info('Is the property writable?')->end() ->booleanNode('nullable')->defaultNull()->info('Is the property nullable? (if null, cardinality will be used: will be true if no cardinality found)')->end() + ->variableNode('defaultValue')->defaultNull()->info('The property default value')->end() ->booleanNode('required')->defaultTrue()->info('Is the property required?')->end() ->booleanNode('unique')->defaultFalse()->info('The property unique')->end() ->booleanNode('embedded')->defaultFalse()->info('Is the property embedded?')->end() diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index 994df78e..feec7860 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -240,6 +240,9 @@ interface: null # Is the property nullable? (if null, cardinality will be used: will be true if no cardinality found) nullable: null + # The property default value + defaultValue: null + # Is the property required? required: true diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index c4a1645e..9dc6e4d2 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -206,6 +206,22 @@ public function testImplicitAndExplicitPropertyInheritance(): void $this->assertStringNotContainsString('setName(', $webPage); } + public function testPropertyDefault(): void + { + $outputDir = __DIR__.'/../../build/property-default'; + $config = __DIR__.'/../config/property-default.yaml'; + $this->fs->mkdir($outputDir); + $commandTester = new CommandTester(new GenerateCommand()); + $this->assertEquals(0, $commandTester->execute(['output' => $outputDir, 'config' => $config])); + + $book = file_get_contents("$outputDir/App/Entity/Book.php"); + + $this->assertStringContainsString(<<<'PHP' + private string $availability = 'https://schema.org/InStock'; +PHP + , $book); + } + public function testReadableWritable(): void { $outputDir = __DIR__.'/../../build/readable-writable'; diff --git a/tests/config/property-default.yaml b/tests/config/property-default.yaml new file mode 100644 index 00000000..d8f13345 --- /dev/null +++ b/tests/config/property-default.yaml @@ -0,0 +1,7 @@ +types: + ItemAvailability: ~ + Book: + properties: + availability: + range: ItemAvailability + defaultValue: "https://schema.org/InStock" From ab36e6dadc7e316ad10afcc99a2b15e0dbb43552 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 6 Sep 2022 17:15:55 +0200 Subject: [PATCH 229/258] ci: add PHP 8.1 (#364) --- .github/workflows/ci.yml | 9 +- composer.json | 2 +- composer.lock | 531 +++++++++--------- src/CardinalitiesExtractor.php | 5 +- src/ClassMutator/ClassParentMutator.php | 4 +- src/ClassMutator/ClassPropertiesAppender.php | 10 +- src/Schema/Model/Class_.php | 6 +- .../PropertyGenerator/PropertyGenerator.php | 9 +- src/TypesGenerator.php | 11 +- 9 files changed, 312 insertions(+), 275 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index ca0e7347..5afb1f63 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -16,8 +16,9 @@ jobs: php: - '7.4' - '8.0' + - '8.1' include: - - php: '8.0' + - php: '8.1' coverage: true steps: - uses: actions/checkout@v2 @@ -48,11 +49,11 @@ jobs: sudo chown -R $(whoami):$(whoami) . - name: Install dependencies - if: startsWith(matrix.php, '8.0') + if: startsWith(matrix.php, '8.1') run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Update dependencies - if: "!startsWith(matrix.php, '8.0')" + if: "!startsWith(matrix.php, '8.1')" run: composer update --no-interaction --no-progress --ansi - name: Enable code coverage @@ -75,7 +76,7 @@ jobs: run: vendor/bin/phpstan analyse --ansi - name: Run e2e tests - if: startsWith(matrix.php, '8.0') + if: startsWith(matrix.php, '8.') run: bin/compile - name: Upload coverage results to Coveralls diff --git a/composer.json b/composer.json index 9592efab..7b0d8786 100644 --- a/composer.json +++ b/composer.json @@ -35,7 +35,7 @@ "php": ">=7.4", "ext-json": "*", "doctrine/inflector": "^1.4.3 || ^2.0", - "easyrdf/easyrdf": "^1.1", + "sweetrdf/easyrdf": "^1.6", "friendsofphp/php-cs-fixer": "^2.15 || ^3.0", "league/html-to-markdown": "^5.0", "psr/log": "^1.0 || ^2.0 || ^3.0", diff --git a/composer.lock b/composer.lock index 96ee10db..6b9562a7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "90af9c60c6d77f881ef527556f6cc865", + "content-hash": "4688a43631493064d637c15f530b0486", "packages": [ { "name": "cebe/php-openapi", @@ -533,81 +533,6 @@ ], "time": "2022-02-28T11:07:21+00:00" }, - { - "name": "easyrdf/easyrdf", - "version": "1.1.1", - "source": { - "type": "git", - "url": "https://github.com/easyrdf/easyrdf.git", - "reference": "c7b0a9dbcb211eb7de03ee99ff5b52d17f2a8e64" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/easyrdf/easyrdf/zipball/c7b0a9dbcb211eb7de03ee99ff5b52d17f2a8e64", - "reference": "c7b0a9dbcb211eb7de03ee99ff5b52d17f2a8e64", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "ext-pcre": "*", - "ext-xmlreader": "*", - "lib-libxml": "*", - "php": ">=7.1.0" - }, - "require-dev": { - "code-lts/doctum": "^5", - "ml/json-ld": "~1.0", - "phpunit/phpunit": "^7", - "semsol/arc2": "^2.4", - "squizlabs/php_codesniffer": "3.*", - "zendframework/zend-http": "~2.3" - }, - "suggest": { - "ml/json-ld": "~1.0", - "semsol/arc2": "~2.2" - }, - "type": "library", - "autoload": { - "psr-4": { - "EasyRdf\\": "lib" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nicholas Humfrey", - "email": "njh@aelius.com", - "homepage": "http://www.aelius.com/njh/", - "role": "Developer" - }, - { - "name": "Alexey Zakhlestin", - "email": "indeyets@gmail.com", - "homepage": "http://indeyets.ru/", - "role": "Developer" - } - ], - "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", - "homepage": "http://www.easyrdf.org/", - "keywords": [ - "Linked Data", - "RDF", - "Semantic Web", - "Turtle", - "rdfa", - "sparql" - ], - "support": { - "forum": "http://groups.google.com/group/easyrdf/", - "issues": "http://github.com/easyrdf/easyrdf/issues", - "source": "https://github.com/easyrdf/easyrdf/tree/1.1.1" - }, - "time": "2020-12-02T08:47:31+00:00" - }, { "name": "friendsofphp/php-cs-fixer", "version": "v3.11.0", @@ -1334,29 +1259,104 @@ ], "time": "2020-10-26T13:10:38+00:00" }, + { + "name": "sweetrdf/easyrdf", + "version": "1.6", + "source": { + "type": "git", + "url": "https://github.com/sweetrdf/easyrdf.git", + "reference": "cd970ff3cb7c209958537d7d097324e6961e8ea9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/cd970ff3cb7c209958537d7d097324e6961e8ea9", + "reference": "cd970ff3cb7c209958537d7d097324e6961e8ea9", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "ext-pcre": "*", + "ext-xmlreader": "*", + "lib-libxml": "*", + "php": "^7.1|^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.0", + "ml/json-ld": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "semsol/arc2": "^2.4", + "zendframework/zend-http": "^2.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "EasyRdf\\": "lib" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nicholas Humfrey", + "email": "njh@aelius.com", + "homepage": "http://www.aelius.com/njh/", + "role": "Developer" + }, + { + "name": "Alexey Zakhlestin", + "email": "indeyets@gmail.com", + "homepage": "http://indeyets.ru/", + "role": "Developer" + }, + { + "name": "Konrad Abicht", + "email": "hi@inspirito.de", + "homepage": "http://inspirito.de/", + "role": "Maintainer, Developer" + } + ], + "description": "EasyRdf is a PHP library designed to make it easy to consume and produce RDF.", + "keywords": [ + "Linked Data", + "RDF", + "Semantic Web", + "Turtle", + "rdfa", + "sparql" + ], + "support": { + "issues": "https://github.com/sweetrdf/easyrdf/issues", + "source": "https://github.com/sweetrdf/easyrdf/tree/1.6" + }, + "time": "2022-08-08T09:12:46+00:00" + }, { "name": "symfony/config", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "956d4ec5df274dda91a4cedfccc2bfd063f6f649" + "reference": "a0645dc585d378b73c01115dd7ab9348f7d40c85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/956d4ec5df274dda91a4cedfccc2bfd063f6f649", - "reference": "956d4ec5df274dda91a4cedfccc2bfd063f6f649", + "url": "https://api.github.com/repos/symfony/config/zipball/a0645dc585d378b73c01115dd7ab9348f7d40c85", + "reference": "a0645dc585d378b73c01115dd7ab9348f7d40c85", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.1|^3", "symfony/filesystem": "^5.4|^6.0", - "symfony/polyfill-ctype": "~1.8", - "symfony/polyfill-php81": "^1.22" + "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<4.4" + "symfony/finder": "<5.4" }, "require-dev": { "symfony/event-dispatcher": "^5.4|^6.0", @@ -1394,7 +1394,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v6.0.11" + "source": "https://github.com/symfony/config/tree/v6.1.3" }, "funding": [ { @@ -1410,24 +1410,25 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:10:44+00:00" + "time": "2022-07-20T15:00:40+00:00" }, { "name": "symfony/console", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "c5c2e313aa682530167c25077d6bdff36346251e" + "reference": "7fccea8728aa2d431a6725b02b3ce759049fc84d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/c5c2e313aa682530167c25077d6bdff36346251e", - "reference": "c5c2e313aa682530167c25077d6bdff36346251e", + "url": "https://api.github.com/repos/symfony/console/zipball/7fccea8728aa2d431a6725b02b3ce759049fc84d", + "reference": "7fccea8728aa2d431a6725b02b3ce759049fc84d", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^1.1|^2|^3", "symfony/string": "^5.4|^6.0" @@ -1489,7 +1490,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.0.12" + "source": "https://github.com/symfony/console/tree/v6.1.4" }, "funding": [ { @@ -1505,29 +1506,29 @@ "type": "tidelift" } ], - "time": "2022-08-23T20:52:30+00:00" + "time": "2022-08-26T10:32:31+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.0.2", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c" + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", - "reference": "26954b3d62a6c5fd0ea8a2a00c0353a14978d05c", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.1-dev" }, "thanks": { "name": "symfony/contracts", @@ -1556,7 +1557,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.2" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" }, "funding": [ { @@ -1572,24 +1573,24 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-02-25T11:15:52+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.0.9", + "version": "v6.1.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "5c85b58422865d42c6eb46f7693339056db098a8" + "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/5c85b58422865d42c6eb46f7693339056db098a8", - "reference": "5c85b58422865d42c6eb46f7693339056db098a8", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/event-dispatcher-contracts": "^2|^3" }, "conflict": { @@ -1639,7 +1640,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.0.9" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0" }, "funding": [ { @@ -1655,24 +1656,24 @@ "type": "tidelift" } ], - "time": "2022-05-05T16:45:52+00:00" + "time": "2022-05-05T16:51:07+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.0.2", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "7bc61cc2db649b4637d331240c5346dcc7708051" + "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7bc61cc2db649b4637d331240c5346dcc7708051", - "reference": "7bc61cc2db649b4637d331240c5346dcc7708051", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", + "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/event-dispatcher": "^1" }, "suggest": { @@ -1681,7 +1682,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.1-dev" }, "thanks": { "name": "symfony/contracts", @@ -1718,7 +1719,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.0.2" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" }, "funding": [ { @@ -1734,24 +1735,24 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-02-25T11:15:52+00:00" }, { "name": "symfony/filesystem", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "a36b782dc19dce3ab7e47d4b92b13cefb3511da3" + "reference": "3f39c04d2630c34019907b02f85672dac99f8659" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/a36b782dc19dce3ab7e47d4b92b13cefb3511da3", - "reference": "a36b782dc19dce3ab7e47d4b92b13cefb3511da3", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/3f39c04d2630c34019907b02f85672dac99f8659", + "reference": "3f39c04d2630c34019907b02f85672dac99f8659", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, @@ -1781,7 +1782,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.0.12" + "source": "https://github.com/symfony/filesystem/tree/v6.1.4" }, "funding": [ { @@ -1797,24 +1798,27 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:01:06+00:00" + "time": "2022-08-02T16:17:38+00:00" }, { "name": "symfony/finder", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "09cb683ba5720385ea6966e5e06be2a34f2568b1" + "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/09cb683ba5720385ea6966e5e06be2a34f2568b1", - "reference": "09cb683ba5720385ea6966e5e06be2a34f2568b1", + "url": "https://api.github.com/repos/symfony/finder/zipball/39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" + }, + "require-dev": { + "symfony/filesystem": "^6.0" }, "type": "library", "autoload": { @@ -1842,7 +1846,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.0.11" + "source": "https://github.com/symfony/finder/tree/v6.1.3" }, "funding": [ { @@ -1858,24 +1862,24 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:39:48+00:00" + "time": "2022-07-29T07:42:06+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.0.3", + "version": "v6.1.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "51f7006670febe4cbcbae177cbffe93ff833250d" + "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/51f7006670febe4cbcbae177cbffe93ff833250d", - "reference": "51f7006670febe4cbcbae177cbffe93ff833250d", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a3016f5442e28386ded73c43a32a5b68586dd1c4", + "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.1|^3" }, "type": "library", @@ -1909,7 +1913,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.0.3" + "source": "https://github.com/symfony/options-resolver/tree/v6.1.0" }, "funding": [ { @@ -1925,7 +1929,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-02-25T11:15:52+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2421,20 +2425,20 @@ }, { "name": "symfony/process", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "44270a08ccb664143dede554ff1c00aaa2247a43" + "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/44270a08ccb664143dede554ff1c00aaa2247a43", - "reference": "44270a08ccb664143dede554ff1c00aaa2247a43", + "url": "https://api.github.com/repos/symfony/process/zipball/a6506e99cfad7059b1ab5cab395854a0a0c21292", + "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "type": "library", "autoload": { @@ -2462,7 +2466,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v6.0.11" + "source": "https://github.com/symfony/process/tree/v6.1.3" }, "funding": [ { @@ -2478,24 +2482,24 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:10:44+00:00" + "time": "2022-06-27T17:24:16+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.0.2", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66" + "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d78d39c1599bd1188b8e26bb341da52c3c6d8a66", - "reference": "d78d39c1599bd1188b8e26bb341da52c3c6d8a66", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", + "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/container": "^2.0" }, "conflict": { @@ -2507,7 +2511,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.1-dev" }, "thanks": { "name": "symfony/contracts", @@ -2517,7 +2521,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Service\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -2544,7 +2551,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.0.2" + "source": "https://github.com/symfony/service-contracts/tree/v3.1.1" }, "funding": [ { @@ -2560,24 +2567,24 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:17:58+00:00" + "time": "2022-05-30T19:18:58+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.0.5", + "version": "v6.1.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "f2c1780607ec6502f2121d9729fd8150a655d337" + "reference": "77dedae82ce2a26e2e9b481855473fc3b3e4e54d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/f2c1780607ec6502f2121d9729fd8150a655d337", - "reference": "f2c1780607ec6502f2121d9729fd8150a655d337", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/77dedae82ce2a26e2e9b481855473fc3b3e4e54d", + "reference": "77dedae82ce2a26e2e9b481855473fc3b3e4e54d", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/service-contracts": "^1|^2|^3" }, "type": "library", @@ -2606,7 +2613,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.0.5" + "source": "https://github.com/symfony/stopwatch/tree/v6.1.0" }, "funding": [ { @@ -2622,24 +2629,24 @@ "type": "tidelift" } ], - "time": "2022-02-21T17:15:17+00:00" + "time": "2022-02-25T11:15:52+00:00" }, { "name": "symfony/string", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "3a975ba1a1508ad97df45f4590f55b7cc4c1a0a0" + "reference": "290972cad7b364e3befaa74ba0ec729800fb161c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/3a975ba1a1508ad97df45f4590f55b7cc4c1a0a0", - "reference": "3a975ba1a1508ad97df45f4590f55b7cc4c1a0a0", + "url": "https://api.github.com/repos/symfony/string/zipball/290972cad7b364e3befaa74ba0ec729800fb161c", + "reference": "290972cad7b364e3befaa74ba0ec729800fb161c", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -2691,7 +2698,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.0.12" + "source": "https://github.com/symfony/string/tree/v6.1.4" }, "funding": [ { @@ -2707,24 +2714,24 @@ "type": "tidelift" } ], - "time": "2022-08-12T18:05:20+00:00" + "time": "2022-08-12T18:05:43+00:00" }, { "name": "symfony/yaml", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "8c68efb08b038ec02753da6f16e1601a6ed4ef17" + "reference": "86ee4d8fa594ed45e40d86eedfda1bcb66c8d919" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/8c68efb08b038ec02753da6f16e1601a6ed4ef17", - "reference": "8c68efb08b038ec02753da6f16e1601a6ed4ef17", + "url": "https://api.github.com/repos/symfony/yaml/zipball/86ee4d8fa594ed45e40d86eedfda1bcb66c8d919", + "reference": "86ee4d8fa594ed45e40d86eedfda1bcb66c8d919", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -2765,7 +2772,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.0.12" + "source": "https://github.com/symfony/yaml/tree/v6.1.4" }, "funding": [ { @@ -2781,7 +2788,7 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:01:06+00:00" + "time": "2022-08-02T16:17:38+00:00" }, { "name": "twig/twig", @@ -5801,22 +5808,22 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "203153a2596e7e2b3eb28a7e0d4e301955d64b2e" + "reference": "68b53b14f337dbc6f92cf6f1656a0adad42482e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/203153a2596e7e2b3eb28a7e0d4e301955d64b2e", - "reference": "203153a2596e7e2b3eb28a7e0d4e301955d64b2e", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/68b53b14f337dbc6f92cf6f1656a0adad42482e0", + "reference": "68b53b14f337dbc6f92cf6f1656a0adad42482e0", "shasum": "" }, "require": { "doctrine/event-manager": "~1.0", "doctrine/persistence": "^2|^3", - "php": ">=8.0.2", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", @@ -5896,7 +5903,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.0.11" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.1.3" }, "funding": [ { @@ -5912,24 +5919,24 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:39:48+00:00" + "time": "2022-07-29T07:42:06+00:00" }, { "name": "symfony/error-handler", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "cb302377e1b862540436f22be9ff07079a5836ae" + "reference": "736e42db3fd586d91820355988698e434e1d8419" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/cb302377e1b862540436f22be9ff07079a5836ae", - "reference": "cb302377e1b862540436f22be9ff07079a5836ae", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/736e42db3fd586d91820355988698e434e1d8419", + "reference": "736e42db3fd586d91820355988698e434e1d8419", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/log": "^1|^2|^3", "symfony/var-dumper": "^5.4|^6.0" }, @@ -5967,7 +5974,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.0.11" + "source": "https://github.com/symfony/error-handler/tree/v6.1.3" }, "funding": [ { @@ -5983,24 +5990,24 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:39:48+00:00" + "time": "2022-07-29T07:42:06+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d50ee4795c981638369dfa0b281107365fab2429" + "reference": "18e0f106a32887bcebef757e5b39c88e39a08f20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d50ee4795c981638369dfa0b281107365fab2429", - "reference": "d50ee4795c981638369dfa0b281107365fab2429", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/18e0f106a32887bcebef757e5b39c88e39a08f20", + "reference": "18e0f106a32887bcebef757e5b39c88e39a08f20", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.1" }, @@ -6042,7 +6049,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.0.12" + "source": "https://github.com/symfony/http-foundation/tree/v6.1.4" }, "funding": [ { @@ -6058,26 +6065,26 @@ "type": "tidelift" } ], - "time": "2022-08-19T14:25:15+00:00" + "time": "2022-08-19T14:27:04+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "8f3563e4518cfee24a5cc724434cc60e0818abec" + "reference": "2144c53a278254af57fa1e6f71427be656fab6f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/8f3563e4518cfee24a5cc724434cc60e0818abec", - "reference": "8f3563e4518cfee24a5cc724434cc60e0818abec", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2144c53a278254af57fa1e6f71427be656fab6f4", + "reference": "2144c53a278254af57fa1e6f71427be656fab6f4", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/error-handler": "^5.4|^6.0", + "symfony/error-handler": "^6.1", "symfony/event-dispatcher": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", "symfony/polyfill-ctype": "^1.8" @@ -6085,9 +6092,9 @@ "conflict": { "symfony/browser-kit": "<5.4", "symfony/cache": "<5.4", - "symfony/config": "<5.4", + "symfony/config": "<6.1", "symfony/console": "<5.4", - "symfony/dependency-injection": "<5.4", + "symfony/dependency-injection": "<6.1", "symfony/doctrine-bridge": "<5.4", "symfony/form": "<5.4", "symfony/http-client": "<5.4", @@ -6104,10 +6111,10 @@ "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", "symfony/browser-kit": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", + "symfony/config": "^6.1", "symfony/console": "^5.4|^6.0", "symfony/css-selector": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", + "symfony/dependency-injection": "^6.1", "symfony/dom-crawler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/finder": "^5.4|^6.0", @@ -6117,6 +6124,7 @@ "symfony/stopwatch": "^5.4|^6.0", "symfony/translation": "^5.4|^6.0", "symfony/translation-contracts": "^1.1|^2|^3", + "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" }, "suggest": { @@ -6151,7 +6159,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.0.12" + "source": "https://github.com/symfony/http-kernel/tree/v6.1.4" }, "funding": [ { @@ -6167,7 +6175,7 @@ "type": "tidelift" } ], - "time": "2022-08-26T14:45:39+00:00" + "time": "2022-08-26T14:50:30+00:00" }, { "name": "symfony/phpunit-bridge", @@ -6330,20 +6338,20 @@ }, { "name": "symfony/property-access", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "8299bd756989ef04be53e2099e6b6fd5154a03ed" + "reference": "25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/8299bd756989ef04be53e2099e6b6fd5154a03ed", - "reference": "8299bd756989ef04be53e2099e6b6fd5154a03ed", + "url": "https://api.github.com/repos/symfony/property-access/zipball/25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5", + "reference": "25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/property-info": "^5.4|^6.0" }, "require-dev": { @@ -6389,7 +6397,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.0.11" + "source": "https://github.com/symfony/property-access/tree/v6.1.3" }, "funding": [ { @@ -6405,29 +6413,29 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:10:44+00:00" + "time": "2022-06-27T17:24:16+00:00" }, { "name": "symfony/property-info", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "518f172491b9c09afd5d963f783909b80c4b0308" + "reference": "2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/518f172491b9c09afd5d963f783909b80c4b0308", - "reference": "518f172491b9c09afd5d963f783909b80c4b0308", + "url": "https://api.github.com/repos/symfony/property-info/zipball/2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8", + "reference": "2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/string": "^5.4|^6.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", - "phpdocumentor/type-resolver": "<1.4.0", + "phpdocumentor/type-resolver": "<1.5.1", "symfony/dependency-injection": "<5.4" }, "require-dev": { @@ -6478,7 +6486,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.0.11" + "source": "https://github.com/symfony/property-info/tree/v6.1.3" }, "funding": [ { @@ -6494,24 +6502,24 @@ "type": "tidelift" } ], - "time": "2022-07-19T08:33:44+00:00" + "time": "2022-07-19T08:34:05+00:00" }, { "name": "symfony/serializer", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "18c9a8101edd84f383f440727052a1926d1e3639" + "reference": "03e5987dd9bb98038c60c7af3e58500c81c4aec1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/18c9a8101edd84f383f440727052a1926d1e3639", - "reference": "18c9a8101edd84f383f440727052a1926d1e3639", + "url": "https://api.github.com/repos/symfony/serializer/zipball/03e5987dd9bb98038c60c7af3e58500c81c4aec1", + "reference": "03e5987dd9bb98038c60c7af3e58500c81c4aec1", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -6579,7 +6587,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.0.12" + "source": "https://github.com/symfony/serializer/tree/v6.1.4" }, "funding": [ { @@ -6595,24 +6603,24 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:20+00:00" + "time": "2022-08-26T10:32:31+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.0.2", + "version": "v3.1.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282" + "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/acbfbb274e730e5a0236f619b6168d9dedb3e282", - "reference": "acbfbb274e730e5a0236f619b6168d9dedb3e282", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc", + "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc", "shasum": "" }, "require": { - "php": ">=8.0.2" + "php": ">=8.1" }, "suggest": { "symfony/translation-implementation": "" @@ -6620,7 +6628,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "3.1-dev" }, "thanks": { "name": "symfony/contracts", @@ -6630,7 +6638,10 @@ "autoload": { "psr-4": { "Symfony\\Contracts\\Translation\\": "" - } + }, + "exclude-from-classmap": [ + "/Test/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6657,7 +6668,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.0.2" + "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1" }, "funding": [ { @@ -6673,27 +6684,27 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:10:44+00:00" + "time": "2022-06-27T17:24:16+00:00" }, { "name": "symfony/validator", - "version": "v6.0.12", + "version": "v6.1.4", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "0987eb0c390d5686768ea2bb388c81494ea4508f" + "reference": "14ec426b9c8ca8cf02bd863a645fb0cc0d73db79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/0987eb0c390d5686768ea2bb388c81494ea4508f", - "reference": "0987eb0c390d5686768ea2bb388c81494ea4508f", + "url": "https://api.github.com/repos/symfony/validator/zipball/14ec426b9c8ca8cf02bd863a645fb0cc0d73db79", + "reference": "14ec426b9c8ca8cf02bd863a645fb0cc0d73db79", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php81": "^1.22", "symfony/translation-contracts": "^1.1|^2|^3" }, "conflict": { @@ -6765,7 +6776,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.0.12" + "source": "https://github.com/symfony/validator/tree/v6.1.4" }, "funding": [ { @@ -6781,24 +6792,24 @@ "type": "tidelift" } ], - "time": "2022-08-12T13:08:57+00:00" + "time": "2022-08-12T13:09:07+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.0.11", + "version": "v6.1.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "2672bdc01c1971e3d8879ce153ec4c3621be5f07" + "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/2672bdc01c1971e3d8879ce153ec4c3621be5f07", - "reference": "2672bdc01c1971e3d8879ce153ec4c3621be5f07", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", + "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { @@ -6853,7 +6864,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.0.11" + "source": "https://github.com/symfony/var-dumper/tree/v6.1.3" }, "funding": [ { @@ -6869,24 +6880,24 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:45:53+00:00" + "time": "2022-07-20T13:46:29+00:00" }, { "name": "symfony/web-link", - "version": "v6.0.3", + "version": "v6.1.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "52d6af6c4476c8ebdef968cb39030826253eb5e4" + "reference": "d6ef738f97b60d859652d92f10bf8645bca28cd6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/52d6af6c4476c8ebdef968cb39030826253eb5e4", - "reference": "52d6af6c4476c8ebdef968cb39030826253eb5e4", + "url": "https://api.github.com/repos/symfony/web-link/zipball/d6ef738f97b60d859652d92f10bf8645bca28cd6", + "reference": "d6ef738f97b60d859652d92f10bf8645bca28cd6", "shasum": "" }, "require": { - "php": ">=8.0.2", + "php": ">=8.1", "psr/link": "^1.1|^2.0" }, "conflict": { @@ -6939,7 +6950,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v6.0.3" + "source": "https://github.com/symfony/web-link/tree/v6.1.0" }, "funding": [ { @@ -6955,7 +6966,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:55:41+00:00" + "time": "2022-02-25T11:15:52+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index 4674defe..78df057f 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -100,7 +100,10 @@ private function extractForProperty(RdfResource $property): string return self::CARDINALITY_UNKNOWN; } - $localName = $property->localName(); + if (!\is_string($localName = $property->localName())) { + return self::CARDINALITY_UNKNOWN; + } + $fromGoodRelations = $this->goodRelationsBridge->extractCardinality($localName); if (false !== $fromGoodRelations) { return $fromGoodRelations; diff --git a/src/ClassMutator/ClassParentMutator.php b/src/ClassMutator/ClassParentMutator.php index 6cd4b745..9d05a4f6 100644 --- a/src/ClassMutator/ClassParentMutator.php +++ b/src/ClassMutator/ClassParentMutator.php @@ -53,7 +53,9 @@ public function __invoke(Class_ $class, array $context): void $this->logger ? $this->logger->info(sprintf('The type "%s" has several supertypes. Using the first one.', $class->rdfType())) : null; } - $class->withParent($this->phpTypeConverter->escapeIdentifier($subclassOf[0]->localName())); + if (\is_string($parentLocalName = $subclassOf[0]->localName())) { + $class->withParent($this->phpTypeConverter->escapeIdentifier($parentLocalName)); + } } if ($class->hasParent() && isset($this->config['types'][$class->parent()]['namespaces']['class'])) { diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index e6d799db..988d135c 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -88,7 +88,9 @@ public function __invoke(Class_ $class, array $context): void } // All properties foreach ($this->propertiesMap[$class->rdfType()] ?? [] as $property) { - unset($remainingProperties[$property->localName()]); + if (\is_string($property->localName())) { + unset($remainingProperties[$property->localName()]); + } if ($property->hasProperty(self::SCHEMA_ORG_SUPERSEDED_BY)) { $supersededBy = $property->get(self::SCHEMA_ORG_SUPERSEDED_BY); $this->logger ? $this->logger->info(sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())) : null; @@ -131,7 +133,11 @@ private function generateCustomField(string $propertyName, RdfResource $type, ?a */ private function generateField(array $config, SchemaClass $class, RdfResource $type, ?array $typeConfig, array $cardinalities, RdfResource $typeProperty, bool $isCustom = false): void { - $property = ($this->propertyGenerator)($typeProperty->localName(), $config, $class, ['type' => $type, 'typeConfig' => $typeConfig, 'cardinalities' => $cardinalities, 'property' => $typeProperty], $isCustom); + $property = null; + + if (\is_string($typeProperty->localName())) { + $property = ($this->propertyGenerator)($typeProperty->localName(), $config, $class, ['type' => $type, 'typeConfig' => $typeConfig, 'cardinalities' => $cardinalities, 'property' => $typeProperty], $isCustom); + } if ($property) { $class->addProperty($property); diff --git a/src/Schema/Model/Class_.php b/src/Schema/Model/Class_.php index 2d4a1d5d..24118617 100644 --- a/src/Schema/Model/Class_.php +++ b/src/Schema/Model/Class_.php @@ -51,7 +51,11 @@ public function description(): ?string public function shortName(): string { - return $this->resource->localName(); + if (\is_string($shortName = $this->resource->localName())) { + return $shortName; + } + + return $this->name(); } /** diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 1363063a..e10b248c 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -108,7 +108,9 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $range = new RdfResource($mappedUri); } - $rangeName = $this->phpTypeConverter->escapeIdentifier($range->localName()); + if (\is_string($range->localName())) { + $rangeName = $this->phpTypeConverter->escapeIdentifier($range->localName()); + } } if (!$ranges) { @@ -172,7 +174,10 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont */ private function getRanges(RdfResource $range, ?array $propertyConfig, array $config): array { - $localName = $range->localName(); + $localName = null; + if (\is_string($range->localName())) { + $localName = $range->localName(); + } $dataType = (bool) $this->typeConverter->getType($range); if (!$dataType) { if (null !== ($unionOf = $range->get('owl:unionOf'))) { diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index ebad9102..d7d26ca3 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -175,7 +175,9 @@ public function generate(array $graphs, array $config): array if (($config['types'][$class->name()]['allProperties'] ?? true) && isset($classes[$class->parent()])) { $type = $class->resource(); foreach ($propertiesMap[$type->getUri()] as $property) { - $propertyName = $property->localName(); + if (!\is_string($propertyName = $property->localName())) { + continue; + } if (!$class->hasProperty($propertyName)) { continue; } @@ -350,7 +352,7 @@ private function createPropertiesMap(array $graphs, array $types, array $config) $typesResources[] = [ 'resources' => $parentClasses, 'uris' => array_map(static fn (RdfResource $parentClass) => $parentClass->getUri(), $parentClasses), - 'names' => array_map(fn (RdfResource $parentClass) => $this->phpTypeConverter->escapeIdentifier($parentClass->localName()), $parentClasses), + 'names' => array_map(fn (RdfResource $parentClass) => \is_string($parentClass->localName()) ? $this->phpTypeConverter->escapeIdentifier($parentClass->localName()) : $parentClass->getUri(), $parentClasses), ]; $map[$type->getUri()] = []; } @@ -382,7 +384,10 @@ private function createPropertiesMap(array $graphs, array $types, array $config) */ private function addPropertyToMap(RdfResource $property, RdfResource $domain, array $typesResources, array $config, array &$map): void { - $propertyName = $property->localName(); + $propertyName = $property->getUri(); + if (\is_string($property->localName())) { + $propertyName = $property->localName(); + } $deprecated = $property->isA('owl:DeprecatedProperty'); if ($domain->isBNode()) { From 39b9d30381b27085aef030c27e27661ac3de9a15 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 6 Sep 2022 17:36:32 +0200 Subject: [PATCH 230/258] chore: update CHANGELOG --- CHANGELOG.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c7531ca8..61495ebf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,20 @@ # Changelog +## 5.0.0 + +* feat: add OpenAPI support +* feat: add API Platform 2.7/3 attributes generation +* feat: custom attributes and custom attribute arguments +* feat: add Doctrine ORM inheritance support (discriminator) +* feat: manage association overrides for Doctrine ORM +* feat: add `defaultCardinality` configuration for relations +* feat: add `defaultValue` in property configuration +* feat: add `resolveTypes` and `allTypes` parameters +* refactor: better handling of data type (including lang string) +* fix: self-referencing relations (Doctrine ORM) +* fix: update reserved keywords +* fix: remove simple in ODM attributes + ## 4.0.1 * fix: use FQCN when using an enum in callback constraint and remove ApiResource from the enum From add3b562be8102d633ffc1c0c3f588ced2a22be1 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 6 Sep 2022 17:59:53 +0200 Subject: [PATCH 231/258] ci: update release workflow --- .github/workflows/ci.yml | 8 ++++---- .github/workflows/release.yml | 26 ++++++-------------------- 2 files changed, 10 insertions(+), 24 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5afb1f63..47ac4d71 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,13 +21,13 @@ jobs: - php: '8.1' coverage: true steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Get Composer Cache Directory id: composer-cache run: echo "::set-output name=dir::$(composer config cache-files-dir)" - - uses: actions/cache@v2 + - uses: actions/cache@v3 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} @@ -44,7 +44,7 @@ jobs: - name: Install prerequisites run: | - wget -O box.phar https://github.com/humbug/box/releases/download/3.13.0/box.phar + wget -O box.phar https://github.com/humbug/box/releases/download/4.0.2/box.phar echo "BOX_BIN=$(pwd)/box.phar" >> $GITHUB_ENV sudo chown -R $(whoami):$(whoami) . @@ -76,7 +76,7 @@ jobs: run: vendor/bin/phpstan analyse --ansi - name: Run e2e tests - if: startsWith(matrix.php, '8.') + if: startsWith(matrix.php, '8.1') run: bin/compile - name: Upload coverage results to Coveralls diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5065ace0..616593ae 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,12 +13,12 @@ jobs: upload_url: ${{ steps.step_upload_url.outputs.upload_url }} steps: - name: Checkout code - uses: actions/checkout@v2 + uses: actions/checkout@v3 - name: Setup PHP with extensions uses: shivammathur/setup-php@v2 with: - php-version: '8.0' + php-version: '8.1' extensions: json ini-values: memory_limit=-1 tools: composer @@ -27,30 +27,16 @@ jobs: run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Download box.phar - run: wget -O box.phar https://github.com/humbug/box/releases/download/3.13.0/box.phar + run: wget -O box.phar https://github.com/humbug/box/releases/download/4.0.2/box.phar - name: Compile project run: php ./box.phar compile - name: Create Release - id: create_release - uses: actions/create-release@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + uses: softprops/action-gh-release@v1 with: - tag_name: ${{ github.ref }} - release_name: Release ${{ github.ref }} + name: Release ${{ github.ref }} body: '' draft: false prerelease: false - - - name: Upload Release Asset - id: upload-release-asset - uses: actions/upload-release-asset@v1 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - upload_url: ${{ steps.create_release.outputs.upload_url }} - asset_path: ./schema.phar - asset_name: schema.phar - asset_content_type: application/x-php + files: schema.phar From 3da765399e18bd12b81cd5ec13146fc198d8102f Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 6 Sep 2022 18:17:50 +0200 Subject: [PATCH 232/258] ci: use ref_name for release workflow --- .github/workflows/release.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 616593ae..3a98fd1d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,7 +35,7 @@ jobs: - name: Create Release uses: softprops/action-gh-release@v1 with: - name: Release ${{ github.ref }} + name: Release ${{ github.ref_name }} body: '' draft: false prerelease: false From 9aa7f65df0b4ac384165c992cc436526ddfe7a7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Suwi=C5=84ski?= Date: Wed, 14 Sep 2022 11:08:31 +0200 Subject: [PATCH 233/258] fix: dateTime resolving (#393) --- src/AttributeGenerator/DoctrineOrmAttributeGenerator.php | 7 +++++-- tests/e2e/original/App/OpenApi/Entity/Book.php | 4 ++-- tests/e2e/original/App/OpenApi/Entity/Order.php | 2 +- tests/e2e/original/App/OpenApi/Entity/Review.php | 2 +- 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 42939fc6..53632ca6 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -108,9 +108,12 @@ public function generatePropertyAttributes(Property $property, string $className case 'time': $type = 'time'; break; - case 'dateTime': + case 'date': $type = 'date'; break; + case 'dateTime': + $type = 'datetime'; + break; default: $type = $phpType; switch ($phpType) { @@ -124,7 +127,7 @@ public function generatePropertyAttributes(Property $property, string $className $type = 'text'; break; case '\\'.\DateTimeInterface::class: - $type = 'date'; + $type = 'datetime'; break; case '\\'.\DateInterval::class: $type = 'string'; diff --git a/tests/e2e/original/App/OpenApi/Entity/Book.php b/tests/e2e/original/App/OpenApi/Entity/Book.php index 98866007..0a85996b 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Book.php +++ b/tests/e2e/original/App/OpenApi/Entity/Book.php @@ -76,7 +76,7 @@ class Book * * @see https://schema.org/dateCreated */ - #[ORM\Column(type: 'date')] + #[ORM\Column(type: 'datetime')] #[ApiProperty(types: ['https://schema.org/dateCreated'])] #[Assert\Type(\DateTimeInterface::class)] #[Assert\NotNull] @@ -101,7 +101,7 @@ class Book #[ApiProperty] private ?string $cover = null; - #[ORM\Column(type: 'date', nullable: true)] + #[ORM\Column(type: 'datetime', nullable: true)] #[ApiProperty] #[Assert\Type(\DateTimeInterface::class)] private ?\DateTimeInterface $archivedAt = null; diff --git a/tests/e2e/original/App/OpenApi/Entity/Order.php b/tests/e2e/original/App/OpenApi/Entity/Order.php index 5626eca8..3739099a 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Order.php +++ b/tests/e2e/original/App/OpenApi/Entity/Order.php @@ -33,7 +33,7 @@ class Order #[Assert\NotNull] private int $quantity; - #[ORM\Column(type: 'date')] + #[ORM\Column(type: 'datetime')] #[ApiProperty] #[Assert\Type(\DateTimeInterface::class)] #[Assert\NotNull] diff --git a/tests/e2e/original/App/OpenApi/Entity/Review.php b/tests/e2e/original/App/OpenApi/Entity/Review.php index 34e2fdb1..fc9e2c0e 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Review.php +++ b/tests/e2e/original/App/OpenApi/Entity/Review.php @@ -78,7 +78,7 @@ class Review /** * Publication date of the review. */ - #[ORM\Column(type: 'date', nullable: true)] + #[ORM\Column(type: 'datetime', nullable: true)] #[ApiProperty] #[Assert\Type(\DateTimeInterface::class)] private ?\DateTimeInterface $publicationDate = null; From f737d780d4122704efa8b229f402a7d3b18a64b6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Pawe=C5=82=20Suwi=C5=84ski?= Date: Mon, 3 Oct 2022 18:03:59 +0200 Subject: [PATCH 234/258] feat: repeatable attributes support (#394) Co-authored-by: Alan Poulain --- CHANGELOG.md | 4 ++ phpstan.neon | 8 +-- .../ConfigurationAttributeGenerator.php | 51 +++++++++++++++---- .../DoctrineMongoDBAttributeGenerator.php | 6 ++- .../DoctrineOrmAttributeGenerator.php | 6 ++- src/Model/AddAttributeTrait.php | 9 +++- src/Model/Attribute.php | 16 +++++- src/SchemaGeneratorConfiguration.php | 12 ++--- .../ConfigurationAttributeGeneratorTest.php | 17 ++++--- tests/Command/GenerateCommandTest.php | 13 +++++ tests/config/custom-attributes.yaml | 7 +++ .../customized/App/Schema/Entity/Person.php | 1 + .../e2e/original/App/Schema/Entity/Person.php | 3 +- tests/e2e/schema.yml | 4 ++ 14 files changed, 121 insertions(+), 36 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 61495ebf..2112f4c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.1.0 + +* feat: repeatable attributes support + ## 5.0.0 * feat: add OpenAPI support diff --git a/phpstan.neon b/phpstan.neon index 529d82ba..5d285b4b 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -18,7 +18,7 @@ parameters: required: ?boolean, unique: boolean, embedded: boolean, - attributes: array + attributes: list> } ''' TypeConfiguration: ''' @@ -28,7 +28,7 @@ parameters: abstract: ?boolean, embeddable: boolean, namespaces: array{class: ?string, interface: ?string}, - attributes: array, + attributes: list>, parent: false|string, guessFrom: string, operations: array>, @@ -38,7 +38,7 @@ parameters: ''' Configuration: ''' array{ - vocabularies: array{uri: string, format: string, allTypes: ?boolean, attributes: array}[], + vocabularies: array{uri: string, format: string, allTypes: ?boolean, attributes: list>}[], vocabularyNamespace: string, relations: array{uris: string[], defaultCardinality: string}, debug: boolean, @@ -53,7 +53,7 @@ parameters: useCollection: boolean, resolveTargetEntityConfigPath: ?string, resolveTargetEntityConfigType: 'XML'|'yaml', - inheritanceAttributes: array, + inheritanceAttributes: list>, inheritanceType: 'JOINED'|'SINGLE_TABLE'|'SINGLE_COLLECTION'|'TABLE_PER_CLASS'|'COLLECTION_PER_CLASS'|'NONE', maxIdentifierLength: integer }, diff --git a/src/AttributeGenerator/ConfigurationAttributeGenerator.php b/src/AttributeGenerator/ConfigurationAttributeGenerator.php index bf13ee45..30d7d46a 100644 --- a/src/AttributeGenerator/ConfigurationAttributeGenerator.php +++ b/src/AttributeGenerator/ConfigurationAttributeGenerator.php @@ -26,16 +26,44 @@ final class ConfigurationAttributeGenerator extends AbstractAttributeGenerator */ public function generateClassAttributes(Class_ $class): array { - $typeConfig = $this->config['types'][$class->name()] ?? null; - $vocabConfig = null; + $typeAttributes = $this->config['types'][$class->name()]['attributes'] ?? [[]]; + $vocabAttributes = [[]]; if ($class instanceof SchemaClass) { - $vocabConfig = $this->config['vocabularies'][$class->resource()->getGraph()->getUri()] ?? null; + $vocabAttributes = $this->config['vocabularies'][$class->resource()->getGraph()->getUri()]['attributes'] ?? [[]]; } + $getAttributesNames = static fn (array $config) => $config === [[]] + ? [] + : array_unique(array_map(fn (array $v) => array_keys($v)[0], $config)); + $typeAttributesNames = $getAttributesNames($typeAttributes); + $vocabAttributesNames = $getAttributesNames($vocabAttributes); + + $getAttribute = static fn (string $name, array $args) => new Attribute( + $name, + $args + [ + // An attribute from a vocabulary cannot be appended if a same one has not + // previously been generated or if the same one is not mergeable. + // It allows vocabulary attributes configuration to only merge the attributes args. + 'alwaysGenerate' => !\in_array($name, $vocabAttributesNames, true) || + \in_array($name, $typeAttributesNames, true), + // Custom explicitly configured attributes is not mergeable with next one + // but treated as repeated if given more than once. + 'mergeable' => false, + ] + ); + $attributes = []; - $configAttributes = array_merge($vocabConfig['attributes'] ?? [], $typeConfig['attributes'] ?? []); - foreach ($configAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, ($attributeArgs ?? []) + ['alwaysGenerate' => !isset($vocabConfig['attributes'][$attributeName]) || isset($typeConfig['attributes'][$attributeName])]); + foreach ($vocabAttributes as $configAttributes) { + foreach ($configAttributes as $attributeName => $attributeArgs) { + if (!\in_array($attributeName, $typeAttributesNames, true)) { + $attributes[] = $getAttribute($attributeName, $attributeArgs ?? []); + } + } + } + foreach ($typeAttributes as $configAttributes) { + foreach ($configAttributes as $attributeName => $attributeArgs) { + $attributes[] = $getAttribute($attributeName, $attributeArgs ?? []); + } } return $attributes; @@ -47,11 +75,16 @@ public function generateClassAttributes(Class_ $class): array public function generatePropertyAttributes(Property $property, string $className): array { $typeConfig = $this->config['types'][$className] ?? null; - $propertyConfig = $typeConfig['properties'][$property->name()] ?? null; + $propertyAttributes = $typeConfig['properties'][$property->name()]['attributes'] ?? [[]]; $attributes = []; - foreach ($propertyConfig['attributes'] ?? [] as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs ?? []); + foreach ($propertyAttributes as $configAttributes) { + foreach ($configAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute( + $attributeName, + ($attributeArgs ?? []) + ['mergeable' => false] + ); + } } return $attributes; diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index 981067d6..b4c0f84d 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -40,8 +40,10 @@ public function generateClassAttributes(Class_ $class): array $attributes = []; if ($class->hasChild && ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes'])) { - foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs); + foreach ($inheritanceAttributes as $configAttributes) { + foreach ($configAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs ?? []); + } } } elseif ($class->isAbstract) { $attributes[] = new Attribute('MongoDB\MappedSuperclass'); diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 53632ca6..989869d9 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -48,8 +48,10 @@ public function generateClassAttributes(Class_ $class): array $attributes = []; if ($class->hasChild && ($inheritanceAttributes = $this->config['doctrine']['inheritanceAttributes'])) { - foreach ($inheritanceAttributes as $attributeName => $attributeArgs) { - $attributes[] = new Attribute($attributeName, $attributeArgs); + foreach ($inheritanceAttributes as $configAttributes) { + foreach ($configAttributes as $attributeName => $attributeArgs) { + $attributes[] = new Attribute($attributeName, $attributeArgs ?? []); + } } } elseif ($class->isAbstract) { $attributes[] = new Attribute('ORM\MappedSuperclass'); diff --git a/src/Model/AddAttributeTrait.php b/src/Model/AddAttributeTrait.php index 8d92f530..a30d0d6a 100644 --- a/src/Model/AddAttributeTrait.php +++ b/src/Model/AddAttributeTrait.php @@ -18,14 +18,19 @@ trait AddAttributeTrait public function addAttribute(Attribute $attribute): self { if (!\in_array($attribute, $this->attributes, true)) { - if (!$this->getAttributeWithName($attribute->name())) { + $previousAttribute = $this->getAttributeWithName($attribute->name()); + if (!$previousAttribute || !$previousAttribute->mergeable) { if ($attribute->append) { $this->attributes[] = $attribute; } } else { $this->attributes = array_map( fn (Attribute $attr) => $attr->name() === $attribute->name() - ? new Attribute($attr->name(), array_merge($attr->args(), $attribute->args())) + ? new Attribute($attr->name(), array_merge( + $attr->args(), + $attribute->args(), + ['mergeable' => $attribute->mergeable] + )) : $attr, $this->attributes ); diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php index 38c4bef3..4562056a 100644 --- a/src/Model/Attribute.php +++ b/src/Model/Attribute.php @@ -25,8 +25,20 @@ final class Attribute /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] */ private array $args; + /** + * If this attribute can be appended if a same one has not previously been generated or if the same one is not mergeable? + * + * @see \ApiPlatform\SchemaGenerator\Model\AddAttributeTrait + */ public bool $append = true; + /** + * If this attribute mergeable with the next one? + * + * @see \ApiPlatform\SchemaGenerator\Model\AddAttributeTrait + */ + public bool $mergeable = true; + /** * @param (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] $args */ @@ -35,7 +47,9 @@ public function __construct(string $name, array $args = []) $this->name = $name; $this->append = (bool) ($args['alwaysGenerate'] ?? true); - unset($args['alwaysGenerate']); + $this->mergeable = (bool) ($args['mergeable'] ?? true); + + unset($args['alwaysGenerate'], $args['mergeable']); $this->args = $args; } diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 3ffe04bd..fda78da9 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -49,13 +49,11 @@ public function getConfigTreeBuilder(): TreeBuilder $namespacePrefix = $this->defaultPrefix ?? 'App\\'; /* @see https://yaml.org/type/omap.html */ - $transformOmap = fn (array $nodeConfig) => !empty(array_filter( - $nodeConfig, - fn ($v, $k) => \is_int($k) && \is_array($v) && 1 === \count($v) && \is_string(array_keys($v)[0]), - \ARRAY_FILTER_USE_BOTH - )) - ? array_reduce(array_values($nodeConfig), fn (array $map, array $v) => $map + $v, []) - : $nodeConfig; + $transformOmap = fn (array $nodeConfig) => array_map( + fn ($v, $k) => \is_int($k) ? $v : [$k => $v], + array_values($nodeConfig), + array_keys($nodeConfig) + ); // @phpstan-ignore-next-line node is not null $attributesNode = fn () => (new NodeBuilder()) diff --git a/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php b/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php index 669d508f..1eb03797 100644 --- a/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php @@ -45,17 +45,18 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'type configuration' => [ $class, - ['types' => ['Foo' => ['attributes' => ['ApiResource' => ['routePrefix' => '/prefix']]]]], - [new Attribute('ApiResource', ['routePrefix' => '/prefix'])], + ['types' => ['Foo' => ['attributes' => [['ApiResource' => ['routePrefix' => '/prefix']]]]]], + [new Attribute('ApiResource', ['routePrefix' => '/prefix', 'mergeable' => false])], ]; $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph(SchemaGeneratorConfiguration::SCHEMA_ORG_URI))); $expectedAttribute = new Attribute('ApiResource', ['routePrefix' => '/prefix']); $expectedAttribute->append = false; + $expectedAttribute->mergeable = false; yield 'vocab configuration' => [ $class, - ['vocabularies' => [SchemaGeneratorConfiguration::SCHEMA_ORG_URI => ['attributes' => ['ApiResource' => ['routePrefix' => '/prefix']]]]], + ['vocabularies' => [SchemaGeneratorConfiguration::SCHEMA_ORG_URI => ['attributes' => [['ApiResource' => ['routePrefix' => '/prefix']]]]]], [$expectedAttribute], ]; @@ -64,10 +65,10 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'vocab and type configuration' => [ $class, [ - 'vocabularies' => [SchemaGeneratorConfiguration::SCHEMA_ORG_URI => ['attributes' => ['ApiResource' => ['routePrefix' => '/prefix']]]], - 'types' => ['Foo' => ['attributes' => ['ApiResource' => ['security' => "is_granted('ROLE_USER')"]]]], + 'vocabularies' => [SchemaGeneratorConfiguration::SCHEMA_ORG_URI => ['attributes' => [['ApiResource' => ['routePrefix' => '/prefix']]]]], + 'types' => ['Foo' => ['attributes' => [['ApiResource' => ['security' => "is_granted('ROLE_USER')"]]]]], ], - [new Attribute('ApiResource', ['security' => "is_granted('ROLE_USER')"])], + [new Attribute('ApiResource', ['security' => "is_granted('ROLE_USER')", 'mergeable' => false])], ]; } @@ -89,8 +90,8 @@ public function provideGeneratePropertyAttributesCases(): \Generator yield 'type configuration' => [ $property, - ['types' => ['Res' => ['properties' => ['prop' => ['attributes' => ['ApiResource' => ['security' => "is_granted('ROLE_USER')"]]]]]]], - [new Attribute('ApiResource', ['security' => "is_granted('ROLE_USER')"])], + ['types' => ['Res' => ['properties' => ['prop' => ['attributes' => [['ApiResource' => ['security' => "is_granted('ROLE_USER')"]]]]]]]], + [new Attribute('ApiResource', ['security' => "is_granted('ROLE_USER')", 'mergeable' => false])], ]; } diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 9dc6e4d2..53bd47d4 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -102,6 +102,8 @@ public function testCustomAttributes(): void */ #[ORM\Entity] #[ApiResource(types: ['https://schema.org/Book'], routePrefix: '/library')] +#[ORM\UniqueConstraint(name: 'isbn', columns: ['isbn'])] +#[ORM\UniqueConstraint(name: 'title', columns: ['title'])] #[MyAttribute] class Book { @@ -115,6 +117,17 @@ class Book , $book); $this->assertStringContainsString(<<<'PHP' #[ORM\OrderBy(name: 'ASC')] +PHP + , $book); + // Generated attribute could be merged with next one that is a configured one. + $this->assertStringContainsString(<<<'PHP' + #[ORM\InverseJoinColumn(nullable: false, unique: true, name: 'first_join_column')] +PHP + , $book); + // Configured attribute could not be merged with next one and it is treated + // as repeated. + $this->assertStringContainsString(<<<'PHP' + #[ORM\InverseJoinColumn(name: 'second_join_column')] PHP , $book); } diff --git a/tests/config/custom-attributes.yaml b/tests/config/custom-attributes.yaml index b70e4ca8..e75c319e 100644 --- a/tests/config/custom-attributes.yaml +++ b/tests/config/custom-attributes.yaml @@ -5,6 +5,8 @@ types: attributes: - ORM\Entity: ~ - ApiResource: { routePrefix: '/library' } + - ORM\UniqueConstraint: { name: "isbn", columns: ["isbn"] } + - ORM\UniqueConstraint: { name: "title", columns: ["title"] } - MyAttribute: ~ properties: isbn: ~ @@ -17,6 +19,11 @@ types: attributes: ORM\OneToMany: { cascade: [persist, remove] } ORM\OrderBy: { name: ASC } + 0: + ORM\InverseJoinColumn: { name: "first_join_column" } + 1: + ORM\InverseJoinColumn: { name: "second_join_column" } + Review: properties: book: diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 6b0106f1..1a9197b6 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -35,6 +35,7 @@ security: 'is_granted(\'ROLE_USER\')', )] #[UniqueEntity('email')] +#[UniqueEntity('givenName', 'familyName')] #[MyCustomAttribute(foo: 'bar')] class Person extends MyCustomClass implements MyCustomInterface { diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 3f5cf8ba..4d7d78f2 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -31,7 +31,8 @@ ], security: 'is_granted(\'ROLE_USER\')', )] -#[UniqueEntity('email')] +#[UniqueEntity('email', 'givenName')] +#[UniqueEntity('familyName')] class Person extends Thing { /** diff --git a/tests/e2e/schema.yml b/tests/e2e/schema.yml index 74a0aa77..903f78fe 100644 --- a/tests/e2e/schema.yml +++ b/tests/e2e/schema.yml @@ -23,6 +23,10 @@ types: ORM\Entity: ~ ApiResource: security: "is_granted('ROLE_USER')" + 0: + UniqueEntity: ['givenName'] + 1: + UniqueEntity: ['familyName'] properties: familyName: ~ givenName: ~ From a5c008253eb325461a273ad3273b4cd1ce9859cf Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Thu, 6 Oct 2022 16:50:27 +0200 Subject: [PATCH 235/258] fix: missing unique for self-referencing relations (#395) --- CHANGELOG.md | 4 ++++ src/AttributeGenerator/DoctrineOrmAttributeGenerator.php | 4 ++-- .../AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php | 2 +- tests/e2e/customized/App/Schema/Entity/Person.php | 2 +- tests/e2e/original/App/Schema/Entity/Person.php | 2 +- 5 files changed, 9 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2112f4c8..cb8ad65b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.1.1 + +* fix: missing unique for self-referencing relations + ## 5.1.0 * feat: repeatable attributes support diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 989869d9..e418c043 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -213,7 +213,7 @@ public function generatePropertyAttributes(Property $property, string $className $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); // Self-referencing relation if ($className === $property->reference->name()) { - $attributes[] = new Attribute('ORM\InverseJoinColumn', ['name' => $this->generateIdentifierName($this->inflector->singularize($property->name())[0].ucfirst($property->reference->name()).'Id', 'inverse_join_column', $this->config)]); + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['name' => $this->generateIdentifierName($this->inflector->singularize($property->name())[0].ucfirst($property->reference->name()).'Id', 'inverse_join_column', $this->config), 'unique' => true]); } else { $attributes[] = new Attribute('ORM\InverseJoinColumn', ['unique' => true]); } @@ -227,7 +227,7 @@ public function generatePropertyAttributes(Property $property, string $className $attributes[] = new Attribute('ORM\JoinTable', ['name' => $relationTableName]); // Self-referencing relation if ($className === $property->reference->name()) { - $attributes[] = new Attribute('ORM\InverseJoinColumn', ['name' => $this->generateIdentifierName($this->inflector->singularize($property->name())[0].ucfirst($property->reference->name()).'Id', 'inverse_join_column', $this->config), 'nullable' => false]); + $attributes[] = new Attribute('ORM\InverseJoinColumn', ['name' => $this->generateIdentifierName($this->inflector->singularize($property->name())[0].ucfirst($property->reference->name()).'Id', 'inverse_join_column', $this->config), 'nullable' => false, 'unique' => true]); } else { $attributes[] = new Attribute('ORM\InverseJoinColumn', ['nullable' => false, 'unique' => true]); } diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index 6f635c5c..f0a86ab9 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -238,7 +238,7 @@ public function testGeneratePropertyAttributes(): void $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N'), 'Vehicle') ); $this->assertEquals( - [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\Vehicle']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_vehicle_relation1_n_self_referencing']), new Attribute('ORM\InverseJoinColumn', ['name' => 'relation1_n_self_referencing_vehicle_id', 'nullable' => false])], + [new Attribute('ORM\ManyToMany', ['targetEntity' => 'App\Entity\Vehicle']), new Attribute('ORM\JoinTable', ['name' => 'vehicle_vehicle_relation1_n_self_referencing']), new Attribute('ORM\InverseJoinColumn', ['name' => 'relation1_n_self_referencing_vehicle_id', 'nullable' => false, 'unique' => true])], $this->generator->generatePropertyAttributes($this->classMap['Vehicle']->getPropertyByName('relation1_N_self_referencing'), 'Vehicle') ); $this->assertEquals( diff --git a/tests/e2e/customized/App/Schema/Entity/Person.php b/tests/e2e/customized/App/Schema/Entity/Person.php index 1a9197b6..f3de5863 100644 --- a/tests/e2e/customized/App/Schema/Entity/Person.php +++ b/tests/e2e/customized/App/Schema/Entity/Person.php @@ -139,7 +139,7 @@ class Person extends MyCustomClass implements MyCustomInterface */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\JoinTable(name: 'person_person_siblings')] - #[ORM\InverseJoinColumn(name: 'sibling_person_id')] + #[ORM\InverseJoinColumn(name: 'sibling_person_id', unique: true)] #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; diff --git a/tests/e2e/original/App/Schema/Entity/Person.php b/tests/e2e/original/App/Schema/Entity/Person.php index 4d7d78f2..1c5c4682 100644 --- a/tests/e2e/original/App/Schema/Entity/Person.php +++ b/tests/e2e/original/App/Schema/Entity/Person.php @@ -130,7 +130,7 @@ class Person extends Thing */ #[ORM\ManyToMany(targetEntity: 'App\Schema\Entity\Person')] #[ORM\JoinTable(name: 'person_person_siblings')] - #[ORM\InverseJoinColumn(name: 'sibling_person_id')] + #[ORM\InverseJoinColumn(name: 'sibling_person_id', unique: true)] #[ApiProperty(types: ['https://schema.org/siblings'])] private ?Collection $siblings = null; From c783b1d2ab4ce409a84e8f8477a3971262321941 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 13 Dec 2022 18:00:17 +0100 Subject: [PATCH 236/258] feat(openapi): improve type detection (#399) Introduce type classes in order to represent array and composite types. Manage correctly allOf and oneOf keywords. --- bin/compile | 5 + composer.json | 2 +- composer.lock | 847 +++++++++--------- .../PhpDocAnnotationGenerator.php | 13 +- .../ConstraintAttributeGenerator.php | 6 +- .../DoctrineMongoDBAttributeGenerator.php | 59 +- .../DoctrineOrmAttributeGenerator.php | 7 +- src/ClassMutator/AnnotationsAppender.php | 2 +- .../ClassPropertiesTypehintMutator.php | 5 +- src/Model/Class_.php | 2 +- src/Model/Property.php | 23 +- src/Model/Type/ArrayType.php | 42 + src/Model/Type/CompositeType.php | 18 + src/Model/Type/PrimitiveType.php | 34 + src/Model/Type/Type.php | 21 + src/Model/Type/UnionType.php | 44 + src/OpenApi/ClassGenerator.php | 12 +- src/OpenApi/Model/Type/PrimitiveType.php | 50 ++ src/OpenApi/PhpTypeConverter.php | 24 +- .../PropertyGenerator/IdPropertyGenerator.php | 8 +- .../PropertyGenerator/PropertyGenerator.php | 67 +- src/OpenApi/SchemaTraversalTrait.php | 50 ++ src/PhpTypeConverter.php | 30 +- src/PropertyGenerator/IdPropertyGenerator.php | 3 +- src/PropertyGenerator/PropertyGenerator.php | 2 +- src/Schema/Model/Type/PrimitiveType.php | 60 ++ .../PropertyGenerator/IdPropertyGenerator.php | 4 + .../PropertyGenerator/PropertyGenerator.php | 9 +- .../PhpDocAnnotationGeneratorTest.php | 7 +- .../ConstraintAttributeGeneratorTest.php | 6 +- .../DoctrineMongoDBAttributeGeneratorTest.php | 13 +- .../DoctrineOrmAttributeGeneratorTest.php | 19 +- .../ClassPropertiesAppenderTest.php | 7 +- .../consumers/EDUXCHANGE/V1/Course.yaml | 45 + .../consumers/EDUXCHANGE/V1/Person.yaml | 47 + .../consumers/EDUXCHANGE/V1/Program.yaml | 45 + .../consumers/RIO/V1/Course.yaml | 42 + .../RIO/V1/EducationSpecification.yaml | 42 + .../consumers/RIO/V1/Offering.yaml | 29 + .../consumers/RIO/V1/Program.yaml | 95 ++ .../consumers/RIO/V1/examples/Course.yaml | 6 + .../V1/examples/EducationSpecification.yaml | 3 + .../consumers/RIO/V1/examples/Offering.yaml | 4 + .../consumers/RIO/V1/examples/Program.yaml | 11 + .../consumers/TEST/V1/TestConsumer.yaml | 7 + .../TEST/V1/examples/TestConsumer.yaml | 3 + .../enumerations/ICERelationType.yaml | 7 + .../enumerations/academicSessionType.yaml | 19 + .../enumerations/addressType.yaml | 14 + .../enumerations/associationRole.yaml | 15 + .../enumerations/associationState.yaml | 9 + .../enumerations/codeType.yaml | 59 ++ .../enumerations/componentType.yaml | 27 + .../enumerations/costType.yaml | 13 + .../educationSpecificationType.yaml | 13 + .../enumerations/formalDocument.yaml | 15 + .../enumerations/gender.yaml | 8 + .../enumerations/groupType.yaml | 11 + .../enumerations/level.yaml | 31 + .../enumerations/levelOfQualification.yaml | 13 + .../enumerations/modeOfStudy.yaml | 12 + .../enumerations/modesOfDelivery.yaml | 17 + .../enumerations/newsItemType.yaml | 12 + .../enumerations/offeringType.yaml | 7 + .../enumerations/organizationType.yaml | 19 + .../enumerations/passState.yaml | 7 + .../enumerations/personAffiliations.yaml | 13 + .../enumerations/programType.yaml | 15 + .../enumerations/qualificationAwarded.yaml | 13 + .../enumerations/remoteAssociationState.yaml | 9 + .../enumerations/resultState.yaml | 8 + .../enumerations/resultValueType.yaml | 9 + .../enumerations/roomType.yaml | 25 + .../enumerations/sector.yaml | 11 + .../parameters/consumer.yaml | 6 + .../parameters/pageNumber.yaml | 9 + .../parameters/pageSize.yaml | 14 + .../parameters/personSearch.yaml | 6 + .../parameters/primaryCode.yaml | 6 + .../parameters/returnTimelineOverrides.yaml | 7 + .../parameters/search.yaml | 6 + .../parameters/teachingLanguage.yaml | 10 + .../paths/AcademicSessionCollection.yaml | 80 ++ .../paths/AcademicSessionInstance.yaml | 47 + .../AcademicSessionOfferingCollection.yaml | 105 +++ .../paths/AssociationInstance.yaml | 102 +++ .../paths/AssociationInstanceExternalMe.yaml | 41 + .../paths/AssociationInstanceMe.yaml | 33 + .../paths/BuildingCollection.yaml | 59 ++ .../paths/BuildingInstance.yaml | 34 + .../paths/BuildingRoomCollection.yaml | 77 ++ .../paths/ComponentInstance.yaml | 46 + .../paths/ComponentOfferingCollection.yaml | 92 ++ .../paths/CourseCollection.yaml | 72 ++ .../paths/CourseComponentCollection.yaml | 74 ++ .../paths/CourseInstance.yaml | 49 + .../paths/CourseOfferingCollection.yaml | 98 ++ .../EducationSpecificationCollection.yaml | 75 ++ ...ducationSpecificationCourseCollection.yaml | 80 ++ ...ationEducationSpecificationCollection.yaml | 69 ++ .../paths/EducationSpecificationInstance.yaml | 52 ++ ...ucationSpecificationProgramCollection.yaml | 104 +++ .../paths/GroupCollection.yaml | 87 ++ .../paths/GroupInstance.yaml | 45 + .../paths/GroupPersonCollection.yaml | 95 ++ .../paths/NewsFeedCollection.yaml | 72 ++ .../paths/NewsFeedInstance.yaml | 34 + .../paths/NewsFeedItemCollection.yaml | 79 ++ .../paths/NewsItemInstance.yaml | 45 + .../paths/OfferingAssociationCollection.yaml | 95 ++ .../paths/OfferingAssociationInstanceMe.yaml | 41 + .../paths/OfferingGroupCollection.yaml | 93 ++ .../paths/OfferingInstance.yaml | 59 ++ .../paths/OrganizationCollection.yaml | 65 ++ .../OrganizationComponentCollection.yaml | 74 ++ .../paths/OrganizationCourseCollection.yaml | 80 ++ ...ationEducationSpecificationCollection.yaml | 75 ++ .../paths/OrganizationGroupCollection.yaml | 73 ++ .../paths/OrganizationInstance.yaml | 46 + .../paths/OrganizationOfferingCollection.yaml | 105 +++ .../paths/OrganizationProgramCollection.yaml | 98 ++ .../paths/PersonAssociationCollection.yaml | 121 +++ .../paths/PersonCollection.yaml | 96 ++ .../paths/PersonGroupCollection.yaml | 93 ++ .../paths/PersonInstance.yaml | 34 + .../open-education-api-v5/paths/PersonMe.yaml | 28 + .../paths/ProgramCollection.yaml | 90 ++ .../paths/ProgramCourseCollection.yaml | 80 ++ .../paths/ProgramInstance.yaml | 50 ++ .../paths/ProgramOfferingCollection.yaml | 98 ++ .../paths/ProgramProgramCollection.yaml | 96 ++ .../paths/RoomCollection.yaml | 69 ++ .../paths/RoomInstance.yaml | 45 + .../open-education-api-v5/paths/Service.yaml | 27 + .../schemas/AcademicSession.yaml | 80 ++ .../schemas/Address.yaml | 53 ++ .../schemas/Association.yaml | 3 + .../schemas/AssociationFull.yaml | 26 + .../schemas/AssociationId.yaml | 11 + .../schemas/AssociationProperties.yaml | 33 + .../schemas/AssociationWrite.yaml | 14 + .../schemas/Building.yaml | 61 ++ .../schemas/Component.yaml | 150 ++++ .../schemas/ComponentOffering.yaml | 80 ++ .../schemas/ComponentOfferingAssociation.yaml | 6 + ...omponentOfferingAssociationExpandable.yaml | 8 + .../ComponentOfferingAssociationExpanded.yaml | 16 + .../schemas/ComponentResult.yaml | 13 + .../schemas/Consumer.yaml | 9 + .../open-education-api-v5/schemas/Cost.yaml | 38 + .../open-education-api-v5/schemas/Course.yaml | 12 + .../schemas/CourseExpanded.yaml | 10 + .../schemas/CourseId.yaml | 11 + .../schemas/CourseOffering.yaml | 85 ++ .../schemas/CourseOfferingAssociation.yaml | 6 + .../CourseOfferingAssociationExpandable.yaml | 8 + .../CourseOfferingAssociationExpanded.yaml | 13 + .../schemas/CourseProperties.yaml | 172 ++++ .../schemas/CourseResult.yaml | 8 + .../schemas/EducationSpecification.yaml | 12 + .../EducationSpecificationExpanded.yaml | 10 + .../schemas/EducationSpecificationId.yaml | 9 + .../EducationSpecificationProperties.yaml | 112 +++ .../schemas/ErrorBadRequest.yaml | 5 + .../schemas/ErrorForbidden.yaml | 5 + .../schemas/ErrorInternalServerError.yaml | 5 + .../schemas/ErrorMethodNotAllowed.yaml | 5 + .../schemas/ErrorNotFound.yaml | 5 + .../schemas/ErrorTooManyRequests.yaml | 5 + .../schemas/ErrorUnauthorized.yaml | 5 + .../open-education-api-v5/schemas/Ext.yaml | 2 + .../open-education-api-v5/schemas/Group.yaml | 81 ++ .../schemas/GroupExpanded.yaml | 9 + .../schemas/Identifier.yaml | 3 + .../schemas/IdentifierEntry.yaml | 14 + .../schemas/LanguageTypedString.yaml | 13 + .../schemas/NewsFeed.yaml | 52 ++ .../schemas/NewsItem.yaml | 83 ++ .../schemas/Offering.yaml | 3 + .../schemas/OfferingId.yaml | 11 + .../schemas/OfferingIdAndType.yaml | 11 + .../schemas/OfferingProperties.yaml | 128 +++ .../schemas/Organization.yaml | 104 +++ .../schemas/Pagination.yaml | 32 + .../open-education-api-v5/schemas/Person.yaml | 3 + .../schemas/PersonId.yaml | 11 + .../schemas/PersonProperties.yaml | 154 ++++ .../schemas/PostResponse.yaml | 18 + .../schemas/Problem.yaml | 17 + .../schemas/Program.yaml | 12 + .../schemas/ProgramExpanded.yaml | 10 + .../schemas/ProgramId.yaml | 11 + .../schemas/ProgramOffering.yaml | 74 ++ .../schemas/ProgramOfferingAssociation.yaml | 6 + .../ProgramOfferingAssociationExpandable.yaml | 9 + .../ProgramOfferingAssociationExpanded.yaml | 12 + .../schemas/ProgramProperties.yaml | 195 ++++ .../schemas/ProgramResult.yaml | 8 + .../open-education-api-v5/schemas/Result.yaml | 25 + .../open-education-api-v5/schemas/Room.yaml | 100 +++ .../schemas/Service.yaml | 34 + .../schemas/StudyLoadDescriptor.yaml | 26 + .../schemas/TimelineOverrideCourse.yaml | 18 + ...imelineOverrideEducationSpecification.yaml | 18 + .../schemas/TimelineOverrideProgram.yaml | 18 + tests/e2e/open-education-api-v5/spec.yaml | 355 ++++++++ .../App/OpenApi/Entity/AcademicSession.php | 270 ++++++ .../App/OpenApi/Entity/Association.php | 192 ++++ tests/e2e/original/App/OpenApi/Entity/Pet.php | 8 +- tests/e2e/schema_open_education_api.yml | 7 + 210 files changed, 8724 insertions(+), 589 deletions(-) create mode 100644 src/Model/Type/ArrayType.php create mode 100644 src/Model/Type/CompositeType.php create mode 100644 src/Model/Type/PrimitiveType.php create mode 100644 src/Model/Type/Type.php create mode 100644 src/Model/Type/UnionType.php create mode 100644 src/OpenApi/Model/Type/PrimitiveType.php create mode 100644 src/OpenApi/SchemaTraversalTrait.php create mode 100644 src/Schema/Model/Type/PrimitiveType.php create mode 100644 tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Course.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Person.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Program.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/Course.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/EducationSpecification.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/Offering.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/Program.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Course.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/EducationSpecification.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Offering.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Program.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/TEST/V1/TestConsumer.yaml create mode 100644 tests/e2e/open-education-api-v5/consumers/TEST/V1/examples/TestConsumer.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/ICERelationType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/academicSessionType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/addressType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/associationRole.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/associationState.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/codeType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/componentType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/costType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/educationSpecificationType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/formalDocument.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/gender.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/groupType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/level.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/levelOfQualification.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/modeOfStudy.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/modesOfDelivery.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/newsItemType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/offeringType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/organizationType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/passState.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/personAffiliations.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/programType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/qualificationAwarded.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/remoteAssociationState.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/resultState.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/resultValueType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/roomType.yaml create mode 100644 tests/e2e/open-education-api-v5/enumerations/sector.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/consumer.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/pageNumber.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/pageSize.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/personSearch.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/primaryCode.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/returnTimelineOverrides.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/search.yaml create mode 100644 tests/e2e/open-education-api-v5/parameters/teachingLanguage.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/AcademicSessionCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/AcademicSessionInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/AcademicSessionOfferingCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/AssociationInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/AssociationInstanceExternalMe.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/AssociationInstanceMe.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/BuildingCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/BuildingInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/BuildingRoomCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ComponentInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ComponentOfferingCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/CourseCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/CourseComponentCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/CourseInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/CourseOfferingCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/EducationSpecificationCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/EducationSpecificationCourseCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/EducationSpecificationEducationSpecificationCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/EducationSpecificationInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/EducationSpecificationProgramCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/GroupCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/GroupInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/GroupPersonCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/NewsFeedCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/NewsFeedInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/NewsFeedItemCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/NewsItemInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OfferingAssociationCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OfferingAssociationInstanceMe.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OfferingGroupCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OfferingInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationComponentCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationCourseCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationEducationSpecificationCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationGroupCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationOfferingCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/OrganizationProgramCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/PersonAssociationCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/PersonCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/PersonGroupCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/PersonInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/PersonMe.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ProgramCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ProgramCourseCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ProgramInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ProgramOfferingCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/ProgramProgramCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/RoomCollection.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/RoomInstance.yaml create mode 100644 tests/e2e/open-education-api-v5/paths/Service.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/AcademicSession.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Address.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Association.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/AssociationFull.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/AssociationId.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/AssociationProperties.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/AssociationWrite.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Building.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Component.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ComponentOffering.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociation.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpandable.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ComponentResult.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Consumer.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Cost.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Course.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseId.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseOffering.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociation.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpandable.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseProperties.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/CourseResult.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/EducationSpecification.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/EducationSpecificationExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/EducationSpecificationId.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/EducationSpecificationProperties.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorBadRequest.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorForbidden.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorInternalServerError.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorMethodNotAllowed.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorNotFound.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorTooManyRequests.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ErrorUnauthorized.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Ext.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Group.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/GroupExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Identifier.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/IdentifierEntry.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/LanguageTypedString.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/NewsFeed.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/NewsItem.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Offering.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/OfferingId.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/OfferingIdAndType.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/OfferingProperties.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Organization.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Pagination.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Person.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/PersonId.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/PersonProperties.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/PostResponse.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Problem.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Program.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramId.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramOffering.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociation.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpandable.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpanded.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramProperties.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/ProgramResult.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Result.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Room.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/Service.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/StudyLoadDescriptor.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/TimelineOverrideCourse.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/TimelineOverrideEducationSpecification.yaml create mode 100644 tests/e2e/open-education-api-v5/schemas/TimelineOverrideProgram.yaml create mode 100644 tests/e2e/open-education-api-v5/spec.yaml create mode 100644 tests/e2e/original/App/OpenApi/Entity/AcademicSession.php create mode 100644 tests/e2e/original/App/OpenApi/Entity/Association.php create mode 100644 tests/e2e/schema_open_education_api.yml diff --git a/bin/compile b/bin/compile index 2ef802ab..4c71351f 100755 --- a/bin/compile +++ b/bin/compile @@ -40,3 +40,8 @@ php schema.phar generate tmp/original tests/e2e/schema_openapi_ref.yml -n -vv -- diff tests/e2e/original/App/OpenApi/Entity/Order.php tmp/original/App/OpenApi/Entity/Order.php; diff tests/e2e/original/App/OpenApi/Entity/Pet.php tmp/original/App/OpenApi/Entity/Pet.php; diff tests/e2e/original/App/OpenApi/Entity/User.php tmp/original/App/OpenApi/Entity/User.php; + +php schema.phar generate tmp/original tests/e2e/schema_open_education_api.yml -n -vv --ansi; + +diff tests/e2e/original/App/OpenApi/Entity/AcademicSession.php tmp/original/App/OpenApi/Entity/AcademicSession.php; +diff tests/e2e/original/App/OpenApi/Entity/Association.php tmp/original/App/OpenApi/Entity/Association.php; diff --git a/composer.json b/composer.json index 7b0d8786..83b530e6 100644 --- a/composer.json +++ b/composer.json @@ -51,7 +51,7 @@ "symfony/string": "^5.2 || ^6.0" }, "require-dev": { - "api-platform/core": "^v2.7.0-rc.1", + "api-platform/core": "^v2.7", "doctrine/orm": "^2.7", "myclabs/php-enum": "^1.7", "symfony/doctrine-bridge": "^5.2 || ^6.0", diff --git a/composer.lock b/composer.lock index 6b9562a7..1e9fb6ec 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4688a43631493064d637c15f530b0486", + "content-hash": "e015c44d59c43f760d99f9c278ce5c96", "packages": [ { "name": "cebe/php-openapi", @@ -77,16 +77,16 @@ }, { "name": "composer/pcre", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd" + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/e300eb6c535192decd27a85bc72a9290f0d6b3bd", - "reference": "e300eb6c535192decd27a85bc72a9290f0d6b3bd", + "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", "shasum": "" }, "require": { @@ -128,7 +128,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.0.0" + "source": "https://github.com/composer/pcre/tree/3.1.0" }, "funding": [ { @@ -144,7 +144,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T20:21:48+00:00" + "time": "2022-11-17T09:50:14+00:00" }, { "name": "composer/semver", @@ -368,28 +368,28 @@ }, { "name": "doctrine/inflector", - "version": "2.0.4", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89" + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", - "reference": "8b7ff3e4b7de6b2c84da85637b59fd2880ecaa89", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^8.2", - "phpstan/phpstan": "^0.12", - "phpstan/phpstan-phpunit": "^0.12", - "phpstan/phpstan-strict-rules": "^0.12", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0", - "vimeo/psalm": "^4.10" + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^8.5 || ^9.5", + "vimeo/psalm": "^4.25" }, "type": "library", "autoload": { @@ -439,7 +439,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.4" + "source": "https://github.com/doctrine/inflector/tree/2.0.6" }, "funding": [ { @@ -455,7 +455,7 @@ "type": "tidelift" } ], - "time": "2021-10-22T20:16:43+00:00" + "time": "2022-10-20T09:10:12+00:00" }, { "name": "doctrine/lexer", @@ -535,16 +535,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.11.0", + "version": "v3.13.0", "source": { "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "7dcdea3f2f5f473464e835be9be55283ff8cfdc3" + "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", + "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/7dcdea3f2f5f473464e835be9be55283ff8cfdc3", - "reference": "7dcdea3f2f5f473464e835be9be55283ff8cfdc3", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a6232229a8309e8811dc751c28b91cb34b2943e1", + "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1", "shasum": "" }, "require": { @@ -568,7 +568,7 @@ }, "require-dev": { "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^1.5", + "keradus/cli-executor": "^2.0", "mikey179/vfsstream": "^1.6.10", "php-coveralls/php-coveralls": "^2.5.2", "php-cs-fixer/accessible-object": "^1.1", @@ -577,8 +577,8 @@ "phpspec/prophecy": "^1.15", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", + "phpunitgoodpractices/polyfill": "^1.6", + "phpunitgoodpractices/traits": "^1.9.2", "symfony/phpunit-bridge": "^6.0", "symfony/yaml": "^5.4 || ^6.0" }, @@ -611,8 +611,8 @@ ], "description": "A tool to automatically fix PHP code style", "support": { - "issues": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/issues", - "source": "https://github.com/FriendsOfPHP/PHP-CS-Fixer/tree/v3.11.0" + "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.0" }, "funding": [ { @@ -620,7 +620,7 @@ "type": "github" } ], - "time": "2022-09-01T18:24:51+00:00" + "time": "2022-10-31T19:28:50+00:00" }, { "name": "justinrainbow/json-schema", @@ -783,25 +783,25 @@ }, { "name": "nette/php-generator", - "version": "v4.0.2", + "version": "v4.0.5", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "f19b7975c7c4d729be5b64fce7eb72f0d4aac6fc" + "reference": "a8d6abeae5d8c7202cd69600e086a7a72877fc86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/f19b7975c7c4d729be5b64fce7eb72f0d4aac6fc", - "reference": "f19b7975c7c4d729be5b64fce7eb72f0d4aac6fc", + "url": "https://api.github.com/repos/nette/php-generator/zipball/a8d6abeae5d8c7202cd69600e086a7a72877fc86", + "reference": "a8d6abeae5d8c7202cd69600e086a7a72877fc86", "shasum": "" }, "require": { "nette/utils": "^3.2.7 || ^4.0", - "php": ">=8.0 <8.2" + "php": ">=8.0 <8.3" }, "require-dev": { "nette/tester": "^2.4", - "nikic/php-parser": "^4.13", + "nikic/php-parser": "^4.15", "phpstan/phpstan": "^1.0", "tracy/tracy": "^2.8" }, @@ -835,7 +835,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.1 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.2 features.", "homepage": "https://nette.org/", "keywords": [ "code", @@ -845,9 +845,9 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.0.2" + "source": "https://github.com/nette/php-generator/tree/v4.0.5" }, - "time": "2022-06-17T12:20:08+00:00" + "time": "2022-11-02T20:37:46+00:00" }, { "name": "nette/utils", @@ -855,12 +855,12 @@ "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "52db62bc9605d7778f0190d8fde0d5db3787be24" + "reference": "7c2a4deaf2ebf54315fdb204911534f97cb19d18" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/52db62bc9605d7778f0190d8fde0d5db3787be24", - "reference": "52db62bc9605d7778f0190d8fde0d5db3787be24", + "url": "https://api.github.com/repos/nette/utils/zipball/7c2a4deaf2ebf54315fdb204911534f97cb19d18", + "reference": "7c2a4deaf2ebf54315fdb204911534f97cb19d18", "shasum": "" }, "require": { @@ -933,20 +933,20 @@ "issues": "https://github.com/nette/utils/issues", "source": "https://github.com/nette/utils/tree/master" }, - "time": "2022-09-06T01:00:53+00:00" + "time": "2022-12-04T22:52:36+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.1", + "version": "v4.15.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", - "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", "shasum": "" }, "require": { @@ -987,9 +987,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" }, - "time": "2022-09-04T07:30:47+00:00" + "time": "2022-11-12T15:38:23+00:00" }, { "name": "psr/cache", @@ -1261,16 +1261,16 @@ }, { "name": "sweetrdf/easyrdf", - "version": "1.6", + "version": "1.7.1", "source": { "type": "git", "url": "https://github.com/sweetrdf/easyrdf.git", - "reference": "cd970ff3cb7c209958537d7d097324e6961e8ea9" + "reference": "19ba21288e0aa344227267cab7f8f9c565eee426" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/cd970ff3cb7c209958537d7d097324e6961e8ea9", - "reference": "cd970ff3cb7c209958537d7d097324e6961e8ea9", + "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/19ba21288e0aa344227267cab7f8f9c565eee426", + "reference": "19ba21288e0aa344227267cab7f8f9c565eee426", "shasum": "" }, "require": { @@ -1281,6 +1281,9 @@ "lib-libxml": "*", "php": "^7.1|^8.0" }, + "replace": { + "easyrdf/easyrdf": "1.0.*|1.1.*" + }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", "ml/json-ld": "^1.0", @@ -1331,22 +1334,22 @@ ], "support": { "issues": "https://github.com/sweetrdf/easyrdf/issues", - "source": "https://github.com/sweetrdf/easyrdf/tree/1.6" + "source": "https://github.com/sweetrdf/easyrdf/tree/1.7.1" }, - "time": "2022-08-08T09:12:46+00:00" + "time": "2022-11-08T08:13:50+00:00" }, { "name": "symfony/config", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a0645dc585d378b73c01115dd7ab9348f7d40c85" + "reference": "ebf27792246165a2a0b6b69ec9c620cac8c5a2f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a0645dc585d378b73c01115dd7ab9348f7d40c85", - "reference": "a0645dc585d378b73c01115dd7ab9348f7d40c85", + "url": "https://api.github.com/repos/symfony/config/zipball/ebf27792246165a2a0b6b69ec9c620cac8c5a2f0", + "reference": "ebf27792246165a2a0b6b69ec9c620cac8c5a2f0", "shasum": "" }, "require": { @@ -1394,7 +1397,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v6.1.3" + "source": "https://github.com/symfony/config/tree/v6.2.0" }, "funding": [ { @@ -1410,20 +1413,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T15:00:40+00:00" + "time": "2022-11-02T09:08:04+00:00" }, { "name": "symfony/console", - "version": "v6.1.4", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "7fccea8728aa2d431a6725b02b3ce759049fc84d" + "reference": "58f6cef5dc5f641b7bbdbf8b32b44cc926c35f3f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/7fccea8728aa2d431a6725b02b3ce759049fc84d", - "reference": "7fccea8728aa2d431a6725b02b3ce759049fc84d", + "url": "https://api.github.com/repos/symfony/console/zipball/58f6cef5dc5f641b7bbdbf8b32b44cc926c35f3f", + "reference": "58f6cef5dc5f641b7bbdbf8b32b44cc926c35f3f", "shasum": "" }, "require": { @@ -1490,7 +1493,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.1.4" + "source": "https://github.com/symfony/console/tree/v6.2.1" }, "funding": [ { @@ -1506,20 +1509,20 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:31+00:00" + "time": "2022-12-01T13:44:20+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918" + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", - "reference": "07f1b9cc2ffee6aaafcf4b710fbc38ff736bd918", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", "shasum": "" }, "require": { @@ -1528,7 +1531,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -1557,7 +1560,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" }, "funding": [ { @@ -1573,20 +1576,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.1.0", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347" + "reference": "9efb1618fabee89515fe031314e8ed5625f85a53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/a0449a7ad7daa0f7c0acd508259f80544ab5a347", - "reference": "a0449a7ad7daa0f7c0acd508259f80544ab5a347", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9efb1618fabee89515fe031314e8ed5625f85a53", + "reference": "9efb1618fabee89515fe031314e8ed5625f85a53", "shasum": "" }, "require": { @@ -1640,7 +1643,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.1.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.0" }, "funding": [ { @@ -1656,20 +1659,20 @@ "type": "tidelift" } ], - "time": "2022-05-05T16:51:07+00:00" + "time": "2022-11-02T09:08:04+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448" + "reference": "0782b0b52a737a05b4383d0df35a474303cabdae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/02ff5eea2f453731cfbc6bc215e456b781480448", - "reference": "02ff5eea2f453731cfbc6bc215e456b781480448", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0782b0b52a737a05b4383d0df35a474303cabdae", + "reference": "0782b0b52a737a05b4383d0df35a474303cabdae", "shasum": "" }, "require": { @@ -1682,7 +1685,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -1719,7 +1722,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.0" }, "funding": [ { @@ -1735,20 +1738,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "symfony/filesystem", - "version": "v6.1.4", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "3f39c04d2630c34019907b02f85672dac99f8659" + "reference": "50b2523c874605cf3d4acf7a9e2b30b6a440a016" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/3f39c04d2630c34019907b02f85672dac99f8659", - "reference": "3f39c04d2630c34019907b02f85672dac99f8659", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/50b2523c874605cf3d4acf7a9e2b30b6a440a016", + "reference": "50b2523c874605cf3d4acf7a9e2b30b6a440a016", "shasum": "" }, "require": { @@ -1782,7 +1785,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.1.4" + "source": "https://github.com/symfony/filesystem/tree/v6.2.0" }, "funding": [ { @@ -1798,20 +1801,20 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:17:38+00:00" + "time": "2022-11-20T13:01:27+00:00" }, { "name": "symfony/finder", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709" + "reference": "eb2355f69519e4ef33f1835bca4c935f5d42e570" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/39696bff2c2970b3779a5cac7bf9f0b88fc2b709", - "reference": "39696bff2c2970b3779a5cac7bf9f0b88fc2b709", + "url": "https://api.github.com/repos/symfony/finder/zipball/eb2355f69519e4ef33f1835bca4c935f5d42e570", + "reference": "eb2355f69519e4ef33f1835bca4c935f5d42e570", "shasum": "" }, "require": { @@ -1846,7 +1849,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.1.3" + "source": "https://github.com/symfony/finder/tree/v6.2.0" }, "funding": [ { @@ -1862,20 +1865,20 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2022-10-09T08:55:40+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.1.0", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4" + "reference": "d28f02acde71ff75e957082cd36e973df395f626" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a3016f5442e28386ded73c43a32a5b68586dd1c4", - "reference": "a3016f5442e28386ded73c43a32a5b68586dd1c4", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/d28f02acde71ff75e957082cd36e973df395f626", + "reference": "d28f02acde71ff75e957082cd36e973df395f626", "shasum": "" }, "require": { @@ -1913,7 +1916,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.1.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.2.0" }, "funding": [ { @@ -1929,20 +1932,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-11-02T09:08:04+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4" + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", - "reference": "6fd1b9a79f6e3cf65f9e679b23af304cd9e010d4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", + "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", "shasum": "" }, "require": { @@ -1957,7 +1960,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1995,7 +1998,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" }, "funding": [ { @@ -2011,20 +2014,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "433d05519ce6990bf3530fba6957499d327395c2" + "reference": "511a08c03c1960e08a883f4cffcacd219b758354" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/433d05519ce6990bf3530fba6957499d327395c2", - "reference": "433d05519ce6990bf3530fba6957499d327395c2", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", + "reference": "511a08c03c1960e08a883f4cffcacd219b758354", "shasum": "" }, "require": { @@ -2036,7 +2039,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2076,7 +2079,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" }, "funding": [ { @@ -2092,20 +2095,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd" + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/219aa369ceff116e673852dce47c3a41794c14bd", - "reference": "219aa369ceff116e673852dce47c3a41794c14bd", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", "shasum": "" }, "require": { @@ -2117,7 +2120,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2160,7 +2163,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" }, "funding": [ { @@ -2176,20 +2179,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e" + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", - "reference": "9344f9cb97f3b19424af1a21a3b0e75b0a7d8d7e", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", "shasum": "" }, "require": { @@ -2204,7 +2207,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2243,7 +2246,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" }, "funding": [ { @@ -2259,20 +2262,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace" + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/cfa0ae98841b9e461207c13ab093d76b0fa7bace", - "reference": "cfa0ae98841b9e461207c13ab093d76b0fa7bace", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", "shasum": "" }, "require": { @@ -2281,7 +2284,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2326,7 +2329,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" }, "funding": [ { @@ -2342,20 +2345,20 @@ "type": "tidelift" } ], - "time": "2022-05-10T07:21:04+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1" + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/13f6d1271c663dc5ae9fb843a8f16521db7687a1", - "reference": "13f6d1271c663dc5ae9fb843a8f16521db7687a1", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", + "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", "shasum": "" }, "require": { @@ -2364,7 +2367,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2405,7 +2408,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" }, "funding": [ { @@ -2421,20 +2424,20 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/process", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292" + "reference": "ba6e55359f8f755fe996c58a81e00eaa67a35877" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/a6506e99cfad7059b1ab5cab395854a0a0c21292", - "reference": "a6506e99cfad7059b1ab5cab395854a0a0c21292", + "url": "https://api.github.com/repos/symfony/process/zipball/ba6e55359f8f755fe996c58a81e00eaa67a35877", + "reference": "ba6e55359f8f755fe996c58a81e00eaa67a35877", "shasum": "" }, "require": { @@ -2466,7 +2469,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v6.1.3" + "source": "https://github.com/symfony/process/tree/v6.2.0" }, "funding": [ { @@ -2482,7 +2485,7 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2022-11-02T09:08:04+00:00" }, { "name": "symfony/service-contracts", @@ -2571,16 +2574,16 @@ }, { "name": "symfony/stopwatch", - "version": "v6.1.0", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "77dedae82ce2a26e2e9b481855473fc3b3e4e54d" + "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/77dedae82ce2a26e2e9b481855473fc3b3e4e54d", - "reference": "77dedae82ce2a26e2e9b481855473fc3b3e4e54d", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/266636bb8f3fbdccc302491df7b3a1b9a8c238a7", + "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7", "shasum": "" }, "require": { @@ -2613,7 +2616,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.1.0" + "source": "https://github.com/symfony/stopwatch/tree/v6.2.0" }, "funding": [ { @@ -2629,20 +2632,20 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-09-28T16:00:52+00:00" }, { "name": "symfony/string", - "version": "v6.1.4", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "290972cad7b364e3befaa74ba0ec729800fb161c" + "reference": "145702685e0d12f81d755c71127bfff7582fdd36" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/290972cad7b364e3befaa74ba0ec729800fb161c", - "reference": "290972cad7b364e3befaa74ba0ec729800fb161c", + "url": "https://api.github.com/repos/symfony/string/zipball/145702685e0d12f81d755c71127bfff7582fdd36", + "reference": "145702685e0d12f81d755c71127bfff7582fdd36", "shasum": "" }, "require": { @@ -2658,6 +2661,7 @@ "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", + "symfony/intl": "^6.2", "symfony/translation-contracts": "^2.0|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, @@ -2698,7 +2702,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.1.4" + "source": "https://github.com/symfony/string/tree/v6.2.0" }, "funding": [ { @@ -2714,20 +2718,20 @@ "type": "tidelift" } ], - "time": "2022-08-12T18:05:43+00:00" + "time": "2022-11-30T17:13:47+00:00" }, { "name": "symfony/yaml", - "version": "v6.1.4", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "86ee4d8fa594ed45e40d86eedfda1bcb66c8d919" + "reference": "f2570f21bd4adc3589aa3133323273995109bae0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/86ee4d8fa594ed45e40d86eedfda1bcb66c8d919", - "reference": "86ee4d8fa594ed45e40d86eedfda1bcb66c8d919", + "url": "https://api.github.com/repos/symfony/yaml/zipball/f2570f21bd4adc3589aa3133323273995109bae0", + "reference": "f2570f21bd4adc3589aa3133323273995109bae0", "shasum": "" }, "require": { @@ -2772,7 +2776,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.1.4" + "source": "https://github.com/symfony/yaml/tree/v6.2.0" }, "funding": [ { @@ -2788,20 +2792,20 @@ "type": "tidelift" } ], - "time": "2022-08-02T16:17:38+00:00" + "time": "2022-11-25T19:00:27+00:00" }, { "name": "twig/twig", - "version": "v3.4.2", + "version": "v3.4.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077" + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", - "reference": "e07cdd3d430cd7e453c31b36eb5ad6c0c5e43077", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", + "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", "shasum": "" }, "require": { @@ -2852,7 +2856,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.2" + "source": "https://github.com/twigphp/Twig/tree/v3.4.3" }, "funding": [ { @@ -2864,30 +2868,30 @@ "type": "tidelift" } ], - "time": "2022-08-12T06:47:24+00:00" + "time": "2022-09-28T08:42:51+00:00" } ], "packages-dev": [ { "name": "api-platform/core", - "version": "v2.7.0-rc.2", + "version": "v2.7.5", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "f2c8a6113d2e004eefe10f95671a8822ce307733" + "reference": "b670958db633d66b05bc46ff34c3bb7c1b306c70" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/f2c8a6113d2e004eefe10f95671a8822ce307733", - "reference": "f2c8a6113d2e004eefe10f95671a8822ce307733", + "url": "https://api.github.com/repos/api-platform/core/zipball/b670958db633d66b05bc46ff34c3bb7c1b306c70", + "reference": "b670958db633d66b05bc46ff34c3bb7c1b306c70", "shasum": "" }, "require": { "doctrine/inflector": "^1.0 || ^2.0", - "fig/link-util": "^1.0", "php": ">=7.1", "psr/cache": "^1.0 || ^2.0 || ^3.0", "psr/container": "^1.0 || ^2.0", + "symfony/deprecation-contracts": "^2.1 || ^3.0", "symfony/http-foundation": "^4.4 || ^5.1 || ^6.0", "symfony/http-kernel": "^4.4 || ^5.1 || ^6.0", "symfony/property-access": "^3.4.19 || ^4.4 || ^5.1 || ^6.0", @@ -2900,7 +2904,8 @@ "doctrine/common": "<2.7", "doctrine/dbal": "<2.10", "doctrine/mongodb-odm": "<2.2", - "doctrine/persistence": "<1.3" + "doctrine/persistence": "<1.3", + "elasticsearch/elasticsearch": ">=8.0" }, "require-dev": { "behat/behat": "^3.1", @@ -2923,6 +2928,7 @@ "justinrainbow/json-schema": "^5.2.1", "phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.1", "phpdocumentor/type-resolver": "^0.3 || ^0.4 || ^1.4", + "phpspec/prophecy": "^1.10", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.1", "phpstan/phpstan-doctrine": "^1.0", @@ -3025,7 +3031,7 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v2.7.0-rc.2" + "source": "https://github.com/api-platform/core/tree/v2.7.5" }, "funding": [ { @@ -3033,7 +3039,7 @@ "type": "tidelift" } ], - "time": "2022-07-25T08:58:06+00:00" + "time": "2022-11-25T08:03:09+00:00" }, { "name": "doctrine/cache", @@ -3130,16 +3136,16 @@ }, { "name": "doctrine/collections", - "version": "1.7.2", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "3fe77330f5591108bbf1315da7377a7e704ed8a0" + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/3fe77330f5591108bbf1315da7377a7e704ed8a0", - "reference": "3fe77330f5591108bbf1315da7377a7e704ed8a0", + "url": "https://api.github.com/repos/doctrine/collections/zipball/2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e", "shasum": "" }, "require": { @@ -3194,22 +3200,22 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/1.7.2" + "source": "https://github.com/doctrine/collections/tree/1.8.0" }, - "time": "2022-08-27T16:08:58+00:00" + "time": "2022-09-01T20:12:10+00:00" }, { "name": "doctrine/common", - "version": "3.4.0", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3" + "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/e09556bbdf95b8420e649162b19ae9da2d1a80f3", - "reference": "e09556bbdf95b8420e649162b19ae9da2d1a80f3", + "url": "https://api.github.com/repos/doctrine/common/zipball/8b5e5650391f851ed58910b3e3d48a71062eeced", + "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced", "shasum": "" }, "require": { @@ -3217,13 +3223,13 @@ "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^9.0 || ^10.0", "doctrine/collections": "^1", "phpstan/phpstan": "^1.4.1", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^4.0.5", + "symfony/phpunit-bridge": "^6.1", "vimeo/psalm": "^4.4" }, "type": "library", @@ -3271,7 +3277,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.0" + "source": "https://github.com/doctrine/common/tree/3.4.3" }, "funding": [ { @@ -3287,27 +3293,27 @@ "type": "tidelift" } ], - "time": "2022-08-23T19:46:56+00:00" + "time": "2022-10-09T11:47:59+00:00" }, { "name": "doctrine/dbal", - "version": "3.4.4", + "version": "3.5.1", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "4cbbe6e4b9ef6c69d5f4c968c637476f47bb54f5" + "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/4cbbe6e4b9ef6c69d5f4c968c637476f47bb54f5", - "reference": "4cbbe6e4b9ef6c69d5f4c968c637476f47bb54f5", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/f38ee8aaca2d58ee88653cb34a6a3880c23f38a5", + "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1.0", + "doctrine/event-manager": "^1|^2", "php": "^7.4 || ^8.0", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" @@ -3315,14 +3321,14 @@ "require-dev": { "doctrine/coding-standard": "10.0.0", "jetbrains/phpstorm-stubs": "2022.2", - "phpstan/phpstan": "1.8.3", - "phpstan/phpstan-strict-rules": "^1.3", - "phpunit/phpunit": "9.5.24", + "phpstan/phpstan": "1.8.10", + "phpstan/phpstan-strict-rules": "^1.4", + "phpunit/phpunit": "9.5.25", "psalm/plugin-phpunit": "0.17.0", "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", - "vimeo/psalm": "4.27.0" + "vimeo/psalm": "4.29.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -3382,7 +3388,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.4.4" + "source": "https://github.com/doctrine/dbal/tree/3.5.1" }, "funding": [ { @@ -3398,7 +3404,7 @@ "type": "tidelift" } ], - "time": "2022-09-01T21:26:42+00:00" + "time": "2022-10-24T07:26:18+00:00" }, { "name": "doctrine/deprecations", @@ -3445,34 +3451,35 @@ }, { "name": "doctrine/event-manager", - "version": "1.1.2", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683" + "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", - "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520", + "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520", "shasum": "" }, "require": { + "doctrine/deprecations": "^0.5.3 || ^1", "php": "^7.1 || ^8.0" }, "conflict": { "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "~1.4.10 || ^1.5.4", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.8", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.24" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\": "lib/Doctrine/Common" + "Doctrine\\Common\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3516,7 +3523,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.1.2" + "source": "https://github.com/doctrine/event-manager/tree/1.2.0" }, "funding": [ { @@ -3532,7 +3539,7 @@ "type": "tidelift" } ], - "time": "2022-07-27T22:18:11+00:00" + "time": "2022-10-12T20:51:15+00:00" }, { "name": "doctrine/instantiator", @@ -3606,16 +3613,16 @@ }, { "name": "doctrine/orm", - "version": "2.13.1", + "version": "2.13.4", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "35c44a56677adb3ce796138b6e4934ce93ec6811" + "reference": "a5a6cc6630ce497290396d5f206887227820a634" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/35c44a56677adb3ce796138b6e4934ce93ec6811", - "reference": "35c44a56677adb3ce796138b6e4934ce93ec6811", + "url": "https://api.github.com/repos/doctrine/orm/zipball/a5a6cc6630ce497290396d5f206887227820a634", + "reference": "a5a6cc6630ce497290396d5f206887227820a634", "shasum": "" }, "require": { @@ -3642,15 +3649,15 @@ }, "require-dev": { "doctrine/annotations": "^1.13", - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^9.0.2 || ^10.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.8.2", + "phpstan/phpstan": "~1.4.10 || 1.9.2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.26.0" + "vimeo/psalm": "4.30.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -3700,26 +3707,26 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.13.1" + "source": "https://github.com/doctrine/orm/tree/2.13.4" }, - "time": "2022-08-08T09:00:16+00:00" + "time": "2022-11-20T18:53:31+00:00" }, { "name": "doctrine/persistence", - "version": "3.0.3", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "ac6fce61f037d7e54dbb2435f5b5648d86548e23" + "reference": "2a9c70a5e21f8968c5a46b79f819ea52f322080b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/ac6fce61f037d7e54dbb2435f5b5648d86548e23", - "reference": "ac6fce61f037d7e54dbb2435f5b5648d86548e23", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/2a9c70a5e21f8968c5a46b79f819ea52f322080b", + "reference": "2a9c70a5e21f8968c5a46b79f819ea52f322080b", "shasum": "" }, "require": { - "doctrine/event-manager": "^1.0", + "doctrine/event-manager": "^1 || ^2", "php": "^7.2 || ^8.0", "psr/cache": "^1.0 || ^2.0 || ^3.0" }, @@ -3730,14 +3737,14 @@ "require-dev": { "composer/package-versions-deprecated": "^1.11", "doctrine/annotations": "^1.7", - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^10", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.5.0", + "phpstan/phpstan": "1.8.8", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8.5 || ^9.5", "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.22.0" + "vimeo/psalm": "4.29.0" }, "type": "library", "autoload": { @@ -3786,7 +3793,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.0.3" + "source": "https://github.com/doctrine/persistence/tree/3.1.0" }, "funding": [ { @@ -3802,68 +3809,7 @@ "type": "tidelift" } ], - "time": "2022-08-04T21:14:21+00:00" - }, - { - "name": "fig/link-util", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/link-util.git", - "reference": "10e52348a2e9ad4581f2bf3e16458f0861a88c6a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/link-util/zipball/10e52348a2e9ad4581f2bf3e16458f0861a88c6a", - "reference": "10e52348a2e9ad4581f2bf3e16458f0861a88c6a", - "shasum": "" - }, - "require": { - "php": ">=8.0.0", - "psr/link": "^1.1.0 | ^2.0.0" - }, - "provide": { - "psr/link-implementation": "1.0" - }, - "require-dev": { - "phpunit/phpunit": "^9", - "squizlabs/php_codesniffer": "^2.3.1" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Fig\\Link\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common utility implementations for HTTP links", - "keywords": [ - "http", - "http-link", - "link", - "psr", - "psr-13", - "rest" - ], - "support": { - "issues": "https://github.com/php-fig/link-util/issues", - "source": "https://github.com/php-fig/link-util/tree/1.2.0" - }, - "time": "2021-03-11T23:09:19+00:00" + "time": "2022-11-18T14:10:19+00:00" }, { "name": "myclabs/deep-copy", @@ -4210,25 +4156,30 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.1", + "version": "1.6.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { "ext-tokenizer": "*", - "psalm/phar": "^4.8" + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.1", + "phpunit/phpunit": "^9.5", + "rector/rector": "^0.13.9", + "vimeo/psalm": "^4.25" }, "type": "library", "extra": { @@ -4254,27 +4205,27 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" }, - "time": "2022-03-15T21:29:03+00:00" + "time": "2022-10-14T12:47:21+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.15.0", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" @@ -4321,9 +4272,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" }, - "time": "2021-12-08T12:19:24+00:00" + "time": "2022-11-29T15:06:56+00:00" }, { "name": "phpspec/prophecy-phpunit", @@ -4379,16 +4330,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.8.4", + "version": "1.9.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "eed4c9da531f6ebb4787235b6fb486e2c20f34e5" + "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/eed4c9da531f6ebb4787235b6fb486e2c20f34e5", - "reference": "eed4c9da531f6ebb4787235b6fb486e2c20f34e5", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d6fdf01c53978b6429f1393ba4afeca39cc68afa", + "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa", "shasum": "" }, "require": { @@ -4418,7 +4369,7 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.8.4" + "source": "https://github.com/phpstan/phpstan/tree/1.9.2" }, "funding": [ { @@ -4434,20 +4385,20 @@ "type": "tidelift" } ], - "time": "2022-09-03T13:08:04+00:00" + "time": "2022-11-10T09:56:11+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.17", + "version": "9.2.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", - "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", + "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", "shasum": "" }, "require": { @@ -4503,7 +4454,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" }, "funding": [ { @@ -4511,7 +4462,7 @@ "type": "github" } ], - "time": "2022-08-30T12:24:04+00:00" + "time": "2022-11-18T07:47:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4756,16 +4707,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.24", + "version": "9.5.27", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" + "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", - "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", + "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", "shasum": "" }, "require": { @@ -4787,14 +4738,14 @@ "phpunit/php-timer": "^5.0.2", "sebastian/cli-parser": "^1.0.1", "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.5", + "sebastian/comparator": "^4.0.8", "sebastian/diff": "^4.0.3", "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.3", + "sebastian/exporter": "^4.0.5", "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.1", + "sebastian/type": "^3.2", "sebastian/version": "^3.0.2" }, "suggest": { @@ -4838,7 +4789,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" }, "funding": [ { @@ -4848,9 +4799,13 @@ { "url": "https://github.com/sebastianbergmann", "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" } ], - "time": "2022-08-30T07:42:16+00:00" + "time": "2022-12-09T07:31:23+00:00" }, { "name": "psr/link", @@ -5077,16 +5032,16 @@ }, { "name": "sebastian/comparator", - "version": "4.0.6", + "version": "4.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382" + "reference": "fa0f136dd2334583309d32b62544682ee972b51a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/55f4261989e546dc112258c7a75935a81a7ce382", - "reference": "55f4261989e546dc112258c7a75935a81a7ce382", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", + "reference": "fa0f136dd2334583309d32b62544682ee972b51a", "shasum": "" }, "require": { @@ -5139,7 +5094,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" }, "funding": [ { @@ -5147,7 +5102,7 @@ "type": "github" } ], - "time": "2020-10-26T15:49:45+00:00" + "time": "2022-09-14T12:41:17+00:00" }, { "name": "sebastian/complexity", @@ -5271,16 +5226,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", - "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", "shasum": "" }, "require": { @@ -5336,7 +5291,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" }, "funding": [ { @@ -5344,7 +5299,7 @@ "type": "github" } ], - "time": "2021-11-11T14:18:36+00:00" + "time": "2022-09-14T06:03:37+00:00" }, { "name": "sebastian/global-state", @@ -5699,16 +5654,16 @@ }, { "name": "sebastian/type", - "version": "3.1.0", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb44e1cc6e557418387ad815780360057e40753e" + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb44e1cc6e557418387ad815780360057e40753e", - "reference": "fb44e1cc6e557418387ad815780360057e40753e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", "shasum": "" }, "require": { @@ -5720,7 +5675,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -5743,7 +5698,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.1.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" }, "funding": [ { @@ -5751,7 +5706,7 @@ "type": "github" } ], - "time": "2022-08-29T06:55:37+00:00" + "time": "2022-09-12T14:47:03+00:00" }, { "name": "sebastian/version", @@ -5808,20 +5763,20 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "68b53b14f337dbc6f92cf6f1656a0adad42482e0" + "reference": "11c13fff0cd2fe1528ea1e60638fb23c9a0c748f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/68b53b14f337dbc6f92cf6f1656a0adad42482e0", - "reference": "68b53b14f337dbc6f92cf6f1656a0adad42482e0", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/11c13fff0cd2fe1528ea1e60638fb23c9a0c748f", + "reference": "11c13fff0cd2fe1528ea1e60638fb23c9a0c748f", "shasum": "" }, "require": { - "doctrine/event-manager": "~1.0", + "doctrine/event-manager": "^1.2|^2", "doctrine/persistence": "^2|^3", "php": ">=8.1", "symfony/deprecation-contracts": "^2.1|^3", @@ -5837,7 +5792,7 @@ "symfony/cache": "<5.4", "symfony/dependency-injection": "<5.4", "symfony/form": "<5.4", - "symfony/http-kernel": "<5.4", + "symfony/http-kernel": "<6.2", "symfony/messenger": "<5.4", "symfony/property-info": "<5.4", "symfony/security-bundle": "<5.4", @@ -5846,7 +5801,7 @@ }, "require-dev": { "doctrine/annotations": "^1.10.4", - "doctrine/collections": "~1.0", + "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", "doctrine/orm": "^2.7.4", @@ -5857,7 +5812,7 @@ "symfony/doctrine-messenger": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/form": "^5.4.9|^6.0.9", - "symfony/http-kernel": "^5.4|^6.0", + "symfony/http-kernel": "^6.2", "symfony/messenger": "^5.4|^6.0", "symfony/property-access": "^5.4|^6.0", "symfony/property-info": "^5.4|^6.0", @@ -5903,7 +5858,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.1.3" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.0" }, "funding": [ { @@ -5919,20 +5874,20 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2022-11-28T12:28:19+00:00" }, { "name": "symfony/error-handler", - "version": "v6.1.3", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "736e42db3fd586d91820355988698e434e1d8419" + "reference": "b4e41f62c1124378863ff2705158a60da3e4c6b9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/736e42db3fd586d91820355988698e434e1d8419", - "reference": "736e42db3fd586d91820355988698e434e1d8419", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/b4e41f62c1124378863ff2705158a60da3e4c6b9", + "reference": "b4e41f62c1124378863ff2705158a60da3e4c6b9", "shasum": "" }, "require": { @@ -5974,7 +5929,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.1.3" + "source": "https://github.com/symfony/error-handler/tree/v6.2.1" }, "funding": [ { @@ -5990,20 +5945,20 @@ "type": "tidelift" } ], - "time": "2022-07-29T07:42:06+00:00" + "time": "2022-12-01T21:07:46+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.1.4", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "18e0f106a32887bcebef757e5b39c88e39a08f20" + "reference": "d0bbd5a7e81b38f32504399b9199f265505b7bac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/18e0f106a32887bcebef757e5b39c88e39a08f20", - "reference": "18e0f106a32887bcebef757e5b39c88e39a08f20", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d0bbd5a7e81b38f32504399b9199f265505b7bac", + "reference": "d0bbd5a7e81b38f32504399b9199f265505b7bac", "shasum": "" }, "require": { @@ -6011,6 +5966,9 @@ "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.1" }, + "conflict": { + "symfony/cache": "<6.2" + }, "require-dev": { "predis/predis": "~1.0", "symfony/cache": "^5.4|^6.0", @@ -6049,7 +6007,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.1.4" + "source": "https://github.com/symfony/http-foundation/tree/v6.2.1" }, "funding": [ { @@ -6065,25 +6023,26 @@ "type": "tidelift" } ], - "time": "2022-08-19T14:27:04+00:00" + "time": "2022-12-04T18:26:13+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.1.4", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "2144c53a278254af57fa1e6f71427be656fab6f4" + "reference": "bcbd2ea12fee651a4c8bff4f6f00cce2ac1f8404" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/2144c53a278254af57fa1e6f71427be656fab6f4", - "reference": "2144c53a278254af57fa1e6f71427be656fab6f4", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/bcbd2ea12fee651a4c8bff4f6f00cce2ac1f8404", + "reference": "bcbd2ea12fee651a4c8bff4f6f00cce2ac1f8404", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/error-handler": "^6.1", "symfony/event-dispatcher": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", @@ -6094,7 +6053,7 @@ "symfony/cache": "<5.4", "symfony/config": "<6.1", "symfony/console": "<5.4", - "symfony/dependency-injection": "<6.1", + "symfony/dependency-injection": "<6.2", "symfony/doctrine-bridge": "<5.4", "symfony/form": "<5.4", "symfony/http-client": "<5.4", @@ -6114,7 +6073,7 @@ "symfony/config": "^6.1", "symfony/console": "^5.4|^6.0", "symfony/css-selector": "^5.4|^6.0", - "symfony/dependency-injection": "^6.1", + "symfony/dependency-injection": "^6.2", "symfony/dom-crawler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/finder": "^5.4|^6.0", @@ -6159,7 +6118,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.1.4" + "source": "https://github.com/symfony/http-kernel/tree/v6.2.1" }, "funding": [ { @@ -6175,20 +6134,20 @@ "type": "tidelift" } ], - "time": "2022-08-26T14:50:30+00:00" + "time": "2022-12-06T17:28:26+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "75c2fa71d049c1f48e39d208c0cefba97e66335a" + "reference": "1bd3b17db6d2ec284efbdc916600e880d6d858df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/75c2fa71d049c1f48e39d208c0cefba97e66335a", - "reference": "75c2fa71d049c1f48e39d208c0cefba97e66335a", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/1bd3b17db6d2ec284efbdc916600e880d6d858df", + "reference": "1bd3b17db6d2ec284efbdc916600e880d6d858df", "shasum": "" }, "require": { @@ -6242,7 +6201,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.1.3" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.0" }, "funding": [ { @@ -6258,20 +6217,20 @@ "type": "tidelift" } ], - "time": "2022-07-28T13:40:41+00:00" + "time": "2022-11-18T19:08:09+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.26.0", + "version": "v1.27.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2" + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/bf44a9fd41feaac72b074de600314a93e2ae78e2", - "reference": "bf44a9fd41feaac72b074de600314a93e2ae78e2", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", + "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", "shasum": "" }, "require": { @@ -6280,7 +6239,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.26-dev" + "dev-main": "1.27-dev" }, "thanks": { "name": "symfony/polyfill", @@ -6318,7 +6277,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.26.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" }, "funding": [ { @@ -6334,24 +6293,25 @@ "type": "tidelift" } ], - "time": "2022-05-24T11:49:31+00:00" + "time": "2022-11-03T14:55:06+00:00" }, { "name": "symfony/property-access", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5" + "reference": "ed937ca8e103fdcefb43020c8784f87d3e5d09c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5", - "reference": "25108ee9b62d6ef0815007d9c7cf6a7ba40bb7c5", + "url": "https://api.github.com/repos/symfony/property-access/zipball/ed937ca8e103fdcefb43020c8784f87d3e5d09c3", + "reference": "ed937ca8e103fdcefb43020c8784f87d3e5d09c3", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/property-info": "^5.4|^6.0" }, "require-dev": { @@ -6397,7 +6357,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.1.3" + "source": "https://github.com/symfony/property-access/tree/v6.2.0" }, "funding": [ { @@ -6413,20 +6373,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2022-10-28T16:24:13+00:00" }, { "name": "symfony/property-info", - "version": "v6.1.3", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8" + "reference": "ddfa5c49812d7bcfea21f9ad5341092daa82e4cc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8", - "reference": "2fc363ed2f2b5d3b231ed0824e066d140d3fd1d8", + "url": "https://api.github.com/repos/symfony/property-info/zipball/ddfa5c49812d7bcfea21f9ad5341092daa82e4cc", + "reference": "ddfa5c49812d7bcfea21f9ad5341092daa82e4cc", "shasum": "" }, "require": { @@ -6486,7 +6446,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.1.3" + "source": "https://github.com/symfony/property-info/tree/v6.2.0" }, "funding": [ { @@ -6502,20 +6462,20 @@ "type": "tidelift" } ], - "time": "2022-07-19T08:34:05+00:00" + "time": "2022-11-25T07:37:13+00:00" }, { "name": "symfony/serializer", - "version": "v6.1.4", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "03e5987dd9bb98038c60c7af3e58500c81c4aec1" + "reference": "e7655a4697c2af2416f0abc6c9f41189ae3eaf0e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/03e5987dd9bb98038c60c7af3e58500c81c4aec1", - "reference": "03e5987dd9bb98038c60c7af3e58500c81c4aec1", + "url": "https://api.github.com/repos/symfony/serializer/zipball/e7655a4697c2af2416f0abc6c9f41189ae3eaf0e", + "reference": "e7655a4697c2af2416f0abc6c9f41189ae3eaf0e", "shasum": "" }, "require": { @@ -6525,7 +6485,7 @@ "conflict": { "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0", + "phpdocumentor/type-resolver": "<1.4.0|>=1.7.0", "symfony/dependency-injection": "<5.4", "symfony/property-access": "<5.4", "symfony/property-info": "<5.4", @@ -6587,7 +6547,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.1.4" + "source": "https://github.com/symfony/serializer/tree/v6.2.1" }, "funding": [ { @@ -6603,20 +6563,20 @@ "type": "tidelift" } ], - "time": "2022-08-26T10:32:31+00:00" + "time": "2022-12-04T18:26:13+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc" + "reference": "68cce71402305a015f8c1589bfada1280dc64fe7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/606be0f48e05116baef052f7f3abdb345c8e02cc", - "reference": "606be0f48e05116baef052f7f3abdb345c8e02cc", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/68cce71402305a015f8c1589bfada1280dc64fe7", + "reference": "68cce71402305a015f8c1589bfada1280dc64fe7", "shasum": "" }, "require": { @@ -6628,7 +6588,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -6668,7 +6628,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/translation-contracts/tree/v3.2.0" }, "funding": [ { @@ -6684,20 +6644,20 @@ "type": "tidelift" } ], - "time": "2022-06-27T17:24:16+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "symfony/validator", - "version": "v6.1.4", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "14ec426b9c8ca8cf02bd863a645fb0cc0d73db79" + "reference": "0f74ad1cab71f5899dca8233db774a50f8656de0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/14ec426b9c8ca8cf02bd863a645fb0cc0d73db79", - "reference": "14ec426b9c8ca8cf02bd863a645fb0cc0d73db79", + "url": "https://api.github.com/repos/symfony/validator/zipball/0f74ad1cab71f5899dca8233db774a50f8656de0", + "reference": "0f74ad1cab71f5899dca8233db774a50f8656de0", "shasum": "" }, "require": { @@ -6776,7 +6736,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.1.4" + "source": "https://github.com/symfony/validator/tree/v6.2.0" }, "funding": [ { @@ -6792,20 +6752,20 @@ "type": "tidelift" } ], - "time": "2022-08-12T13:09:07+00:00" + "time": "2022-11-25T08:42:40+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.1.3", + "version": "v6.2.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427" + "reference": "1e7544c8698627b908657e5276854d52ab70087a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", - "reference": "d5a5e44a2260c5eb5e746bf4f1fbd12ee6ceb427", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1e7544c8698627b908657e5276854d52ab70087a", + "reference": "1e7544c8698627b908657e5276854d52ab70087a", "shasum": "" }, "require": { @@ -6864,7 +6824,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.1.3" + "source": "https://github.com/symfony/var-dumper/tree/v6.2.1" }, "funding": [ { @@ -6880,20 +6840,20 @@ "type": "tidelift" } ], - "time": "2022-07-20T13:46:29+00:00" + "time": "2022-12-03T22:32:58+00:00" }, { "name": "symfony/web-link", - "version": "v6.1.0", + "version": "v6.2.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "d6ef738f97b60d859652d92f10bf8645bca28cd6" + "reference": "068136a48bd945b0b4a4a13ceaa1327ac6606aa3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/d6ef738f97b60d859652d92f10bf8645bca28cd6", - "reference": "d6ef738f97b60d859652d92f10bf8645bca28cd6", + "url": "https://api.github.com/repos/symfony/web-link/zipball/068136a48bd945b0b4a4a13ceaa1327ac6606aa3", + "reference": "068136a48bd945b0b4a4a13ceaa1327ac6606aa3", "shasum": "" }, "require": { @@ -6950,7 +6910,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v6.1.0" + "source": "https://github.com/symfony/web-link/tree/v6.2.0" }, "funding": [ { @@ -6966,7 +6926,7 @@ "type": "tidelift" } ], - "time": "2022-02-25T11:15:52+00:00" + "time": "2022-08-25T15:27:04+00:00" }, { "name": "theseer/tokenizer", @@ -7136,8 +7096,7 @@ "aliases": [], "minimum-stability": "stable", "stability-flags": { - "nette/utils": 20, - "api-platform/core": 5 + "nette/utils": 20 }, "prefer-stable": false, "prefer-lowest": false, diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index 2924cf95..44e725b4 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -199,18 +199,19 @@ protected function toPhpDocType(Property $property, bool $adderOrRemover = false { $suffix = $property->isNullable ? '|null' : ''; if ($property->isEnum) { - if ($property->isArray) { + if ($property->isArray()) { return 'string[]'.$suffix; } return 'string'.$suffix; } - $enforcedNonArrayProperty = clone $property; - $enforcedNonArrayProperty->isArray = false; + if (!$property->reference && null !== $phpDocType = $this->phpTypeConverter->getPhpType($property)) { + if ('array' === $phpDocType && $property->type) { + $phpDocType = $property->type->getPhp(); + } - if (!$property->reference && null !== $phpDocType = $this->phpTypeConverter->getPhpType($enforcedNonArrayProperty)) { - return ($property->isArray ? sprintf('%s[]', $phpDocType) : $phpDocType).$suffix; + return $phpDocType.$suffix; } if (!$property->reference) { @@ -218,7 +219,7 @@ protected function toPhpDocType(Property $property, bool $adderOrRemover = false } $phpDocType = $property->reference->interfaceName() ?: $property->reference->name(); - if (!$property->isArray || $adderOrRemover) { + if ($adderOrRemover || !$property->isArray()) { return $phpDocType.$suffix; } diff --git a/src/AttributeGenerator/ConstraintAttributeGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php index a50f4705..a5ea99d6 100644 --- a/src/AttributeGenerator/ConstraintAttributeGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -42,8 +42,8 @@ public function generatePropertyAttributes(Property $property, string $className $asserts = []; - if (!$property->isArray && $property->type) { - switch ($property->type) { + if ($property->type && !$property->isArray()) { + switch ((string) $property->type) { case 'url': $asserts[] = new Attribute('Assert\Url'); break; @@ -74,7 +74,7 @@ public function generatePropertyAttributes(Property $property, string $className if ($property->isEnum && $property->reference) { $args = ['callback' => [new Literal(sprintf('%s::class', $property->reference->name())), 'toArray']]; - if ($property->isArray) { + if ($property->isArray()) { $args['multiple'] = true; } diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index b4c0f84d..e75fe6af 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -17,6 +17,7 @@ use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\CompositeType; use ApiPlatform\SchemaGenerator\Model\Use_; use Nette\PhpGenerator\Literal; @@ -86,34 +87,38 @@ public function generatePropertyAttributes(Property $property, string $className $type = null; if ($property->isEnum) { - $type = $property->isArray ? 'simple_array' : 'string'; - } elseif ($property->isArray && $property->type) { + $type = $property->isArray() ? 'simple_array' : 'string'; + } elseif (!$property->reference && $property->isArray()) { $type = 'collection'; - } elseif (!$property->isArray && $property->type && !$property->reference && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { - switch ($property->type) { - case 'time': - $type = 'time'; - break; - case 'dateTime': - $type = 'date'; - break; - default: - $type = $phpType; - switch ($phpType) { - case 'bool': - $type = 'boolean'; - break; - case 'int': - $type = 'integer'; - break; - case '\\'.\DateTimeInterface::class: - $type = 'date'; - break; - case '\\'.\DateInterval::class: - $type = 'string'; - break; - } - break; + } elseif ($property->type && !$property->reference && !$property->isArray() && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { + if ($property->type instanceof CompositeType) { + $type = 'raw'; + } else { + switch ((string) $property->type) { + case 'time': + $type = 'time'; + break; + case 'dateTime': + $type = 'date'; + break; + default: + $type = $phpType; + switch ($phpType) { + case 'bool': + $type = 'boolean'; + break; + case 'int': + $type = 'integer'; + break; + case '\\'.\DateTimeInterface::class: + $type = 'date'; + break; + case '\\'.\DateInterval::class: + $type = 'string'; + break; + } + break; + } } } diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index e418c043..6ddad3f9 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -17,6 +17,7 @@ use ApiPlatform\SchemaGenerator\Model\Attribute; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\CompositeType; use ApiPlatform\SchemaGenerator\Model\Use_; use Nette\PhpGenerator\Literal; @@ -102,10 +103,10 @@ public function generatePropertyAttributes(Property $property, string $className $type = null; if ($property->isEnum) { - $type = $property->isArray ? 'simple_array' : 'string'; - } elseif ($property->isArray && $property->type) { + $type = $property->isArray() ? 'simple_array' : 'string'; + } elseif (!$property->reference && $property->isArray()) { $type = 'json'; - } elseif (!$property->isArray && $property->type && !$property->reference && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { + } elseif ($property->type && !$property instanceof CompositeType && !$property->reference && !$property->isArray() && null !== ($phpType = $this->phpTypeConverter->getPhpType($property, $this->config, []))) { switch ($property->type) { case 'time': $type = 'time'; diff --git a/src/ClassMutator/AnnotationsAppender.php b/src/ClassMutator/AnnotationsAppender.php index 14d5c5ad..fc074e65 100644 --- a/src/ClassMutator/AnnotationsAppender.php +++ b/src/ClassMutator/AnnotationsAppender.php @@ -119,7 +119,7 @@ private function generatePropertiesAnnotations(Class_ $class): void $property->addGetterAnnotation($getterAnnotation); } - if ($property->isArray) { + if ($property->isArray()) { foreach ($annotationGenerator->generateAdderAnnotations($property) as $adderAnnotation) { $property->addAdderAnnotation($adderAnnotation); } diff --git a/src/ClassMutator/ClassPropertiesTypehintMutator.php b/src/ClassMutator/ClassPropertiesTypehintMutator.php index 9ba9db2d..62e46b90 100644 --- a/src/ClassMutator/ClassPropertiesTypehintMutator.php +++ b/src/ClassMutator/ClassPropertiesTypehintMutator.php @@ -14,6 +14,7 @@ namespace ApiPlatform\SchemaGenerator\ClassMutator; use ApiPlatform\SchemaGenerator\Model\Class_; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; final class ClassPropertiesTypehintMutator implements ClassMutatorInterface @@ -48,9 +49,9 @@ public function __invoke(Class_ $class, array $context): void $this->classes ); - if ($property->isArray) { + if ($property->type instanceof ArrayType) { $nonArrayForcedProperty = clone $property; - $nonArrayForcedProperty->isArray = false; + $nonArrayForcedProperty->type = $property->type->type; $property->adderRemoverTypeHint = $this->phpTypeConverter->getPhpType($nonArrayForcedProperty, $this->config, $this->classes); } diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 7827a72c..a7003fc8 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -318,7 +318,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi } foreach ($sortedProperties as $property) { - if ($property->isArray && 'array' !== $property->typeHint && !$property->isEnum) { + if (!$property->isEnum && 'array' !== $property->typeHint && $property->isArray()) { $constructor->addBody('$this->? = new ArrayCollection();', [$property->name()]); } } diff --git a/src/Model/Property.php b/src/Model/Property.php index 58221496..27c27226 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -13,6 +13,8 @@ namespace ApiPlatform\SchemaGenerator\Model; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; +use ApiPlatform\SchemaGenerator\Model\Type\Type; use Nette\PhpGenerator\ClassType; use Nette\PhpGenerator\Method; use Nette\PhpGenerator\PhpNamespace; @@ -25,14 +27,10 @@ abstract class Property private string $name; public string $cardinality; - /** @var ?string the data type (array and object are not one) */ - public ?string $type = null; + /** @var ?Type the data types (object is not one) */ + public ?Type $type = null; /** @var mixed */ public $defaultValue = null; - /** @var ?string the array data type (object is not one) */ - public ?string $arrayType = null; - /** @var bool can be true and array type false if the property is an array of references */ - public bool $isArray = false; public ?Class_ $reference = null; public bool $isReadable = true; public bool $isWritable = true; @@ -76,6 +74,11 @@ abstract public function description(): ?string; abstract public function rdfType(): ?string; + public function isArray(): bool + { + return $this->type instanceof ArrayType; + } + public function addAnnotation(string $annotation): self { if ('' === $annotation || !\in_array($annotation, $this->annotations, true)) { @@ -146,7 +149,7 @@ public function toNetteProperty(PhpNamespace $namespace, string $visibility = nu $property->setType($this->resolveName($namespace, $this->typeHint)); } - if (!$this->isArray || $this->isTypeHintedAsCollection()) { + if (!$this->isArray() || $this->isTypeHintedAsCollection()) { $property->setNullable($this->isNullable); } @@ -206,7 +209,7 @@ private function generateGetter(PhpNamespace $namespace): Method } if ($this->typeHint) { $getter->setReturnType($this->resolveName($namespace, $this->typeHint)); - if ($this->isNullable && !$this->isArray) { + if ($this->isNullable && !$this->isArray()) { $getter->setReturnNullable(); } } @@ -229,7 +232,7 @@ private function generateMutators( } $mutators = []; - if ($this->isArray) { + if ($this->isArray()) { $singularProperty = $singularize($this->name()); $adder = (new Method('add'.ucfirst($singularProperty)))->setVisibility(ClassType::VISIBILITY_PUBLIC); @@ -307,7 +310,7 @@ private function generateMutators( */ private function guessDefaultGeneratedValue(bool $useDoctrineCollections = true) { - if ($this->isArray && !$this->isTypeHintedAsCollection() && ($this->isEnum || !$this->typeHint || 'array' === $this->typeHint || !$useDoctrineCollections)) { + if (($this->isEnum || !$this->typeHint || 'array' === $this->typeHint || !$useDoctrineCollections) && $this->isArray() && !$this->isTypeHintedAsCollection()) { return []; } diff --git a/src/Model/Type/ArrayType.php b/src/Model/Type/ArrayType.php new file mode 100644 index 00000000..f6e496d1 --- /dev/null +++ b/src/Model/Type/ArrayType.php @@ -0,0 +1,42 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model\Type; + +final class ArrayType implements Type +{ + public ?Type $type; + + public function __construct(?Type $type = null) + { + $this->type = $type; + } + + public function __toString(): string + { + if ($this->type instanceof CompositeType) { + return '('.$this->type.')[]'; + } + + return $this->type ? $this->type.'[]' : 'array'; + } + + public function getPhp(): string + { + if ($this->type instanceof CompositeType) { + return '('.$this->type.')[]'; + } + + return $this->type ? $this->type.'[]' : 'array'; + } +} diff --git a/src/Model/Type/CompositeType.php b/src/Model/Type/CompositeType.php new file mode 100644 index 00000000..538742f0 --- /dev/null +++ b/src/Model/Type/CompositeType.php @@ -0,0 +1,18 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model\Type; + +interface CompositeType extends Type +{ +} diff --git a/src/Model/Type/PrimitiveType.php b/src/Model/Type/PrimitiveType.php new file mode 100644 index 00000000..dd06776f --- /dev/null +++ b/src/Model/Type/PrimitiveType.php @@ -0,0 +1,34 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model\Type; + +final class PrimitiveType implements Type +{ + public string $name; + + public function __construct(string $name) + { + $this->name = $name; + } + + public function __toString(): string + { + return $this->name; + } + + public function getPhp(): string + { + return $this->name; + } +} diff --git a/src/Model/Type/Type.php b/src/Model/Type/Type.php new file mode 100644 index 00000000..8d4139fc --- /dev/null +++ b/src/Model/Type/Type.php @@ -0,0 +1,21 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model\Type; + +interface Type +{ + public function __toString(): string; + + public function getPhp(): string; +} diff --git a/src/Model/Type/UnionType.php b/src/Model/Type/UnionType.php new file mode 100644 index 00000000..3fd09c86 --- /dev/null +++ b/src/Model/Type/UnionType.php @@ -0,0 +1,44 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Model\Type; + +final class UnionType implements CompositeType +{ + /** @var Type[] */ + public array $types; + + /** + * @param Type[] $types + */ + public function __construct(array $types) + { + $this->types = $types; + } + + public function __toString(): string + { + return implode('|', array_map(fn (Type $type) => $type instanceof CompositeType ? '('.$type.')' : $type, $this->types)); + } + + public function getPhp(): string + { + // Deduplicate PHP types. + $phpTypes = []; + foreach ($this->types as $type) { + $phpTypes[$type->getPhp()] = $type; + } + + return implode('|', array_map(fn (Type $type) => $type instanceof CompositeType ? '('.$type->getPhp().')' : $type->getPhp(), $phpTypes)); + } +} diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index 9f42ea9d..b23d50a9 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -40,6 +40,7 @@ final class ClassGenerator { use LoggerAwareTrait; + use SchemaTraversalTrait; private InflectorInterface $inflector; private PhpTypeConverterInterface $phpTypeConverter; @@ -153,7 +154,7 @@ public function generate(OpenApi $openApi, array $config): array if ($reference = $classes[preg_replace('/Ids?$/', '', $this->inflector->singularize(u($property->name())->title()->toString())[0])] ?? null) { $property->reference = $reference; $property->cardinality = $property->isNullable ? CardinalitiesExtractor::CARDINALITY_0_1 : CardinalitiesExtractor::CARDINALITY_1_1; - if ($property->isArray) { + if ($property->isArray()) { $property->cardinality = $property->isNullable ? CardinalitiesExtractor::CARDINALITY_0_N : CardinalitiesExtractor::CARDINALITY_1_N; } } @@ -166,7 +167,7 @@ public function generate(OpenApi $openApi, array $config): array // Try to guess the mapped by from the references foreach ($class->properties() as $property) { - if ($property->reference && $property->isArray) { + if ($property->reference && $property->isArray()) { $mappedByName = strtolower($class->name()); foreach ($property->reference->properties() as $referenceProperty) { if ($mappedByName === $referenceProperty->name()) { @@ -227,7 +228,12 @@ private function buildClassFromSchema(Schema $schema, string $name, array $confi $class->setRdfType($schema->externalDocs->url); } - foreach ($schema->properties as $propertyName => $schemaProperty) { + $schemaProperties = []; + foreach ($this->getSchemaItem($schema) as $schemaItem) { + $schemaProperties = array_merge($schemaProperties, $schemaItem->properties); + } + + foreach ($schemaProperties as $propertyName => $schemaProperty) { \assert($schemaProperty instanceof Schema); $property = ($this->propertyGenerator)($propertyName, $config, $class, ['schema' => $schema, 'property' => $schemaProperty]); if ($property) { diff --git a/src/OpenApi/Model/Type/PrimitiveType.php b/src/OpenApi/Model/Type/PrimitiveType.php new file mode 100644 index 00000000..4f8603e8 --- /dev/null +++ b/src/OpenApi/Model/Type/PrimitiveType.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi\Model\Type; + +use ApiPlatform\SchemaGenerator\Model\Type\Type; + +final class PrimitiveType implements Type +{ + public string $name; + + public function __construct(string $name) + { + $this->name = $name; + } + + public function __toString(): string + { + return $this->name; + } + + public function getPhp(): string + { + /* @see https://swagger.io/specification/#data-types */ + switch ($this->name) { + case 'integer': + return 'int'; + case 'boolean': + return 'bool'; + case 'float': + case 'double': + return 'float'; + case 'date': + case 'dateTime': + return '\\'.\DateTimeInterface::class; + default: + return 'string'; + } + } +} diff --git a/src/OpenApi/PhpTypeConverter.php b/src/OpenApi/PhpTypeConverter.php index a2a6b303..e0b82fe0 100644 --- a/src/OpenApi/PhpTypeConverter.php +++ b/src/OpenApi/PhpTypeConverter.php @@ -20,33 +20,23 @@ final class PhpTypeConverter implements PhpTypeConverterInterface { public function getPhpType(Property $property, array $config = [], array $classes = []): ?string { - if ($property->reference && $property->isArray) { + if ($property->reference && $property->isArray()) { return ($config['doctrine']['useCollection'] ?? false) ? 'Collection' : 'array'; } - if ($property->reference && !$property->isArray) { + if ($property->reference && !$property->isArray()) { return $property->reference->name(); } - if ($property->isArray) { + if ($property->isArray()) { return 'array'; } - /* @see https://swagger.io/specification/#data-types */ - switch ($property->type) { - case 'integer': - return 'int'; - case 'boolean': - return 'bool'; - case 'float': - case 'double': - return 'float'; - case 'date': - case 'dateTime': - return '\\'.\DateTimeInterface::class; - default: - return 'string'; + if (!$property->type) { + return 'string'; } + + return $property->type->getPhp(); } public function escapeIdentifier(string $identifier): string diff --git a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php index 73d7ee94..830f2c77 100644 --- a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php @@ -14,7 +14,9 @@ namespace ApiPlatform\SchemaGenerator\OpenApi\PropertyGenerator; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\PrimitiveType; use ApiPlatform\SchemaGenerator\OpenApi\Model\Property as OpenApiProperty; +use ApiPlatform\SchemaGenerator\OpenApi\Model\Type\PrimitiveType as OpenApiPrimitiveType; use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGenerator as CommonIdPropertyGenerator; use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGeneratorInterface; @@ -29,6 +31,10 @@ public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property { - return ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new OpenApiProperty('id')); + $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new OpenApiProperty('id')); + + $idProperty->type = $idProperty->type instanceof PrimitiveType ? new OpenApiPrimitiveType($idProperty->type->name) : null; + + return $idProperty; } } diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index 1eae587f..ef0d0135 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -15,7 +15,12 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; +use ApiPlatform\SchemaGenerator\Model\Type\Type; +use ApiPlatform\SchemaGenerator\Model\Type\UnionType; use ApiPlatform\SchemaGenerator\OpenApi\Model\Property as OpenApiProperty; +use ApiPlatform\SchemaGenerator\OpenApi\Model\Type\PrimitiveType; +use ApiPlatform\SchemaGenerator\OpenApi\SchemaTraversalTrait; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator as CommonPropertyGenerator; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; use cebe\openapi\spec\Schema; @@ -24,6 +29,8 @@ final class PropertyGenerator implements PropertyGeneratorInterface { + use SchemaTraversalTrait; + private PropertyGeneratorInterface $propertyGenerator; public function __construct(?PropertyGeneratorInterface $propertyGenerator = null) @@ -41,7 +48,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty = $context['property']; $openApiProperty = new OpenApiProperty($name); - $openApiProperty->isArray = 'array' === $schemaProperty->type; + $openApiProperty->type = $this->getType($schemaProperty); $openApiProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $openApiProperty); @@ -51,10 +58,6 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $requiredFields = $schema->required ?? []; - $openApiProperty->type = $this->getType($schemaProperty->type, $schemaProperty->format); - $openApiProperty->arrayType = $openApiProperty->isArray && $schemaProperty->items instanceof Schema - ? $this->getType($schemaProperty->items->type, $schemaProperty->items->format) - : null; if ($schemaProperty->description) { $openApiProperty->setDescription($schemaProperty->description); } @@ -70,22 +73,66 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont return $openApiProperty; } - private function getType(string $type, ?string $format): ?string + private function getType(Schema $schemaProperty, bool $inComposite = false): ?Type { + if ($schemaProperty->oneOf) { + $types = []; + foreach ($schemaProperty->oneOf as $oneOfProperty) { + \assert($oneOfProperty instanceof Schema); + if ($oneOfType = $this->getType($oneOfProperty, true)) { + $types[] = $oneOfType; + } + } + + return new UnionType($types); + } + + // Merge properties. + if ($schemaProperty->allOf) { + $type = 'string'; + $format = 'string'; + foreach ($this->getSchemaItem($schemaProperty) as $schemaPropertyItem) { + $type = $schemaPropertyItem->type ?? $type; + $format = $schemaPropertyItem->format ?? $format; + } + $schemaProperty = new Schema([ + 'type' => $type, + 'format' => $format, + ]); + } + + // Not supported. + if ($schemaProperty->anyOf || $schemaProperty->not) { + return null; + } + + if ('array' === $schemaProperty->type) { + return new ArrayType($schemaProperty->items instanceof Schema ? $this->getType($schemaProperty->items) : null); + } + + $type = $schemaProperty->type; + $format = $schemaProperty->format; + + $primitiveType = new PrimitiveType($type); + if ($format) { switch ($format) { case 'int32': case 'int64': - return 'integer'; + $primitiveType = new PrimitiveType('integer'); + + break; default: - return u(str_replace('-', '_', $format))->camel()->toString(); + $primitiveType = new PrimitiveType(u(str_replace('-', '_', $format))->camel()->toString()); } + + return $primitiveType; } - if (\in_array($type, ['array', 'object'], true)) { + if (!$inComposite && \in_array($type, ['array', 'object'], true)) { return null; } - return $type; + return $primitiveType; } } diff --git a/src/OpenApi/SchemaTraversalTrait.php b/src/OpenApi/SchemaTraversalTrait.php new file mode 100644 index 00000000..21b6b8b6 --- /dev/null +++ b/src/OpenApi/SchemaTraversalTrait.php @@ -0,0 +1,50 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\OpenApi; + +use cebe\openapi\spec\Schema; + +trait SchemaTraversalTrait +{ + /** + * @return \Generator + */ + private function getSchemaItem(Schema $schema): \Generator + { + if (!$schema->oneOf && !$schema->allOf) { + yield $schema; + + return; + } + + if ($schema->oneOf) { + // Only use the first oneOf item. Needs to be improved. + $oneOfSchema = $schema->oneOf[0]; + \assert($oneOfSchema instanceof Schema); + foreach ($this->getSchemaItem($oneOfSchema) as $schemaItem) { + yield $schemaItem; + } + } + + foreach ($schema->allOf ?? [] as $allOfSchema) { + \assert($allOfSchema instanceof Schema); + foreach ($this->getSchemaItem($allOfSchema) as $schemaItem) { + yield $schemaItem; + } + } + + // Once all items have been used, yield the main schema in case there are some properties in it. + yield $schema; + } +} diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index 68cbbfa3..e06a924d 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -25,11 +25,11 @@ public function getPhpType(Property $property, array $config = [], array $classe throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); } - if ($property->isArray && $property->reference) { + if ($property->reference && $property->isArray()) { return ($config['doctrine']['useCollection'] ?? false) ? 'Collection' : 'array'; } - if ($property->isArray) { + if ($property->isArray()) { return 'array'; } @@ -61,31 +61,7 @@ private function getNonArrayType(SchemaProperty $property, array $classes): ?str } if ($property->type) { - switch ($property->type) { - case 'integer': - case 'negativeInteger': - case 'nonNegativeInteger': - case 'positiveInteger': - case 'nonPositiveInteger': - case 'byte': - return 'int'; - case 'boolean': - return 'bool'; - case 'float': - case 'double': - case 'decimal': - return 'float'; - case 'date': - case 'dateTime': - case 'time': - return '\\'.\DateTimeInterface::class; - case 'duration': - return '\\'.\DateInterval::class; - case 'mixed': - return null; - default: - return 'string'; - } + return $property->type->getPhp(); } $typeName = $property->rangeName; diff --git a/src/PropertyGenerator/IdPropertyGenerator.php b/src/PropertyGenerator/IdPropertyGenerator.php index 8208ffea..2559f7b1 100644 --- a/src/PropertyGenerator/IdPropertyGenerator.php +++ b/src/PropertyGenerator/IdPropertyGenerator.php @@ -15,6 +15,7 @@ use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\PrimitiveType; final class IdPropertyGenerator implements IdPropertyGeneratorInterface { @@ -57,7 +58,7 @@ public function __invoke(string $generationStrategy, bool $supportsWritableId, ? $property->isUnique = false; $property->isCustom = true; $property->isId = true; - $property->type = $type; + $property->type = new PrimitiveType($type); $property->typeHint = $typeHint; return $property; diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index 5f2562fd..0df61662 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -30,7 +30,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $property->isCustom = $isCustom; - if ($property->isArray) { + if ($property->isArray()) { $class->hasConstructor = true; } diff --git a/src/Schema/Model/Type/PrimitiveType.php b/src/Schema/Model/Type/PrimitiveType.php new file mode 100644 index 00000000..16b62891 --- /dev/null +++ b/src/Schema/Model/Type/PrimitiveType.php @@ -0,0 +1,60 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +declare(strict_types=1); + +namespace ApiPlatform\SchemaGenerator\Schema\Model\Type; + +use ApiPlatform\SchemaGenerator\Model\Type\Type; + +final class PrimitiveType implements Type +{ + public string $name; + + public function __construct(string $name) + { + $this->name = $name; + } + + public function __toString(): string + { + return $this->name; + } + + public function getPhp(): string + { + switch ($this->name) { + case 'integer': + case 'negativeInteger': + case 'nonNegativeInteger': + case 'positiveInteger': + case 'nonPositiveInteger': + case 'byte': + return 'int'; + case 'boolean': + return 'bool'; + case 'float': + case 'double': + case 'decimal': + return 'float'; + case 'date': + case 'dateTime': + case 'time': + return '\\'.\DateTimeInterface::class; + case 'duration': + return '\\'.\DateInterval::class; + case 'mixed': + return ''; + default: + return 'string'; + } + } +} diff --git a/src/Schema/PropertyGenerator/IdPropertyGenerator.php b/src/Schema/PropertyGenerator/IdPropertyGenerator.php index e78e6816..93cd83a7 100644 --- a/src/Schema/PropertyGenerator/IdPropertyGenerator.php +++ b/src/Schema/PropertyGenerator/IdPropertyGenerator.php @@ -14,9 +14,11 @@ namespace ApiPlatform\SchemaGenerator\Schema\PropertyGenerator; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\PrimitiveType; use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGenerator as CommonIdPropertyGenerator; use ApiPlatform\SchemaGenerator\PropertyGenerator\IdPropertyGeneratorInterface; use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType as SchemaPrimitiveType; use EasyRdf\Resource as RdfResource; final class IdPropertyGenerator implements IdPropertyGeneratorInterface @@ -36,6 +38,8 @@ public function __invoke(string $generationStrategy, bool $supportsWritableId, ? throw new \LogicException(sprintf('ID property has to be an instance of "%s".', SchemaProperty::class)); } + $idProperty->type = $idProperty->type instanceof PrimitiveType ? new SchemaPrimitiveType($idProperty->type->name) : null; + $rangeName = 'Text'; $uri = 'https://schema.org/Text'; if ('auto' === $generationStrategy) { diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index e10b248c..124e88cf 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -17,10 +17,12 @@ use ApiPlatform\SchemaGenerator\GoodRelationsBridge; use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; use ApiPlatform\SchemaGenerator\PhpTypeConverterInterface; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGenerator as CommonPropertyGenerator; use ApiPlatform\SchemaGenerator\PropertyGenerator\PropertyGeneratorInterface; use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType; use ApiPlatform\SchemaGenerator\Schema\TypeConverter; use EasyRdf\Resource as RdfResource; use Psr\Log\LoggerAwareTrait; @@ -134,7 +136,11 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont ], true); $schemaProperty = new SchemaProperty($name); - $schemaProperty->isArray = $isArray; + if ($isArray) { + $schemaProperty->type = new ArrayType($type ? new PrimitiveType($type) : null); + } elseif ($type) { + $schemaProperty->type = new PrimitiveType($type); + } $schemaProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $schemaProperty); @@ -150,7 +156,6 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty->resource = $typeProperty; $schemaProperty->range = $range; $schemaProperty->rangeName = $rangeName; - $schemaProperty->type = $type; $schemaProperty->defaultValue = $propertyConfig['defaultValue'] ?? null; $schemaProperty->cardinality = $cardinality; $schemaProperty->isReadable = $propertyConfig['readable'] ?? true; diff --git a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php index 5c262729..85545a24 100644 --- a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php @@ -17,9 +17,11 @@ use ApiPlatform\SchemaGenerator\Model\Class_; use ApiPlatform\SchemaGenerator\Model\Interface_; use ApiPlatform\SchemaGenerator\Model\Property; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use ApiPlatform\SchemaGenerator\Schema\Model\Property as SchemaProperty; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType as SchemaPrimitiveType; use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; @@ -87,9 +89,8 @@ public function provideGeneratePropertyAnnotationsCases(): \Generator $resource = new RdfResource('https://schema.org/review', $graph); $resource->addResource('rdfs:comment', 'A review of the item.'); $property->resource = $resource; - $property->isArray = true; $property->typeHint = 'array'; - $property->type = 'string'; + $property->type = new ArrayType(new SchemaPrimitiveType('string')); $property->range = new RdfResource('https://schema.org/Text'); yield 'array of strings property' => [$property, 'Place', ['@var string[]|null A review of the item.', '@see https://schema.org/review', '']]; @@ -97,8 +98,8 @@ public function provideGeneratePropertyAnnotationsCases(): \Generator $property = new SchemaProperty('address'); $graph = new RdfGraph(); $property->isNullable = false; - $property->isArray = true; $property->typeHint = 'array'; + $property->type = new ArrayType(); $property->reference = new SchemaClass('PostalAddress', new RdfResource('https://schema.org/PostalAddress', $graph)); yield 'reference property' => [$property, 'Place', ['@var Collection ', '']]; diff --git a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php index 03f1df0a..9f4d2e6f 100644 --- a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php @@ -15,10 +15,12 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\ConstraintAttributeGenerator; use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; use ApiPlatform\SchemaGenerator\Model\Use_; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType as SchemaPrimitiveType; use ApiPlatform\SchemaGenerator\TypesGenerator; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; @@ -93,14 +95,14 @@ public function provideGeneratePropertyAttributesCases(): \Generator $property = new Property('prop'); $property->resource = new RdfResource('https://schema.org/email'); - $property->type = 'string'; + $property->type = new SchemaPrimitiveType('string'); $property->isNullable = false; yield 'email' => [$property, [new Attribute('Assert\Email'), new Attribute('Assert\NotNull')]]; $property = new Property('prop'); $property->reference = new SchemaClass('Enum', new RdfResource('https://schema.org/Enum', new RdfGraph())); $property->isEnum = true; - $property->isArray = true; + $property->type = new ArrayType(); yield 'enum' => [$property, [new Attribute('Assert\Choice', ['callback' => [new Literal('Enum::class'), 'toArray'], 'multiple' => true])]]; } diff --git a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php index 2c1c2be6..42dcc0e9 100644 --- a/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineMongoDBAttributeGeneratorTest.php @@ -16,9 +16,11 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineMongoDBAttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType as SchemaPrimitiveType; use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use ApiPlatform\SchemaGenerator\TypesGenerator; use EasyRdf\Graph as RdfGraph; @@ -57,7 +59,7 @@ protected function setUp(): void $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; $idProperty->range = new RdfResource('https://schema.org/identifier'); - $idProperty->type = 'string'; + $idProperty->type = new SchemaPrimitiveType('string'); $idProperty->isId = true; $vehicle->addProperty($idProperty); $enumProperty = new Property('enum'); @@ -65,18 +67,17 @@ protected function setUp(): void $enumProperty->range = new RdfResource('https://schema.org/Thing'); $enumProperty->reference = new SchemaClass('Thing', new RdfResource('htts://schema.org/Thing', $graph)); $enumProperty->isEnum = true; - $enumProperty->isArray = true; + $enumProperty->type = new ArrayType(); $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); $collectionProperty->rangeName = 'string'; $collectionProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#string'); - $collectionProperty->type = 'string'; - $collectionProperty->isArray = true; + $collectionProperty->type = new ArrayType(new SchemaPrimitiveType('string')); $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); $weightProperty->rangeName = 'nonPositiveInteger'; $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); - $weightProperty->type = 'nonPositiveInteger'; + $weightProperty->type = new SchemaPrimitiveType('nonPositiveInteger'); $vehicle->addProperty($weightProperty); $productProperty = new Property('product'); $productProperty->rangeName = 'Product'; @@ -94,7 +95,7 @@ protected function setUp(): void $relationsProperty->range = new RdfResource('https://schema.org/Person'); $relationsProperty->reference = new SchemaClass('Person', new RdfResource('htts://schema.org/Person', $graph)); $relationsProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; - $relationsProperty->isArray = true; + $relationsProperty->type = new ArrayType(); $vehicle->addProperty($relationsProperty); $this->classMap[$vehicle->name()] = $vehicle; diff --git a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php index f0a86ab9..a8a11942 100644 --- a/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/DoctrineOrmAttributeGeneratorTest.php @@ -16,9 +16,11 @@ use ApiPlatform\SchemaGenerator\AttributeGenerator\DoctrineOrmAttributeGenerator; use ApiPlatform\SchemaGenerator\CardinalitiesExtractor; use ApiPlatform\SchemaGenerator\Model\Attribute; +use ApiPlatform\SchemaGenerator\Model\Type\ArrayType; use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType as SchemaPrimitiveType; use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use ApiPlatform\SchemaGenerator\TypesGenerator; use EasyRdf\Graph as RdfGraph; @@ -60,26 +62,25 @@ protected function setUp(): void $idProperty = new Property('id'); $idProperty->rangeName = 'identifier'; $idProperty->range = new RdfResource('https://schema.org/identifier'); - $idProperty->type = 'string'; + $idProperty->type = new SchemaPrimitiveType('string'); $idProperty->isId = true; $vehicle->addProperty($idProperty); $enumProperty = new Property('enum'); $enumProperty->rangeName = 'Thing'; $enumProperty->range = new RdfResource('https://schema.org/Thing'); $enumProperty->isEnum = true; - $enumProperty->isArray = true; + $enumProperty->type = new ArrayType(); $enumProperty->reference = new SchemaClass('Thing', new RdfResource('htts://schema.org/Thing', $graph)); $vehicle->addProperty($enumProperty); $collectionProperty = new Property('collection'); $collectionProperty->rangeName = 'string'; $collectionProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#string'); - $collectionProperty->type = 'string'; - $collectionProperty->isArray = true; + $collectionProperty->type = new ArrayType(new SchemaPrimitiveType('string')); $vehicle->addProperty($collectionProperty); $weightProperty = new Property('weight'); $weightProperty->rangeName = 'nonPositiveInteger'; $weightProperty->range = new RdfResource('http://www.w3.org/2001/XMLSchema#nonPositiveInteger'); - $weightProperty->type = 'nonPositiveInteger'; + $weightProperty->type = new SchemaPrimitiveType('nonPositiveInteger'); $vehicle->addProperty($weightProperty); $prefixedWeightProperty = new Property('prefixedWeight'); $prefixedWeightProperty->isEmbedded = true; @@ -121,28 +122,28 @@ protected function setUp(): void $relation0NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation0NProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relation0NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_0_N; - $relation0NProperty->isArray = true; + $relation0NProperty->type = new ArrayType(); $vehicle->addProperty($relation0NProperty); $relation1NProperty = new Property('relation1_N'); $relation1NProperty->rangeName = 'QuantitativeValue'; $relation1NProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relation1NProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relation1NProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; - $relation1NProperty->isArray = true; + $relation1NProperty->type = new ArrayType(); $vehicle->addProperty($relation1NProperty); $relation1NSelfReferencingProperty = new Property('relation1_N_self_referencing'); $relation1NSelfReferencingProperty->rangeName = 'Vehicle'; $relation1NSelfReferencingProperty->range = new RdfResource('https://schema.org/Vehicle'); $relation1NSelfReferencingProperty->reference = new SchemaClass('Vehicle', new RdfResource('htts://schema.org/Vehicle', $graph)); $relation1NSelfReferencingProperty->cardinality = CardinalitiesExtractor::CARDINALITY_1_N; - $relation1NSelfReferencingProperty->isArray = true; + $relation1NSelfReferencingProperty->type = new ArrayType(); $vehicle->addProperty($relation1NSelfReferencingProperty); $relationNNProperty = new Property('relationN_N'); $relationNNProperty->rangeName = 'QuantitativeValue'; $relationNNProperty->range = new RdfResource('https://schema.org/QuantitativeValue'); $relationNNProperty->reference = new SchemaClass('QuantitativeValue', new RdfResource('htts://schema.org/QuantitativeValue', $graph)); $relationNNProperty->cardinality = CardinalitiesExtractor::CARDINALITY_N_N; - $relationNNProperty->isArray = true; + $relationNNProperty->type = new ArrayType(); $vehicle->addProperty($relationNNProperty); $this->classMap[$vehicle->name()] = $vehicle; diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index 6f78d3f6..bf4c2e26 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -19,6 +19,7 @@ use ApiPlatform\SchemaGenerator\PhpTypeConverter; use ApiPlatform\SchemaGenerator\Schema\Model\Class_ as SchemaClass; use ApiPlatform\SchemaGenerator\Schema\Model\Property; +use ApiPlatform\SchemaGenerator\Schema\Model\Type\PrimitiveType as SchemaPrimitiveType; use ApiPlatform\SchemaGenerator\Schema\PropertyGenerator\PropertyGenerator as SchemaPropertyGenerator; use ApiPlatform\SchemaGenerator\Schema\TypeConverter; use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; @@ -105,14 +106,14 @@ public function provideInvokeTestCases(): \Generator $expectedArticleBodyProperty->resource = new RdfResource('https://schema.org/articleBody', $graph); $expectedArticleBodyProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedArticleBodyProperty->rangeName = 'Text'; - $expectedArticleBodyProperty->type = 'string'; + $expectedArticleBodyProperty->type = new SchemaPrimitiveType('string'); $expectedArticleBodyProperty->isNullable = true; $expectedArticleSectionProperty = new Property('articleSection'); $expectedArticleSectionProperty->cardinality = CardinalitiesExtractor::CARDINALITY_UNKNOWN; $expectedArticleSectionProperty->resource = new RdfResource('https://schema.org/articleSection', $graph); $expectedArticleSectionProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedArticleSectionProperty->rangeName = 'Text'; - $expectedArticleSectionProperty->type = 'string'; + $expectedArticleSectionProperty->type = new SchemaPrimitiveType('string'); $expectedArticleSectionProperty->isNullable = true; yield 'no configuration' => [clone $article, (clone $article)->addProperty($expectedArticleBodyProperty)->addProperty($expectedArticleSectionProperty), $graph]; @@ -123,7 +124,7 @@ public function provideInvokeTestCases(): \Generator $expectedGivenNameProperty->resource = new RdfResource('https://schema.org/givenName', $graph); $expectedGivenNameProperty->range = new RdfResource('https://schema.org/Text', $graph); $expectedGivenNameProperty->rangeName = 'Text'; - $expectedGivenNameProperty->type = 'string'; + $expectedGivenNameProperty->type = new SchemaPrimitiveType('string'); $expectedGivenNameProperty->isNullable = true; $expectedGivenNameProperty->isRequired = true; yield 'with configuration' => [clone $person, (clone $person)->addProperty($expectedGivenNameProperty), $graph]; diff --git a/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Course.yaml b/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Course.yaml new file mode 100644 index 00000000..3c2532d4 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Course.yaml @@ -0,0 +1,45 @@ +type: object +required: + - consumerKey + - alliances +properties: + consumerKey: + type: string + alliances: + type: array + items: + type: object + required: + - name + properties: + name: + type: string + description: The name of the alliance + enum: + - ewuu + - lde + theme: + type: string + description: the theme of the Program or Course within the alliance + selection: + type: boolean + description: A boolean value (`true` or `false`) indicating whether this Program or Course is selective, e.g. whether student need to pass extra requirements before being allowed to enroll. + type: + type: string + description: A string indicating whether a Program or Course is broadening or deepening + enum: + - broadening + - deepening + visibleForOwnStudents: + type: boolean + description: a boolean value (`true` or `false`) indicating whether this Program or Course should be visible for students of the offering institution. The default values for this attribute is specified outside of this specification on the alliance level. + enrollmentForOwnStudents: + type: string + description: a string indicating which enrollments process should be followed for students of the offering institution. Allowed values are "broker"` or `"url"`. This attribute is only used if `visibleForOwnStudents` is set to `true`. If `"url"` is chosen the attribute `enrollmentUrl` is mandatory. + enum: + - broker + - url + enrollmentUrl: + type: string + description: a string formatted as an url to which students will be redirected if `enrollmentForOwnStudents is set to `"url"`. + format: url diff --git a/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Person.yaml b/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Person.yaml new file mode 100644 index 00000000..a1bc8980 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Person.yaml @@ -0,0 +1,47 @@ +type: object +required: + - consumerKey + - enrollments + - institutionBRINCode +properties: + consumerKey: + type: string + enrollments: + type: array + items: + type: object + required: + - crohoCreboCode + - name + properties: + crohoCreboCode: + type: string + description: The crohoCreboCode for this program. This should be a five character string, e.g. "34401". + name: + type: string + description: The name of the program this enrollment is for. + phase: + type: string + description: The phase of the program for this enrollment. + enum: + - bachelor + - master + modeOfStudy: + type: string + description: The modeOfStudy of the program for this enrollment + enum: + - full-time + - part-time + - dual training + - self-paced + startDate: + type: string + description: The start date for this enrollment. Should be a string formatted as an RFC3099 full-date. + format: date + endDate: + type: string + description: The end date for this enrollment. Should be a string formatted as an RFC3099 full-date. + format: date + institutionBRINCode: + type: string + pattern: ^\d{2}[A-Z]{2}$ diff --git a/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Program.yaml b/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Program.yaml new file mode 100644 index 00000000..3c2532d4 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/EDUXCHANGE/V1/Program.yaml @@ -0,0 +1,45 @@ +type: object +required: + - consumerKey + - alliances +properties: + consumerKey: + type: string + alliances: + type: array + items: + type: object + required: + - name + properties: + name: + type: string + description: The name of the alliance + enum: + - ewuu + - lde + theme: + type: string + description: the theme of the Program or Course within the alliance + selection: + type: boolean + description: A boolean value (`true` or `false`) indicating whether this Program or Course is selective, e.g. whether student need to pass extra requirements before being allowed to enroll. + type: + type: string + description: A string indicating whether a Program or Course is broadening or deepening + enum: + - broadening + - deepening + visibleForOwnStudents: + type: boolean + description: a boolean value (`true` or `false`) indicating whether this Program or Course should be visible for students of the offering institution. The default values for this attribute is specified outside of this specification on the alliance level. + enrollmentForOwnStudents: + type: string + description: a string indicating which enrollments process should be followed for students of the offering institution. Allowed values are "broker"` or `"url"`. This attribute is only used if `visibleForOwnStudents` is set to `true`. If `"url"` is chosen the attribute `enrollmentUrl` is mandatory. + enum: + - broker + - url + enrollmentUrl: + type: string + description: a string formatted as an url to which students will be redirected if `enrollmentForOwnStudents is set to `"url"`. + format: url diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/Course.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/Course.yaml new file mode 100644 index 00000000..edddaf9e --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/Course.yaml @@ -0,0 +1,42 @@ +type: object +description: RIO add-on attributes to a course that lead to a certifiable learning outcome +required: + - educationOffererCode +properties: + educationOffererCode: + type: string + description: | + onderwijsaanbiedercode + Een betekenisloze identifier voor een onderwijsaanbieder in de Registratie Instellingen en Opleidingen. + pattern: ^(?:\d{3}A\d{3})$ + educationLocationCode: + type: string + description: | + onderwijslocatiecode + Een betekenisloze identifier voor een onderwijslocatie in de Registratie Instellingen en Opleidingen. + pattern: ^(?:\d{3}X\d{3})$ + consentParticipationSTAP: + type: string + description: | + toestemmingDeelnameSTAP + Geeft aan of een AangebodenOpleiding beschikbaar is in het kader van de STAP-regeling en voorkomt in het Scholingsregister. + enum: + - permission_granted + - permission_not_granted + jointPartnerCodes: + type: array + items: + type: string + pattern: ^(?:\d{3}A\d{3})$ + minItems: 1 + description: | + samenwerkendeOnderwijsaanbiedercode + Code van de onderwijsaanbieder waarmee wordt samengewerkt OnderwijsaanbiederID-v01 + foreignPartners: + type: array + items: string + minItems: 1 + description: | + buitenlandsePartner + Beschrijving van de organisatie waarmee door een Nederlandse onderwijsbestuur wordt samengewerkt + bij het verzorgen van een Joint Degree. diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/EducationSpecification.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/EducationSpecification.yaml new file mode 100644 index 00000000..bf9b14ba --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/EducationSpecification.yaml @@ -0,0 +1,42 @@ +type: object +description: RIO add-on attributes to an education specification +required: +properties: + educationSpecificationSubType: + type: string + description: | + The subtype of the EducationSpecification. At the moment only used for EducationSpecification's of the type `program`: + Allowed subtypes when type = `program`: + - variant: if the subtype attribute is set to `variant`, the program maps to a HoOpleiding of 'soort' `VARIANT` + - *...*: if the `educationSpecificationSubType`` attribute is absent, the program maps to a HoOpleiding of 'soort' `OPLEIDING` + enum: + - variant + example: program + category: + type: array + description: | + A classification for programs in non-formal education. Used when describing EducationSpecification's that will map to a `articuliereOpleiding in RIO + minItems: 0 + maxItems: 3 + items: + type: string + enum: + - business_and_project_support + - economy + - behavior_and_society + - healthcare_and_sport + - hobby_and_leisure_time + - agriculture_food_and_natural_environment + - management_and_project_management + - nature + - education + - law + - cross_sectoral + - language_and_culture + - technology_and_ict + - tourism_hospitality_and_recreation + - transport_and_logistics + - security_and_defense + example: + - business_and_project_support + - economy diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/Offering.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/Offering.yaml new file mode 100644 index 00000000..e00e41d3 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/Offering.yaml @@ -0,0 +1,29 @@ +type: object +description: RIO add-on attributes to the offerings of either a collection of courses or courses that lead to a certifiable learning outcome +required: + - registrationStatus + - requiredPermissionRegistration +properties: + explanationRequiredPermission: + type: string + description: | + toelichtingVereisteToestemming + Is een tekstuele toelichting op de voor aanmelding vereiste toestemming van de onderwijsaanbieder + requiredPermissionRegistration: + type: string + description: | + toestemmingVereistVoorAanmelding + Geeft aan of een aspirant-student voor een bepaald cohort van een aangeboden opleiding toestemming van de onderwijsaanbieder nodig heeft om zich aan te mogen melden. + - yes: JA + - no: NEE + enum: + - yes + - no + registrationStatus: + type: string + description: | + cohortStatus + De toegestane waarden voor de status van een cohort van een aangeboden opleiding. Hiermee kan bijvoorbeeld worden aangegeven of een bepaald cohort open staat voor aanmelding, of dat het gesloten is. + enum: + - open + - closed diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/Program.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/Program.yaml new file mode 100644 index 00000000..6bccce51 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/Program.yaml @@ -0,0 +1,95 @@ +type: object +description: RIO add-on attributes to a collection of courses that lead to a certifiable learning outcome +required: + - educationOffererCode +properties: + educationOffererCode: + type: string + description: | + onderwijsaanbiedercode + Een betekenisloze identifier voor een onderwijsaanbieder in de Registratie Instellingen en Opleidingen. + pattern: ^(?:\d{3}A\d{3})$ + educationLocationCode: + type: string + description: | + onderwijslocatiecode + Een betekenisloze identifier voor een onderwijslocatie in de Registratie Instellingen en Opleidingen. + pattern: ^(?:\d{3}X\d{3})$ + consentParticipationSTAP: + type: string + description: | + toestemmingDeelnameSTAP + Geeft aan of een AangebodenOpleiding beschikbaar is in het kader van de STAP-regeling en voorkomt in het Scholingsregister. + enum: + - permission_granted + - permission_not_granted + jointPartnerCodes: + type: array + items: + type: string + pattern: ^(?:\d{3}A\d{3})$ + minItems: 1 + description: | + samenwerkendeOnderwijsaanbiedercode + Code van de onderwijsaanbieder waarmee wordt samengewerkt OnderwijsaanbiederID-v01 + foreignPartners: + type: array + items: string + minItems: 1 + description: | + buitenlandsePartner + Beschrijving van de organisatie waarmee door een Nederlandse onderwijsbestuur wordt samengewerkt + bij het verzorgen van een Joint Degree. + deficiency: + type: string + description: | + deficientie Geeft aan of inschrijving met onvoldoende vooropleiding mogelijk is + - deficiencies: DEFICIENTIES Inschrijving mogelijk met onvoldoende vooropleiding + - no_dediciencies: GEEN_DEFICIENTIES Inschrijving alleen mogelijk met voldoende vooropleiding + enum: + - deficiencies + - no_deficiencies + requirementsActivities: + type: string + description: | + eisenWerkzaamheden + Geeft aan of er eisen zijn gesteld aan het type werkzaamheden die verricht worden in het kader van de opleiding. + - requirements: EISEN Er zijn eisen gesteld aan de werkzaamheden in het kader van de opleiding + - no_requirements: GEEN_EISEN Er zijn geen eisen gesteld aan de werkzaamheden in het kader van de opleiding + enum: + - requirements + - no_requirements + propaedeuticPhase: + type: string + description: | + propadeutischeFase + Geeft aan of de aangeboden opleiding een propedeutische fase kent en of deze wordt afgesloten met een propedeutisch examen. + - no_propaedeutic_phase: GEEN_PROPEDEUTISCHE_FASE Geen propedeutische fase + - propaedeutic_phase_exam: PROPEDEUTISCHE_FASE_EXAMEN Propedeutische fase met examen + - propaedeutic_phase_no_exam: PROPEDEUTISCHE_FASE_ZONDER_EXAMEN Propedeutische fase zonder examen + enum: + - no_propaedeutic_phase + - propaedeutic_phase_exam + - propaedeutic_phase_no_exam + studyChoiceCheck: + type: string + description: | + studiekeuzecheck + Specificeert of er en zo ja hoe een controle op geschiktheid van een aankomend student voor deelname aan gekozen studie plaatsvindt. + - no_study_choice_check: GEEN_STUDIEKEUZE_CHECK Geen studiekeuzecheck + - study_choice_check_available: STUDIEKEUZE_CHECK_VAN_TOEPASSING Studiekeuzecheck van toepassing + - study_choice_check_mandatory: STUDIEKEUZE_CHECK_VERPLICHT Studiekeuzecheck verplicht + enum: + - no_study_choice_check + - study_choice_check_available + - study_choice_check_mandatory + acceleratedRoute: + type: string + description: | + versneldTraject + Geeft aan of een student een versneld programma volgt zodat het opleiding in minder tijd dan normaal doorlopen kan worden. + - accelerated_route: VERSNELD_TRAJECT Versneld traject + - no_accelerated_route: GEEN_VERSNELD_TRAJECT Geen versneld traject + enum: + - accelerated_route + - no_accelerated_route diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Course.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Course.yaml new file mode 100644 index 00000000..383a84a8 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Course.yaml @@ -0,0 +1,6 @@ +- consumerKey: rio + educationOffererCode: 123A321 + educationLocationCode: 334X123 + consentParticipationSTAP: permission_granted + jointPartnerCodes: [123A123] + foreignPartners: ["Harvard University"] diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/EducationSpecification.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/EducationSpecification.yaml new file mode 100644 index 00000000..bc158a40 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/EducationSpecification.yaml @@ -0,0 +1,3 @@ +- consumerKey: rio + educationSpecificationSubType: variant + category: ['business_and_project_support', 'economy'] diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Offering.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Offering.yaml new file mode 100644 index 00000000..92a02eb3 --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Offering.yaml @@ -0,0 +1,4 @@ +- consumerKey: rio + explanationRequiredPermission: Toestemming is vereist omdat we daarom vragen. + requiredPermissionRegistration: yes + registrationStatus: open diff --git a/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Program.yaml b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Program.yaml new file mode 100644 index 00000000..8c7a9ddf --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/RIO/V1/examples/Program.yaml @@ -0,0 +1,11 @@ +- consumerKey: rio + educationOffererCode: 122A112 + educationLocationCode: 123X122 + consentParticipationSTAP: permission_granted + jointPartnerCodes: [122A113] + foreignPartners: ["Harvard University"] + deficiency: deficiencies + requirementsActivities: requirements + propaedeuticPhase: no_propaedeutic_phase + studyChoiceCheck: no_study_choice_check + acceleratedRoute: accelerated_route diff --git a/tests/e2e/open-education-api-v5/consumers/TEST/V1/TestConsumer.yaml b/tests/e2e/open-education-api-v5/consumers/TEST/V1/TestConsumer.yaml new file mode 100644 index 00000000..c5564bfb --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/TEST/V1/TestConsumer.yaml @@ -0,0 +1,7 @@ +type: object +description: extra elements +properties: + additional: + type: string + attributes: + type: string diff --git a/tests/e2e/open-education-api-v5/consumers/TEST/V1/examples/TestConsumer.yaml b/tests/e2e/open-education-api-v5/consumers/TEST/V1/examples/TestConsumer.yaml new file mode 100644 index 00000000..ec410aaf --- /dev/null +++ b/tests/e2e/open-education-api-v5/consumers/TEST/V1/examples/TestConsumer.yaml @@ -0,0 +1,3 @@ +- consumerKey: x-test-consumer + additional: custom + attributes: here diff --git a/tests/e2e/open-education-api-v5/enumerations/ICERelationType.yaml b/tests/e2e/open-education-api-v5/enumerations/ICERelationType.yaml new file mode 100644 index 00000000..440b0682 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/ICERelationType.yaml @@ -0,0 +1,7 @@ +type: string +description: Type of relation between person and In Case of Emergency contact +enum: + - partner + - parent + - other +example: partner diff --git a/tests/e2e/open-education-api-v5/enumerations/academicSessionType.yaml b/tests/e2e/open-education-api-v5/enumerations/academicSessionType.yaml new file mode 100644 index 00000000..3a64b977 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/academicSessionType.yaml @@ -0,0 +1,19 @@ +type: string +description: | + The type of this Academic Session This is an *extensible enumeration*. + - academic year: academic year + - semester: semester, typically there are two semesters per academic year + - trimester: trimester, typically there are three semesters per academic year + - quarter: quarter, typically there are four quarters per academic year + - testing period: a period in which tests take place + - period: any other period in an academic year + + Implementations are allowed to add additional values to those above, as long as they do not overlap in definition to existing values. +example: semester +x-ooapi-extensible-enum: + - academic year + - semester + - trimester + - quarter + - testing period + - period diff --git a/tests/e2e/open-education-api-v5/enumerations/addressType.yaml b/tests/e2e/open-education-api-v5/enumerations/addressType.yaml new file mode 100644 index 00000000..4ed1445c --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/addressType.yaml @@ -0,0 +1,14 @@ +type: string +description: | + Address type + - postal: post + - visit: bezoek + - deliveries: bezorg + - billing: factuur + - teaching: the address where education takes place +enum: + - postal + - visit + - deliveries + - billing + - teaching diff --git a/tests/e2e/open-education-api-v5/enumerations/associationRole.yaml b/tests/e2e/open-education-api-v5/enumerations/associationRole.yaml new file mode 100644 index 00000000..6b2c4c9b --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/associationRole.yaml @@ -0,0 +1,15 @@ +type: string +description: | + The role of this person associated with the offering + - student: student + - lecturer: docent + - teaching assistant: studentassistent + - coordinator: coördinator + - guest: gast +enum: + - student + - lecturer + - teaching assistant + - coordinator + - guest +example: student diff --git a/tests/e2e/open-education-api-v5/enumerations/associationState.yaml b/tests/e2e/open-education-api-v5/enumerations/associationState.yaml new file mode 100644 index 00000000..33fb7c6b --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/associationState.yaml @@ -0,0 +1,9 @@ +type: string +description: The state of this association +enum: + - pending + - canceled + - denied + - associated + - queued +example: associated diff --git a/tests/e2e/open-education-api-v5/enumerations/codeType.yaml b/tests/e2e/open-education-api-v5/enumerations/codeType.yaml new file mode 100644 index 00000000..7bfa853b --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/codeType.yaml @@ -0,0 +1,59 @@ +type: string +description: | + The code/identifier type. + + This is an *extensible enumeration*. Use `x-` to prefix custom values + + The predefined values are: + - `brin`: The registration number for a Dutch educational institution that is issued by the Dutch Ministry of Education, Culture and Science + - `crohoCreboCode`: programs with a CREBO and CROHO number are accredited by the Dutch Ministry of Education, Culture and Science (OCW) + - `programCode`: Identifier for the program (collection of courses) + - `componentCode`: The code for a component (part of a course) + - `offeringCode`: The code to identify a specific offering (program, course or component offering) + - `organizationId`: The identifier for the organization + - `buildingId`: The number or code to identify a building + - `bagId`: The identification of a building as it is known in the Dutch Building Administration (BAG) + - `roomCode`: The code for a room + - `systemId`: Identifier assigned to an entity in context of a specific system + - `productId`: Identifier assigned to a specific product + - `nationalIdentityNumber`: Identifier assigned by the governement of the person. e.g. a social security number in the USA + - `studentNumber`: Identifier for the student + - `studielinkNumber`: Identifier for the person as determined by Studielink + - `esi`: European Student Identifier + - `userName`: The name of a user + - `accountId`: Identifier assigned to a specific account + - `emailAdress`: An email address + - `groupCode`: The identifier for a group (of persons) + - `isbn`: International Standard Book Number that serve as product identifiers for Books + - `issn`: International Standard Book Number that serve as product identifiers for periodicals + - `orcId`: Open Researcher and Contributor ID + - `uuid`: A universally unique identifier + - `schacHome`: Home organization using the domain name of the organization + - `identifier`: Generic Identifier +x-ooapi-extensible-enum: + - brin + - crohoCreboCode + - programCode + - componentCode + - offeringCode + - organizationId + - buildingId + - bagId + - roomCode + - systemId + - productId + - nationalIdentityNumber + - studentNumber + - studielinkNumber + - esi + - userName + - accountId + - emailAdress + - groupCode + - isbn + - issn + - orcId + - uuid + - schacHome + - identifier +example: identifier diff --git a/tests/e2e/open-education-api-v5/enumerations/componentType.yaml b/tests/e2e/open-education-api-v5/enumerations/componentType.yaml new file mode 100644 index 00000000..b4c1517a --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/componentType.yaml @@ -0,0 +1,27 @@ +type: string +description: | + The component type + - test: tentamen + - lecture: college + - practical: practicum + - tutorial: werkcollege + - consultation: consultatie + - project: project + - workshop: workshop + - excursion: excursie + - independent study: zelfstudie + - external: extern + - skills training: vaardighedentraining +enum: + - test + - lecture + - practical + - tutorial + - consultation + - project + - workshop + - excursion + - independent study + - external + - skills training +example: test diff --git a/tests/e2e/open-education-api-v5/enumerations/costType.yaml b/tests/e2e/open-education-api-v5/enumerations/costType.yaml new file mode 100644 index 00000000..c9620568 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/costType.yaml @@ -0,0 +1,13 @@ +type: string +description: | + The type of the cost. This is an *extensible enumeration*. + + The following values have been defined in the specification: + - `STAP eligible`: the costs that a student can get STAP subsidy for + - `total costs`: the total costs that a student is to pay to follow this offering + + Implementations are allowed to add additional values to those above, as long as they do not overlap in definition to existing values. +example: total costs +x-ooapi-extensible-enum: + - STAP eligible + - total costs diff --git a/tests/e2e/open-education-api-v5/enumerations/educationSpecificationType.yaml b/tests/e2e/open-education-api-v5/enumerations/educationSpecificationType.yaml new file mode 100644 index 00000000..94fee9c9 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/educationSpecificationType.yaml @@ -0,0 +1,13 @@ +type: string +description: | + The type of education specification + - program: HOOPLEIDING + - privateProgram: PARTICULIEREOPLEIDING + - programCluster: HOONDERWIJSEENHEDENCLUSTER + - course: HOONDERWIJSEENHEID +enum: + - program + - privateProgram + - cluster + - course +example: program diff --git a/tests/e2e/open-education-api-v5/enumerations/formalDocument.yaml b/tests/e2e/open-education-api-v5/enumerations/formalDocument.yaml new file mode 100644 index 00000000..34f8c086 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/formalDocument.yaml @@ -0,0 +1,15 @@ +type: string +description: | + The type of formal document obtained after completion of this education + - diploma: DIPLOMA + - certificate: CERTIFICAAT + - no official document: GEEN OFFICIEEL DOCUMENT + - testimonial: GETUIGSCHRIFT + - school advice: SCHOOLADVIES +enum: + - diploma + - certificate + - no official document + - testimonial + - school advice +example: diploma diff --git a/tests/e2e/open-education-api-v5/enumerations/gender.yaml b/tests/e2e/open-education-api-v5/enumerations/gender.yaml new file mode 100644 index 00000000..68049b98 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/gender.yaml @@ -0,0 +1,8 @@ +type: string +description: The gender of this person +enum: + - M + - F + - U + - X +example: F diff --git a/tests/e2e/open-education-api-v5/enumerations/groupType.yaml b/tests/e2e/open-education-api-v5/enumerations/groupType.yaml new file mode 100644 index 00000000..8d151ff8 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/groupType.yaml @@ -0,0 +1,11 @@ +type: string +description: | + The type of this group + - learning group: A collection of participants carrying out common learning activities + - class: A collection of participants carrying out jointly scheduled educational activities + - team: A collection of members of a team, either students, employees or mixed. +enum: + - learning group + - class + - team +example: learning group diff --git a/tests/e2e/open-education-api-v5/enumerations/level.yaml b/tests/e2e/open-education-api-v5/enumerations/level.yaml new file mode 100644 index 00000000..bf7a5e75 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/level.yaml @@ -0,0 +1,31 @@ +type: string +description: | + The level of this course (ECTS-year of study if applicable) + - secondary vocational education: mbo + - secondary vocational education 1: mbo 1, corresponds to levelOfQualification 1 + - secondary vocational education 2: mbo 2, corresponds to levelOfQualification 2 + - secondary vocational education 3: mbo 3, corresponds to levelOfQualification 3 + - secondary vocational education 4: mbo 4, corresponds to levelOfQualification 4 + - associate degree: associate degree, corresponds to levelOfQualification 5 + - bachelor: bachelor, corresponds to levelOfQualification 6 + - master: master, corresponds to levelOfQualification 7 + - doctoral: doctoraal, corresponds to levelOfQualification 8 + - undefined: onbepaald + - undivided: ongedeeld + - nt2-1: NT2 niveau 1 + - nt2-2: NT2 niveau 2 +enum: + - secondary vocational education + - secondary vocational education 1 + - secondary vocational education 2 + - secondary vocational education 3 + - secondary vocational education 4 + - associate degree + - bachelor + - master + - doctoral + - undefined + - undivided + - nt2-1 + - nt2-2 +example: master diff --git a/tests/e2e/open-education-api-v5/enumerations/levelOfQualification.yaml b/tests/e2e/open-education-api-v5/enumerations/levelOfQualification.yaml new file mode 100644 index 00000000..c3f4f407 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/levelOfQualification.yaml @@ -0,0 +1,13 @@ +type: string +description: Level of qualification according to the Dutch National Qualification Framework and the European Qualifications Framework, see [this overview](https://nlqf.nl/images/downloads/English2018/Schematic_overview_NLQF_2020.pdf) for more information. +enum: + - '1' + - '2' + - '3' + - '4' + - '4+' + - '5' + - '6' + - '7' + - '8' +example: '6' diff --git a/tests/e2e/open-education-api-v5/enumerations/modeOfStudy.yaml b/tests/e2e/open-education-api-v5/enumerations/modeOfStudy.yaml new file mode 100644 index 00000000..d844a045 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/modeOfStudy.yaml @@ -0,0 +1,12 @@ +type: string +description: | + Indicates whether the education is full-time, part-time, dual or self-paced. + - full-time: fulltime + - part-time: parttime + - dual training: duaal + - self-paced: eigen tempo +enum: + - full-time + - part-time + - dual training + - self-paced \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/enumerations/modesOfDelivery.yaml b/tests/e2e/open-education-api-v5/enumerations/modesOfDelivery.yaml new file mode 100644 index 00000000..76cb9dea --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/modesOfDelivery.yaml @@ -0,0 +1,17 @@ +type: array +description: | + The mode of delivery of the component (ECTS-mode of delivery) + - distance-learning: afstandsleren + - on campus: op de campus + - online: online + - hybrid: hybride + - situated: op locatie +items: + type: string + enum: + - distance-learning + - on campus + - online + - hybrid + - situated + example: situated diff --git a/tests/e2e/open-education-api-v5/enumerations/newsItemType.yaml b/tests/e2e/open-education-api-v5/enumerations/newsItemType.yaml new file mode 100644 index 00000000..0107a467 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/newsItemType.yaml @@ -0,0 +1,12 @@ +type: string +description: | + The type of this news item + - calamity: calamiteit + - general: algemeen + - schedule-change: roosterwijziging + - announcement: aankondiging +enum: + - calamity + - general + - schedule-change + - announcement diff --git a/tests/e2e/open-education-api-v5/enumerations/offeringType.yaml b/tests/e2e/open-education-api-v5/enumerations/offeringType.yaml new file mode 100644 index 00000000..aa8fb100 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/offeringType.yaml @@ -0,0 +1,7 @@ +type: string +description: The type of offering based on the object that is offered +enum: + - program + - course + - component +example: course diff --git a/tests/e2e/open-education-api-v5/enumerations/organizationType.yaml b/tests/e2e/open-education-api-v5/enumerations/organizationType.yaml new file mode 100644 index 00000000..a6231ff1 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/organizationType.yaml @@ -0,0 +1,19 @@ +type: string +description: | + The type of this organization. Each OOAPI endpoint should have a single organization with type `root`, describing the root organization. + - root: the root of this organization, representing the Educational Institution itself + - institute: instituut + - department: departement + - faculty: faculteit + - branch: vestiging + - academy: academie + - school: school +enum: + - root + - institute + - department + - faculty + - branch + - academy + - school +example: root diff --git a/tests/e2e/open-education-api-v5/enumerations/passState.yaml b/tests/e2e/open-education-api-v5/enumerations/passState.yaml new file mode 100644 index 00000000..eb041389 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/passState.yaml @@ -0,0 +1,7 @@ +type: string +description: The state of this result +enum: + - unknown + - passed + - failed +example: passed diff --git a/tests/e2e/open-education-api-v5/enumerations/personAffiliations.yaml b/tests/e2e/open-education-api-v5/enumerations/personAffiliations.yaml new file mode 100644 index 00000000..82a4563b --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/personAffiliations.yaml @@ -0,0 +1,13 @@ +type: array +description: | + The affiliations of this person, the relations a person has with the organization providing this endpoint + - student: student + - employee: medewerker + - guest: gast +items: + type: string + enum: + - student + - employee + - guest + example: student diff --git a/tests/e2e/open-education-api-v5/enumerations/programType.yaml b/tests/e2e/open-education-api-v5/enumerations/programType.yaml new file mode 100644 index 00000000..5e2ea5a3 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/programType.yaml @@ -0,0 +1,15 @@ +type: string +description: | + The type of this program + - program: opleiding + - minor: minor + - honours: honours + - specialization: specialisatie + - track: track +enum: + - program + - minor + - honours + - specialization + - track +example: program diff --git a/tests/e2e/open-education-api-v5/enumerations/qualificationAwarded.yaml b/tests/e2e/open-education-api-v5/enumerations/qualificationAwarded.yaml new file mode 100644 index 00000000..f0ada2ef --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/qualificationAwarded.yaml @@ -0,0 +1,13 @@ +type: string +description: Type of qualificaton that can be obtained on finishing the program +enum: + - AD + - BA + - BSc + - LLB + - MA + - MSc + - LLM + - Phd + - None +example: None diff --git a/tests/e2e/open-education-api-v5/enumerations/remoteAssociationState.yaml b/tests/e2e/open-education-api-v5/enumerations/remoteAssociationState.yaml new file mode 100644 index 00000000..c7b21ee5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/remoteAssociationState.yaml @@ -0,0 +1,9 @@ +type: string +description: The state of this association for the institution performing the request. +enum: + - pending + - canceled + - denied + - associated + - queued +example: associated diff --git a/tests/e2e/open-education-api-v5/enumerations/resultState.yaml b/tests/e2e/open-education-api-v5/enumerations/resultState.yaml new file mode 100644 index 00000000..9763a414 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/resultState.yaml @@ -0,0 +1,8 @@ +type: string +description: The state of this result +enum: + - in progress + - postponed + - completed + - queued +example: completed diff --git a/tests/e2e/open-education-api-v5/enumerations/resultValueType.yaml b/tests/e2e/open-education-api-v5/enumerations/resultValueType.yaml new file mode 100644 index 00000000..04948836 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/resultValueType.yaml @@ -0,0 +1,9 @@ +type: string +description: The result value type for this offering +enum: + - 'pass-or-fail' + - 'US letter' + - 'UK letter' + - '0-100' + - '1-10' +example: '1-10' diff --git a/tests/e2e/open-education-api-v5/enumerations/roomType.yaml b/tests/e2e/open-education-api-v5/enumerations/roomType.yaml new file mode 100644 index 00000000..527870c0 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/roomType.yaml @@ -0,0 +1,25 @@ +type: string +description: | + The type of this room + - general purpose: algemeen + - lecture room: collegezaal + - computer room: computerruimte + - laboratory: laboratorium + - office: kantoor + - workspace: werkruimte + - exam location: tentamenruimte + - study room: studieruimte + - examination room: onderzoekskamer + - conference room: vergaderkamer +enum: + - general purpose + - lecture room + - computer room + - laboratory + - office + - workspace + - exam location + - study room + - examination room + - conference room +example: exam location diff --git a/tests/e2e/open-education-api-v5/enumerations/sector.yaml b/tests/e2e/open-education-api-v5/enumerations/sector.yaml new file mode 100644 index 00000000..f6dadf89 --- /dev/null +++ b/tests/e2e/open-education-api-v5/enumerations/sector.yaml @@ -0,0 +1,11 @@ +type: string +description: | + The sector for this program + - secondary vocational education: middelbaar beroepsonderwijs + - higher professional education: hoger beroepsonderwijs + - university education: universitair onderwijs +enum: + - secondary vocational education + - higher professional education + - university education +example: university education diff --git a/tests/e2e/open-education-api-v5/parameters/consumer.yaml b/tests/e2e/open-education-api-v5/parameters/consumer.yaml new file mode 100644 index 00000000..31dc9556 --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/consumer.yaml @@ -0,0 +1,6 @@ +name: consumer +in: query +description: Request entities meant for a specific consumer. This query parameter is independent from the `consumers` attribute. See the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. +required: false +schema: + type: string diff --git a/tests/e2e/open-education-api-v5/parameters/pageNumber.yaml b/tests/e2e/open-education-api-v5/parameters/pageNumber.yaml new file mode 100644 index 00000000..35cfdf27 --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/pageNumber.yaml @@ -0,0 +1,9 @@ +name: pageNumber +in: query +description: The page number to get. Page numbers start at 1. +required: false +schema: + type: integer + format: int32 + example: 1 + minimum: 1 diff --git a/tests/e2e/open-education-api-v5/parameters/pageSize.yaml b/tests/e2e/open-education-api-v5/parameters/pageSize.yaml new file mode 100644 index 00000000..4677acc2 --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/pageSize.yaml @@ -0,0 +1,14 @@ +name: pageSize +in: query +description: The number of items per page +required: false +schema: + type: integer + format: int32 + default: 10 + enum: + - 10 + - 20 + - 50 + - 100 + - 250 diff --git a/tests/e2e/open-education-api-v5/parameters/personSearch.yaml b/tests/e2e/open-education-api-v5/parameters/personSearch.yaml new file mode 100644 index 00000000..20b31a40 --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/personSearch.yaml @@ -0,0 +1,6 @@ +name: q +in: query +description: Filter by persons having a givenName, surNamePrefix, surname, displayName, initials, mail or secondaryMail containing the given search term (exact partial match, case insensitive) +required: false +schema: + type: string diff --git a/tests/e2e/open-education-api-v5/parameters/primaryCode.yaml b/tests/e2e/open-education-api-v5/parameters/primaryCode.yaml new file mode 100644 index 00000000..be3a625b --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/primaryCode.yaml @@ -0,0 +1,6 @@ +name: primaryCode +in: query +description: The primaryCode of the requested item. This is often the source identifier as defined by the institution. +required: false +schema: + type: string diff --git a/tests/e2e/open-education-api-v5/parameters/returnTimelineOverrides.yaml b/tests/e2e/open-education-api-v5/parameters/returnTimelineOverrides.yaml new file mode 100644 index 00000000..6aa3da87 --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/returnTimelineOverrides.yaml @@ -0,0 +1,7 @@ +name: returnTimelineOverrides +in: query +description: Controls whether the attribute `timelineOverrides` is returned or not. The default is `false`, so this has to explicitly set to `true` if a client needs the timeline overrides. See [GET /education-specifications/{educationSpecificationId}](#tag/education-specifications/paths/~1education-specifications~1{educationSpecificationId}/get) for an example. +required: false +schema: + type: boolean + default: false diff --git a/tests/e2e/open-education-api-v5/parameters/search.yaml b/tests/e2e/open-education-api-v5/parameters/search.yaml new file mode 100644 index 00000000..d03b610f --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/search.yaml @@ -0,0 +1,6 @@ +name: q +in: query +description: Filter by items having a name, abbreviation or description containing the given search term (exact partial match, case insensitive) +required: false +schema: + type: string diff --git a/tests/e2e/open-education-api-v5/parameters/teachingLanguage.yaml b/tests/e2e/open-education-api-v5/parameters/teachingLanguage.yaml new file mode 100644 index 00000000..dafe1868 --- /dev/null +++ b/tests/e2e/open-education-api-v5/parameters/teachingLanguage.yaml @@ -0,0 +1,10 @@ +name: teachingLanguage +in: query +description: Filter by teachingLanguage, which is a string describing the main teaching language, should be a three-letter language code as specified by ISO 639-2. +required: false +schema: + type: string + pattern: "^[a-z]{3}$" + minLength: 3 + maxLength: 3 +example: nld diff --git a/tests/e2e/open-education-api-v5/paths/AcademicSessionCollection.yaml b/tests/e2e/open-education-api-v5/paths/AcademicSessionCollection.yaml new file mode 100644 index 00000000..1976f0d5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/AcademicSessionCollection.yaml @@ -0,0 +1,80 @@ +get: + summary: GET /academic-sessions + description: Get a list of all academic sessions, ordered chronologically. + tags: + - academic sessions + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - name: academicSessionType + in: query + description: Filter by academic session type + required: false + schema: + $ref: '../enumerations/academicSessionType.yaml' + - name: parent + in: query + description: Filter by parent (academicSessionId) + required: false + schema: + type: string + format: uuid + - name: year + in: query + description: Filter by year (academicSessionId) + required: false + schema: + type: string + format: uuid + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - academicSessionId + - name + - startDate + - -academicSessionId + - -name + - -startDate + default: [ startDate ] + example: + - startDate + - -academicSessionId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/AcademicSession.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/AcademicSessionInstance.yaml b/tests/e2e/open-education-api-v5/paths/AcademicSessionInstance.yaml new file mode 100644 index 00000000..5110a581 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/AcademicSessionInstance.yaml @@ -0,0 +1,47 @@ +get: + summary: GET /academic-sessions/{academicSessionId} + description: Get a single academic session. + tags: + - academic sessions + parameters: + - name: academicSessionId + in: path + description: Academic session ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - parent + - children + - year + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/AcademicSession.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/AcademicSessionOfferingCollection.yaml b/tests/e2e/open-education-api-v5/paths/AcademicSessionOfferingCollection.yaml new file mode 100644 index 00000000..9d86a656 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/AcademicSessionOfferingCollection.yaml @@ -0,0 +1,105 @@ +get: + summary: GET /academic-sessions/{academicSessionId}/offerings + description: Get a list of all offerings during this academic session + tags: + - academic sessions + parameters: + - name: academicSessionId + in: path + description: Academic session ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: offeringType + in: query + description: Filter by offering type + required: false + schema: + type: string + enum: + - program + - course + - component + - name: resultExpected + in: query + description: Filter by resultExpected + required: false + schema: + type: boolean + - name: since + in: query + description: Filter all offerings by providing a minimum start date for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=`). + required: false + schema: + type: string + format: date + - name: until + in: query + description: Filter all offerings by providing a maximum end date for the corresponding academic session, RFC3339 (full-date). + required: false + schema: + type: string + format: date + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - offeringId + - name + - startDate + - endDate + - -offeringId + - -name + - -startDate + - -endDate + default: [ startDate ] + example: + - startDate + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + oneOf: + - $ref: '../schemas/ProgramOffering.yaml' + - $ref: '../schemas/CourseOffering.yaml' + - $ref: '../schemas/ComponentOffering.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/AssociationInstance.yaml b/tests/e2e/open-education-api-v5/paths/AssociationInstance.yaml new file mode 100644 index 00000000..151799be --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/AssociationInstance.yaml @@ -0,0 +1,102 @@ +get: + summary: GET /associations/{associationId} + description: Get a single association. + tags: + - associations + parameters: + - name: associationId + in: path + description: Association ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - person + - offering + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/AssociationFull.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' + + + + +patch: + summary: PATCH /associations/{associationId} + description: | + Update the status or result of an enrollment. Other elements of the association object COULD + also be PATCHED. But are not likely and have therefor not been included in this endpoint. + Implementation of the PATCH activity is based on use PATCH with JSON Merge Patch standard, + a specialized media type `application/merge-patch+json` for partial resource representation + to update parts of resource objects. + security: + - openId: + - associations.write + tags: + - associations + + parameters: + - name: associationId + in: path + description: The id of the association to update + required: true + schema: + type: string + format: uuid + + requestBody: + required: true + content: + application/merge-patch+json: + schema: + properties: + remoteState: + $ref: '../enumerations/remoteAssociationState.yaml' + result: + oneOf: + - $ref: '../schemas/ComponentResult.yaml' + - $ref: '../schemas/CourseResult.yaml' + - $ref: '../schemas/ProgramResult.yaml' + + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/AssociationId.yaml' + - $ref: '../schemas/PostResponse.yaml' + - properties: + state: + $ref: '../enumerations/associationState.yaml' + + '400': + $ref: '../schemas/ErrorBadRequest.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/AssociationInstanceExternalMe.yaml b/tests/e2e/open-education-api-v5/paths/AssociationInstanceExternalMe.yaml new file mode 100644 index 00000000..b38640bd --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/AssociationInstanceExternalMe.yaml @@ -0,0 +1,41 @@ +post: + summary: POST /associations/external/me + description: | + POST a single association enroll a person based on person information obtained from .wellknown endpoint, an offering, + and the organization/type=root information form the organization that is issuing this association. + The offering can either be identified by an offeringId if known or the full offering details. + security: + - openId: + - associations:external:me.write + tags: + - associations + + requestBody: + required: true + content: + application/json: + schema: + required: + - remoteState + allOf: + - $ref: '../schemas/AssociationWrite.yaml' + - properties: + issuer: + $ref: '../schemas/Organization.yaml' + + responses: + '201': + description: CREATED + content: + application/json: + schema: + allOf: + - $ref: '../schemas/AssociationId.yaml' + - $ref: '../schemas/PostResponse.yaml' + - properties: + state: + $ref: '../enumerations/associationState.yaml' + + + '400': + $ref: '../schemas/ErrorBadRequest.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/AssociationInstanceMe.yaml b/tests/e2e/open-education-api-v5/paths/AssociationInstanceMe.yaml new file mode 100644 index 00000000..15f694c9 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/AssociationInstanceMe.yaml @@ -0,0 +1,33 @@ +post: + summary: POST /associations/me + description: POST a single association to enroll a person based on person information obtained from .wellknown endpoint and an offering. The offering can either be identified by an offeringId if known or the full offering details. + security: + - openId: + - associations:me.write + tags: + - associations + + requestBody: + required: true + content: + application/json: + schema: + $ref: '../schemas/AssociationFull.yaml' + + + responses: + '201': + description: CREATED + content: + application/json: + schema: + allOf: + - $ref: '../schemas/AssociationId.yaml' + - $ref: '../schemas/PostResponse.yaml' + + '400': + description: Bad Request + content: + application/problem+json: + schema: + $ref: '../schemas/Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/paths/BuildingCollection.yaml b/tests/e2e/open-education-api-v5/paths/BuildingCollection.yaml new file mode 100644 index 00000000..f4c93670 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/BuildingCollection.yaml @@ -0,0 +1,59 @@ +get: + summary: GET /buildings + description: Get a list of all buildings, ordered by name (ascending). + tags: + - buildings + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - buildingId + - name + - -buildingId + - -name + default: [ name ] + example: + - name + - -buildingId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Building.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/BuildingInstance.yaml b/tests/e2e/open-education-api-v5/paths/BuildingInstance.yaml new file mode 100644 index 00000000..9f6b815d --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/BuildingInstance.yaml @@ -0,0 +1,34 @@ +get: + summary: GET /buildings/{buildingId} + description: Get a single building. + tags: + - buildings + parameters: + - name: buildingId + in: path + description: Building ID + required: true + schema: + type: string + format: uuid + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Building.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/BuildingRoomCollection.yaml b/tests/e2e/open-education-api-v5/paths/BuildingRoomCollection.yaml new file mode 100644 index 00000000..65005f1e --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/BuildingRoomCollection.yaml @@ -0,0 +1,77 @@ +get: + summary: GET /buildings/{buildingId}/rooms + description: Get a list of all rooms in a building. + tags: + - buildings + parameters: + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: buildingId + in: path + description: The id of the building to find rooms for + required: true + schema: + type: string + format: uuid + - name: roomType + in: query + description: Filter by room type + required: false + schema: + $ref: '../enumerations/roomType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - roomId + - name + - totalSeats + - availableSeats + - -roomId + - -name + - -totalSeats + - -availableSeats + default: [ name ] + example: + - name + - -availableSeats + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Room.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ComponentInstance.yaml b/tests/e2e/open-education-api-v5/paths/ComponentInstance.yaml new file mode 100644 index 00000000..c0a8251d --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ComponentInstance.yaml @@ -0,0 +1,46 @@ +get: + summary: GET /components/{componentId} + description: Get a single component. + tags: + - components + parameters: + - name: componentId + in: path + description: component ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - course + - organization + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Component.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ComponentOfferingCollection.yaml b/tests/e2e/open-education-api-v5/paths/ComponentOfferingCollection.yaml new file mode 100644 index 00000000..5e709f2c --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ComponentOfferingCollection.yaml @@ -0,0 +1,92 @@ +get: + summary: GET /components/{componentId}/offerings + description: Get a list of all offerings for this component, ordered chronologically. + tags: + - components + parameters: + - name: componentId + in: path + description: Component ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: resultExpected + in: query + description: Filter by resultExpected + required: false + schema: + type: boolean + - name: since + in: query + description: Filter all offerings by providing a minimum start date for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=`). + required: false + schema: + type: string + format: date + - name: until + in: query + description: Filter all offerings by providing a maximum end date for the corresponding academic session, RFC3339 (full-date). + required: false + schema: + type: string + format: date + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - offeringId + - name + - startDateTime + - endDateTime + - -offeringId + - -name + - -startDateTime + - -endDateTime + default: [ startDateTime ] + example: + - offeringId + - -startDateTime + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/ComponentOffering.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/CourseCollection.yaml b/tests/e2e/open-education-api-v5/paths/CourseCollection.yaml new file mode 100644 index 00000000..4f9b57dd --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/CourseCollection.yaml @@ -0,0 +1,72 @@ +get: + summary: GET /courses + description: Get a list of all courses, ordered by name (ascending). + tags: + - courses + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: level + in: query + description: Filter by level + required: false + schema: + $ref: '../enumerations/level.yaml' + - name: modeOfDelivery + in: query + description: Filter by modeOfDelivery + required: false + schema: + $ref: '../enumerations/modesOfDelivery.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - courseId + - name + - -courseId + - -name + default: [ name ] + example: + - name + - -courseId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Course.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/CourseComponentCollection.yaml b/tests/e2e/open-education-api-v5/paths/CourseComponentCollection.yaml new file mode 100644 index 00000000..fdd4ddbb --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/CourseComponentCollection.yaml @@ -0,0 +1,74 @@ +get: + summary: GET /courses/{courseId}/components + description: Get an ordered list of all course components. + tags: + - courses + parameters: + - name: courseId + in: path + description: Course ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: componentType + in: query + description: Filter by component type + required: false + schema: + $ref: '../enumerations/componentType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - componentId + - name + - -componentId + - -name + default: [ componentId ] + example: + - name + - -componentId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Component.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/CourseInstance.yaml b/tests/e2e/open-education-api-v5/paths/CourseInstance.yaml new file mode 100644 index 00000000..7a379769 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/CourseInstance.yaml @@ -0,0 +1,49 @@ +get: + summary: GET /courses/{courseId} + description: Get a single course. + tags: + - courses + parameters: + - name: courseId + in: path + description: Course ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to include, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - programs + - coordinators + - organization + - educationSpecification + - $ref: '../parameters/returnTimelineOverrides.yaml' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/CourseExpanded.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/CourseOfferingCollection.yaml b/tests/e2e/open-education-api-v5/paths/CourseOfferingCollection.yaml new file mode 100644 index 00000000..01f19a4c --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/CourseOfferingCollection.yaml @@ -0,0 +1,98 @@ +get: + summary: GET /courses/{courseId}/offerings + description: Get a list of all offerings for this course, ordered chronologically. + tags: + - courses + parameters: + - name: courseId + in: path + description: Course ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: modeOfDelivery + in: query + description: Filter by modeOfDelivery + required: false + schema: + $ref: '../enumerations/modesOfDelivery.yaml' + - name: resultExpected + in: query + description: Filter by resultExpected + required: false + schema: + type: boolean + - name: since + in: query + description: Filter all offerings by providing a minimum start date for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=`). + required: false + schema: + type: string + format: date + - name: until + in: query + description: Filter all offerings by providing a maximum end date for the corresponding academic session, RFC3339 (full-date). + required: false + schema: + type: string + format: date + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - offeringId + - name + - startDate + - endDate + - -offeringId + - -name + - -startDate + - -endDate + default: [ startDate ] + example: + - offeringId + - -endDate + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/CourseOffering.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/EducationSpecificationCollection.yaml b/tests/e2e/open-education-api-v5/paths/EducationSpecificationCollection.yaml new file mode 100644 index 00000000..dcca08ab --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/EducationSpecificationCollection.yaml @@ -0,0 +1,75 @@ +get: + summary: GET /education-specifications + description: Get a list of all education specifications, ordered by name (ascending). + tags: + - education specifications + parameters: + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: educationSpecificationType + in: query + description: Filter by type of education specification + required: false + schema: + $ref: '../enumerations/educationSpecificationType.yaml' + - name: primaryCode + in: query + description: Filter by primary code of education specification + required: false + schema: + type: string + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - educationSpecificationType + - name + - primaryCode + - -educationSpecificationType + - -name + - -primaryCode + default: + - [ name ] + example: + - educationSpecificationType + - -primaryCode + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/EducationSpecification.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/EducationSpecificationCourseCollection.yaml b/tests/e2e/open-education-api-v5/paths/EducationSpecificationCourseCollection.yaml new file mode 100644 index 00000000..d97299b3 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/EducationSpecificationCourseCollection.yaml @@ -0,0 +1,80 @@ +get: + summary: GET /education-specifications/{educationSpecificationId}/courses + description: Get an ordered list of all courses given through this EducationSpecification. + tags: + - education specifications + parameters: + - name: educationSpecificationId + in: path + description: Education Specification ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: level + in: query + description: Filter by level + required: false + schema: + $ref: '../enumerations/level.yaml' + - name: modeOfDelivery + in: query + description: Filter by modeOfDelivery + required: false + schema: + $ref: '../enumerations/modesOfDelivery.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - courseId + - name + - -courseId + - -name + default: [ courseId ] + example: + - courseId + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Course.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/EducationSpecificationEducationSpecificationCollection.yaml b/tests/e2e/open-education-api-v5/paths/EducationSpecificationEducationSpecificationCollection.yaml new file mode 100644 index 00000000..41cf7135 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/EducationSpecificationEducationSpecificationCollection.yaml @@ -0,0 +1,69 @@ +get: + summary: GET /education-specifications/{educationSpecificationId}/education-specifications + description: Get an ordered list of all education-specifications given through this educationspecification. + tags: + - education specifications + parameters: + - name: educationSpecificationId + in: path + description: Education Specification ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - educationSpecificationId + - name + - educationSpecificationType + - -educationSpecificationId + - -name + - -educationSpecificationType + default: [ educationSpecificationId ] + example: + - educationSpecificationId + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Course.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/EducationSpecificationInstance.yaml b/tests/e2e/open-education-api-v5/paths/EducationSpecificationInstance.yaml new file mode 100644 index 00000000..f76b6bba --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/EducationSpecificationInstance.yaml @@ -0,0 +1,52 @@ +get: + summary: GET /education-specifications/{educationSpecificationId} + description: Get a single education specification. + tags: + - education specifications + parameters: + - name: educationSpecificationId + in: path + description: Education specification ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/returnTimelineOverrides.yaml' + - name: expand + in: query + explode: false + description: Optional properties to include, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - parent + - children + - organization + responses: + '200': + description: OK + content: + application/json: + schema: + oneOf: + - title: Without timelineOverrides (default) + $ref: '../schemas/EducationSpecification.yaml' + - title: With timelineOverrides + $ref: '../schemas/EducationSpecificationExpanded.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/EducationSpecificationProgramCollection.yaml b/tests/e2e/open-education-api-v5/paths/EducationSpecificationProgramCollection.yaml new file mode 100644 index 00000000..84722ce6 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/EducationSpecificationProgramCollection.yaml @@ -0,0 +1,104 @@ +get: + summary: GET /education-specifications/{educationSpecificationId}/programs + description: Get an ordered list of all programs for a given education specification, ordered by name. + tags: + - education specifications + parameters: + - name: educationSpecificationId + in: path + description: Education Specification ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: programType + in: query + description: Filter by program type + required: false + schema: + $ref: '../enumerations/programType.yaml' + - name: qualificationAwarded + in: query + description: Filter by qualificationAwarded + required: false + schema: + $ref: '../enumerations/qualificationAwarded.yaml' + - name: levelOfQualification + in: query + description: Filter by levelOfQualification + required: false + schema: + $ref: '../enumerations/levelOfQualification.yaml' + - name: sector + in: query + description: Filter by sector + required: false + schema: + $ref: '../enumerations/sector.yaml' + - name: fieldsOfStudy + in: query + description: Filter by fieldsOfStudy + required: false + schema: + type: string + - name: croho-creboCode + in: query + description: Filter by croho-creboCode + required: false + schema: + type: string + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - programId + - name + - -programId + - -name + default: [ name ] + example: + - programId + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Program.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/GroupCollection.yaml b/tests/e2e/open-education-api-v5/paths/GroupCollection.yaml new file mode 100644 index 00000000..6e8cb0fb --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/GroupCollection.yaml @@ -0,0 +1,87 @@ +get: + summary: GET /groups + description: Get a list of all groups, ordered by name (ascending). + tags: + - groups + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: groupType + in: query + description: Filter by group type + required: false + schema: + $ref: '../enumerations/groupType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - groupId + - name + - startDate + - -groupId + - -name + - -startDate + default: [ name ] + example: + - groupId + - -startDate + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + required: + - pageSize + - pageNumber + - hasPreviousPage + - hasNextPage + - items + properties: + pageSize: + type: integer + format: int32 + description: The number of items per page + pageNumber: + type: integer + format: int32 + description: The current page number + hasPreviousPage: + type: boolean + description: Whether there is a previous page + hasNextPage: + type: boolean + description: Whether there is a previous page + totalPages: + type: integer + format: int32 + description: Total number of pages + items: + type: array + items: + $ref: '../schemas/Group.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/GroupInstance.yaml b/tests/e2e/open-education-api-v5/paths/GroupInstance.yaml new file mode 100644 index 00000000..c74ba60b --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/GroupInstance.yaml @@ -0,0 +1,45 @@ +get: + summary: GET /groups/{groupId} + description: Get a single group. + tags: + - groups + parameters: + - name: groupId + in: path + description: Group ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - organization + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Group.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/GroupPersonCollection.yaml b/tests/e2e/open-education-api-v5/paths/GroupPersonCollection.yaml new file mode 100644 index 00000000..2783a5db --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/GroupPersonCollection.yaml @@ -0,0 +1,95 @@ +get: + summary: GET /groups/{groupId}/persons + description: Get an ordered list of all persons that are member of a given group, ordered by personId. + tags: + - groups + parameters: + - name: groupId + in: path + description: Group ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/personSearch.yaml' + - name: affiliations + in: query + description: Filter by affiliations + required: false + schema: + $ref: '../enumerations/personAffiliations.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - personId + - givenName + - surName + - displayName + - -personId + - -givenName + - -surName + - -displayName + default: [ personId ] + example: + - personId + - -givenName + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + required: + - pageSize + - pageNumber + - hasPreviousPage + - hasNextPage + - items + properties: + pageSize: + type: integer + format: int32 + description: The number of items per page + pageNumber: + type: integer + format: int32 + description: The current page number + hasPreviousPage: + type: boolean + description: Whether there is a previous page + hasNextPage: + type: boolean + description: Whether there is a previous page + totalPages: + type: integer + format: int32 + description: Total number of pages + items: + type: array + items: + $ref: '../schemas/Person.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/NewsFeedCollection.yaml b/tests/e2e/open-education-api-v5/paths/NewsFeedCollection.yaml new file mode 100644 index 00000000..e6368aee --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/NewsFeedCollection.yaml @@ -0,0 +1,72 @@ +get: + summary: GET /news-feeds + description: Get a list of all news feeds, ordered by title. + tags: + - news + parameters: + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: newsFeedType + in: query + description: Filter by news type + required: false + schema: + type: string + enum: + - organization + - program + - course + - component + - person + - building + - room + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - newsFeedId + - name + - -newsFeedId + - -name + default: [ name ] + example: + - name + - -newsFeedId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/NewsFeed.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/NewsFeedInstance.yaml b/tests/e2e/open-education-api-v5/paths/NewsFeedInstance.yaml new file mode 100644 index 00000000..9f6cfb5a --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/NewsFeedInstance.yaml @@ -0,0 +1,34 @@ +get: + summary: GET /news-feeds/{newsFeedId} + description: Get a single news feed. + tags: + - news + parameters: + - name: newsFeedId + in: path + description: News feed ID + required: true + schema: + type: string + format: uuid + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/NewsFeed.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/NewsFeedItemCollection.yaml b/tests/e2e/open-education-api-v5/paths/NewsFeedItemCollection.yaml new file mode 100644 index 00000000..e509e718 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/NewsFeedItemCollection.yaml @@ -0,0 +1,79 @@ +get: + summary: GET /news-feeds/{newsFeedId}/news-items + description: Get an ordered list of all news items. + tags: + - news + parameters: + - name: newsFeedId + in: path + description: News feed ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: author + in: query + description: Filter by author + required: false + schema: + type: string + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - newsItemId + - name + - validFrom + - validUntil + - lastModified + - -newsItemId + - -name + - -validFrom + - -validUntil + - -lastModified + default: [ newsItemId ] + example: + - validFrom + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/NewsItem.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/NewsItemInstance.yaml b/tests/e2e/open-education-api-v5/paths/NewsItemInstance.yaml new file mode 100644 index 00000000..e0eb3768 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/NewsItemInstance.yaml @@ -0,0 +1,45 @@ +get: + summary: GET /news-items/{newsItemId} + description: Get a single news item. + tags: + - news + parameters: + - name: newsItemId + in: path + description: News item ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to include, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - newsFeeds + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/NewsItem.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OfferingAssociationCollection.yaml b/tests/e2e/open-education-api-v5/paths/OfferingAssociationCollection.yaml new file mode 100644 index 00000000..7e914118 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OfferingAssociationCollection.yaml @@ -0,0 +1,95 @@ +get: + summary: GET /offerings/{offeringId}/associations + description: Get a list of all offering associations. + tags: + - offerings + parameters: + - name: offeringId + in: path + description: Offering ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - name: associationType + in: query + description: Filter by association type + required: false + schema: + type: string + enum: + - programOffering + - courseOffering + - componentOffering + - name: role + in: query + description: Filter by role + required: false + schema: + $ref: '../enumerations/associationRole.yaml' + - name: state + in: query + description: Filter by state + required: false + schema: + $ref: '../enumerations/associationState.yaml' + - name: result-state + in: query + description: Filter by result state + required: false + schema: + $ref: '../enumerations/resultState.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - associationId + - -associationId + default: + - associationId + example: + - associationId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + oneOf: + - $ref: '../schemas/ProgramOfferingAssociationExpandable.yaml' + - $ref: '../schemas/CourseOfferingAssociationExpandable.yaml' + - $ref: '../schemas/ComponentOfferingAssociationExpandable.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OfferingAssociationInstanceMe.yaml b/tests/e2e/open-education-api-v5/paths/OfferingAssociationInstanceMe.yaml new file mode 100644 index 00000000..175c3028 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OfferingAssociationInstanceMe.yaml @@ -0,0 +1,41 @@ +post: + summary: POST offerings/{offeringId}/associations/me + description: | + POST a single association to enroll a person based on hte .wellknown information of the person at the institution. The offeringId is provided in the path. + security: + - openId: + - associations:me.write + tags: + - offerings + parameters: + - name: offeringId + in: path + description: Offering ID + required: true + schema: + type: string + format: uuid + + requestBody: + required: true + content: + application/json: + schema: + $ref: '../schemas/AssociationProperties.yaml' + + responses: + '201': + description: CREATED + content: + application/json: + schema: + allOf: + - $ref: '../schemas/AssociationId.yaml' + - $ref: '../schemas/PostResponse.yaml' + + '400': + description: Bad Request + content: + application/problem+json: + schema: + $ref: '../schemas/Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/paths/OfferingGroupCollection.yaml b/tests/e2e/open-education-api-v5/paths/OfferingGroupCollection.yaml new file mode 100644 index 00000000..f26717f8 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OfferingGroupCollection.yaml @@ -0,0 +1,93 @@ +get: + summary: GET /offerings/{offeringId}/groups + description: Get an ordered list of all groups related to an offering, ordered by name. + tags: + - offerings + parameters: + - name: offeringId + in: path + description: Offering ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: groupType + in: query + description: Filter by group type + required: false + schema: + $ref: '../enumerations/groupType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - groupId + - name + - startDate + - -groupId + - -name + - -startDate + default: [ name ] + example: + - name + - -startDate + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + required: + - pageSize + - pageNumber + - hasPreviousPage + - hasNextPage + - items + properties: + pageSize: + type: integer + format: int32 + description: The number of items per page + pageNumber: + type: integer + format: int32 + description: The current page number + hasPreviousPage: + type: boolean + description: Whether there is a previous page + hasNextPage: + type: boolean + description: Whether there is a previous page + totalPages: + type: integer + format: int32 + description: Total number of pages + items: + type: array + items: + $ref: '../schemas/Group.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OfferingInstance.yaml b/tests/e2e/open-education-api-v5/paths/OfferingInstance.yaml new file mode 100644 index 00000000..2bcfad24 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OfferingInstance.yaml @@ -0,0 +1,59 @@ +get: + summary: GET /offerings/{offeringId} + description: Get a single offering. + tags: + - offerings + parameters: + - name: offeringId + in: path + description: Offering ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - program + - programOffering + - course + - courseOffering + - component + - organization + - academicSession + responses: + '200': + description: OK + content: + application/json: + schema: + oneOf: + - $ref: '../schemas/CourseOffering.yaml' + title: courseOffering + - $ref: '../schemas/ComponentOffering.yaml' + title: componentOffering + - $ref: '../schemas/ProgramOffering.yaml' + title: programOffering + + + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationCollection.yaml new file mode 100644 index 00000000..fb8b7ee0 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationCollection.yaml @@ -0,0 +1,65 @@ +get: + summary: GET /organizations + description: Get an ordered list of all organizations, ordered by name. + tags: + - organizations + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: organizationType + in: query + description: Filter by organization type + required: false + schema: + $ref: '../enumerations/organizationType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - organizationId + - name + - -organizationId + - -name + default: [ name ] + example: + - name + - -organizationId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Organization.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationComponentCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationComponentCollection.yaml new file mode 100644 index 00000000..4dc1bb07 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationComponentCollection.yaml @@ -0,0 +1,74 @@ +get: + summary: GET /organizations/{organizationId}/components + description: Get an ordered list of all components for a given organization, ordered by name. + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: componentType + in: query + description: Filter by component type + required: false + schema: + $ref: '../enumerations/componentType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - componentId + - name + - -componentId + - -name + default: [ name ] + example: + - componentId + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Component.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationCourseCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationCourseCollection.yaml new file mode 100644 index 00000000..0dd90ac5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationCourseCollection.yaml @@ -0,0 +1,80 @@ +get: + summary: GET /organizations/{organizationId}/courses + description: Get an ordered list of all courses for a given organization, ordered by name. + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: level + in: query + description: Filter by level + required: false + schema: + $ref: '../enumerations/level.yaml' + - name: modeOfDelivery + in: query + description: Filter by modeOfDelivery + required: false + schema: + $ref: '../enumerations/modesOfDelivery.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - courseId + - name + - -courseId + - -name + default: [ name ] + example: + - name + - -courseId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Course.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationEducationSpecificationCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationEducationSpecificationCollection.yaml new file mode 100644 index 00000000..222f57fe --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationEducationSpecificationCollection.yaml @@ -0,0 +1,75 @@ +get: + summary: GET /organizations/{organizationId}/education-specifications + description: Get an ordered list of all EducationSpecifications for a given organization, ordered by name. + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: educationSpecificationType + in: query + description: Filter by type of education specification + required: false + schema: + $ref: '../enumerations/educationSpecificationType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - educationSpecificationType + - name + - primarycode + - -educationSpecificationType + - -name + - -primarycode + default: [ name ] + example: + - name + - -educationSpecificationType + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/EducationSpecification.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationGroupCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationGroupCollection.yaml new file mode 100644 index 00000000..f1bb1003 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationGroupCollection.yaml @@ -0,0 +1,73 @@ +get: + summary: GET /organizations/{organizationId}/groups + description: Get an ordered list of all groups for a given organization, ordered by name. + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: groupType + in: query + description: Filter by group type + required: false + schema: + $ref: '../enumerations/groupType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - groupId + - name + - startDate + - -groupId + - -name + - -startDate + default: [ name ] + example: + - groupId + - -name + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Group.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationInstance.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationInstance.yaml new file mode 100644 index 00000000..9e4e3ee5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationInstance.yaml @@ -0,0 +1,46 @@ +get: + summary: GET /organizations/{organizationId} + description: Get a single organization. + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - parent + - children + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Organization.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationOfferingCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationOfferingCollection.yaml new file mode 100644 index 00000000..96cf73ce --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationOfferingCollection.yaml @@ -0,0 +1,105 @@ +get: + summary: GET /organizations/{organizationId}/offerings + description: Get a list of all offerings for a given organization + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: offeringType + in: query + description: Filter by offering type + required: false + schema: + type: string + enum: + - program + - course + - component + - name: resultExpected + in: query + description: Filter by resultExpected + required: false + schema: + type: boolean + - name: since + in: query + description: Filter all offerings by providing a minimum start date for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=`). + required: false + schema: + type: string + format: date + - name: until + in: query + description: Filter all offerings by providing a maximum end date for the corresponding academic session, RFC3339 (full-date). + required: false + schema: + type: string + format: date + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - offeringId + - name + - startDate + - endDate + - -offeringId + - -name + - -startDate + - -endDate + default: [ startDate ] + example: + - name + - -startDate + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + oneOf: + - $ref: '../schemas/ProgramOffering.yaml' + - $ref: '../schemas/CourseOffering.yaml' + - $ref: '../schemas/ComponentOffering.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/OrganizationProgramCollection.yaml b/tests/e2e/open-education-api-v5/paths/OrganizationProgramCollection.yaml new file mode 100644 index 00000000..31e47988 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/OrganizationProgramCollection.yaml @@ -0,0 +1,98 @@ +get: + summary: GET /organizations/{organizationId}/programs + description: Get an ordered list of all programs for a given organization, ordered by name. + tags: + - organizations + parameters: + - name: organizationId + in: path + description: Organization ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: programType + in: query + description: Filter by program type + required: false + schema: + $ref: '../enumerations/programType.yaml' + - name: qualificationAwarded + in: query + description: Filter by qualificationAwarded + required: false + schema: + $ref: '../enumerations/qualificationAwarded.yaml' + - name: levelOfQualification + in: query + description: Filter by levelOfQualification + required: false + schema: + $ref: '../enumerations/levelOfQualification.yaml' + - name: sector + in: query + description: Filter by sector + required: false + schema: + $ref: '../enumerations/sector.yaml' + - name: fieldsOfStudy + in: query + description: Filter by fieldsOfStudy + required: false + schema: + type: string + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - programId + - name + - -programId + - -name + default: [ name ] + example: + - name + - -programId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Program.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/PersonAssociationCollection.yaml b/tests/e2e/open-education-api-v5/paths/PersonAssociationCollection.yaml new file mode 100644 index 00000000..57440bb0 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/PersonAssociationCollection.yaml @@ -0,0 +1,121 @@ +get: + summary: GET /persons/{personId}/associations + description: Get a list of all associations for an individual person. + tags: + - persons + parameters: + - name: personId + in: path + description: Person ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - name: associationType + in: query + description: Filter by association type + required: false + schema: + type: string + enum: + - programOffering + - courseOffering + - componentOffering + - name: role + in: query + description: Filter by role + required: false + schema: + $ref: '../enumerations/associationRole.yaml' + - name: state + in: query + description: Filter by state + required: false + schema: + $ref: '../enumerations/associationState.yaml' + - name: result-state + in: query + description: Filter by result state + required: false + schema: + $ref: '../enumerations/resultState.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - associationId + - -associationId + default: [ associationId ] + example: + - associationId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + oneOf: + - allOf: + - $ref: '../schemas/ProgramOfferingAssociation.yaml' + - type: object + required: + - offering + properties: + offering: + $ref: '../schemas/ProgramOffering.yaml' + academicSession: + $ref: '../schemas/AcademicSession.yaml' + - allOf: + - $ref: '../schemas/CourseOfferingAssociation.yaml' + - type: object + required: + - offering + properties: + offering: + $ref: '../schemas/CourseOffering.yaml' + academicSession: + $ref: '../schemas/AcademicSession.yaml' + - allOf: + - $ref: '../schemas/ComponentOfferingAssociation.yaml' + - type: object + required: + - offering + properties: + offering: + $ref: '../schemas/ComponentOffering.yaml' + academicSession: + $ref: '../schemas/AcademicSession.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/PersonCollection.yaml b/tests/e2e/open-education-api-v5/paths/PersonCollection.yaml new file mode 100644 index 00000000..a347130a --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/PersonCollection.yaml @@ -0,0 +1,96 @@ +get: + summary: GET /persons + description: Get an ordered list of all persons. + tags: + - persons + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/personSearch.yaml' + - name: affiliations + in: query + description: Filter by affiliations + required: false + schema: + $ref: '../enumerations/personAffiliations.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - personId + - givenName + - surName + - displayName + - -personId + - -givenName + - -surName + - -displayName + default: [ personId ] + example: + - surName + - -personId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Person.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' + +post: + summary: POST /persons + description: POST a single person. + tags: + - persons + requestBody: + required: true + content: + application/json: + schema: + allOf: + - $ref: '../schemas/PersonProperties.yaml' + + + responses: + '201': + description: CREATED + content: + application/json: + schema: + allOf: + - $ref: '../schemas/PersonId.yaml' + - $ref: '../schemas/PostResponse.yaml' + + '400': + $ref: '../schemas/ErrorBadRequest.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/PersonGroupCollection.yaml b/tests/e2e/open-education-api-v5/paths/PersonGroupCollection.yaml new file mode 100644 index 00000000..6da00cc7 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/PersonGroupCollection.yaml @@ -0,0 +1,93 @@ +get: + summary: GET /persons/{personId}/groups + description: Get an ordered list of all groups for a given person, ordered by name. + tags: + - persons + parameters: + - name: personId + in: path + description: Person ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: groupType + in: query + description: Filter by group type + required: false + schema: + $ref: '../enumerations/groupType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - groupId + - name + - startDate + - -groupId + - -name + - -startDate + default: [ name ] + example: + - name + - -groupId + responses: + '200': + description: OK + content: + application/json: + schema: + type: object + required: + - pageSize + - pageNumber + - hasPreviousPage + - hasNextPage + - items + properties: + pageSize: + type: integer + format: int32 + description: The number of items per page + pageNumber: + type: integer + format: int32 + description: The current page number + hasPreviousPage: + type: boolean + description: Whether there is a previous page + hasNextPage: + type: boolean + description: Whether there is a previous page + totalPages: + type: integer + format: int32 + description: Total number of pages + items: + type: array + items: + $ref: '../schemas/Group.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/PersonInstance.yaml b/tests/e2e/open-education-api-v5/paths/PersonInstance.yaml new file mode 100644 index 00000000..46e9b2cb --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/PersonInstance.yaml @@ -0,0 +1,34 @@ +get: + summary: GET /persons/{personId} + description: Get a single person. + tags: + - persons + parameters: + - name: personId + in: path + description: User ID + required: true + schema: + type: string + format: uuid + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Person.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/PersonMe.yaml b/tests/e2e/open-education-api-v5/paths/PersonMe.yaml new file mode 100644 index 00000000..de91d00a --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/PersonMe.yaml @@ -0,0 +1,28 @@ +get: + summary: GET /persons/me + description: Returns the person object for the currently authenticated user. + security: + - bearerAuth: [] + tags: + - persons + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Person.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ProgramCollection.yaml b/tests/e2e/open-education-api-v5/paths/ProgramCollection.yaml new file mode 100644 index 00000000..cfd375b9 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ProgramCollection.yaml @@ -0,0 +1,90 @@ +get: + summary: GET /programs + description: Get an ordered list of all programs, ordered by name. + tags: + - programs + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: programType + in: query + description: Filter by program type + required: false + schema: + $ref: '../enumerations/programType.yaml' + - name: qualificationAwarded + in: query + description: Filter by qualificationAwarded + required: false + schema: + $ref: '../enumerations/qualificationAwarded.yaml' + - name: levelOfQualification + in: query + description: Filter by levelOfQualification + required: false + schema: + $ref: '../enumerations/levelOfQualification.yaml' + - name: sector + in: query + description: Filter by sector + required: false + schema: + $ref: '../enumerations/sector.yaml' + - name: fieldsOfStudy + in: query + description: Filter by fieldsOfStudy + required: false + schema: + type: string + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - programId + - name + - -programId + - -name + default: [ name ] + example: + - name + - programId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Program.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ProgramCourseCollection.yaml b/tests/e2e/open-education-api-v5/paths/ProgramCourseCollection.yaml new file mode 100644 index 00000000..3ee838a3 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ProgramCourseCollection.yaml @@ -0,0 +1,80 @@ +get: + summary: GET /programs/{programId}/courses + description: Get an ordered list of all courses given through this program. + tags: + - programs + parameters: + - name: programId + in: path + description: Program ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: level + in: query + description: Filter by level + required: false + schema: + $ref: '../enumerations/level.yaml' + - name: modeOfDelivery + in: query + description: Filter by modeOfDelivery + required: false + schema: + $ref: '../enumerations/modesOfDelivery.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - courseId + - name + - -courseId + - -name + default: [ courseId ] + example: + - name + - -courseId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Course.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ProgramInstance.yaml b/tests/e2e/open-education-api-v5/paths/ProgramInstance.yaml new file mode 100644 index 00000000..7893b45e --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ProgramInstance.yaml @@ -0,0 +1,50 @@ +get: + summary: GET /programs/{programId} + description: Get a single program. + tags: + - programs + parameters: + - name: programId + in: path + description: Program ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to include, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - parent + - children + - coordinators + - organization + - educationSpecification + - $ref: '../parameters/returnTimelineOverrides.yaml' + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/ProgramExpanded.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ProgramOfferingCollection.yaml b/tests/e2e/open-education-api-v5/paths/ProgramOfferingCollection.yaml new file mode 100644 index 00000000..ffb90b21 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ProgramOfferingCollection.yaml @@ -0,0 +1,98 @@ +get: + summary: GET /programs/{programId}/offerings + description: Get a list of all offerings for this program, ordered chronologically. + tags: + - programs + parameters: + - name: programId + in: path + description: Program ID + required: true + schema: + type: string + format: uuid + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: modeOfStudy + in: query + description: Filter by modeOfStudy + required: false + schema: + $ref: '../enumerations/modeOfStudy.yaml' + - name: resultExpected + in: query + description: Filter by resultExpected + required: false + schema: + type: boolean + - name: since + in: query + description: Filter all offerings by providing a minimum start date for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=`). + required: false + schema: + type: string + format: date + - name: until + in: query + description: Filter all offerings by providing a maximum end date for the corresponding academic session, RFC3339 (full-date). + required: false + schema: + type: string + format: date + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - offeringId + - name + - startDate + - endDate + - -offeringId + - -name + - -startDate + - -endDate + default: [ startDate ] + example: + - name + - -startDate + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/ProgramOffering.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/ProgramProgramCollection.yaml b/tests/e2e/open-education-api-v5/paths/ProgramProgramCollection.yaml new file mode 100644 index 00000000..6716f124 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/ProgramProgramCollection.yaml @@ -0,0 +1,96 @@ +get: + summary: GET /programs/{programId}/programs + description: Get an ordered list of nested programs, ordered by name. + tags: + - programs + parameters: + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - $ref: '../parameters/teachingLanguage.yaml' + - name: programId + in: path + description: the id of the program to find nested programs for + required: true + schema: + type: string + format: uuid + - name: programType + in: query + description: Filter by program type + required: false + schema: + $ref: '../enumerations/programType.yaml' + - name: qualificationAwarded + in: query + description: Filter by qualificationAwarded + required: false + schema: + $ref: '../enumerations/qualificationAwarded.yaml' + - name: levelOfQualification + in: query + description: Filter by levelOfQualification + required: false + schema: + $ref: '../enumerations/levelOfQualification.yaml' + - name: sector + in: query + description: Filter by sector + required: false + schema: + $ref: '../enumerations/sector.yaml' + - name: fieldsOfStudy + in: query + description: Filter by fieldsOfStudy + required: false + schema: + type: string + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - programId + - name + - -programId + - -name + default: [ name ] + example: + - name + - -programId + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Program.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/RoomCollection.yaml b/tests/e2e/open-education-api-v5/paths/RoomCollection.yaml new file mode 100644 index 00000000..776d74a1 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/RoomCollection.yaml @@ -0,0 +1,69 @@ +get: + summary: GET /rooms + description: Get a list of all rooms, ordered by name (ascending). + tags: + - rooms + parameters: + - $ref: '../parameters/primaryCode.yaml' + - $ref: '../parameters/pageSize.yaml' + - $ref: '../parameters/pageNumber.yaml' + - $ref: '../parameters/consumer.yaml' + - $ref: '../parameters/search.yaml' + - name: roomType + in: query + description: Filter by room type + required: false + schema: + $ref: '../enumerations/roomType.yaml' + - name: sort + in: query + explode: false + description: 'Sort by one or more attributes, the default is ascending. Prefixing the attribute with a minus sign `-` allows for descending sort. Examples: [ATTR | -ATTR | ATTR1,-ATTR2]' + required: false + schema: + type: array + items: + type: string + enum: + - roomId + - name + - totalSeats + - availableSeats + - -roomId + - -name + - -totalSeats + - -availableSeats + default: [ name ] + example: + - name + - -availableSeats + responses: + '200': + description: OK + content: + application/json: + schema: + allOf: + - $ref: '../schemas/Pagination.yaml' + - type: object + required: + - items + properties: + items: + type: array + items: + $ref: '../schemas/Room.yaml' + ext: + $ref: '../schemas/Ext.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/RoomInstance.yaml b/tests/e2e/open-education-api-v5/paths/RoomInstance.yaml new file mode 100644 index 00000000..9733f436 --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/RoomInstance.yaml @@ -0,0 +1,45 @@ +get: + summary: GET /rooms/{roomId} + description: Get a single room. + tags: + - rooms + parameters: + - name: roomId + in: path + description: Room ID + required: true + schema: + type: string + format: uuid + - name: expand + in: query + explode: false + description: Optional properties to expand, separated by a comma + required: false + schema: + type: array + items: + type: string + enum: + - building + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Room.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/paths/Service.yaml b/tests/e2e/open-education-api-v5/paths/Service.yaml new file mode 100644 index 00000000..5459dbdc --- /dev/null +++ b/tests/e2e/open-education-api-v5/paths/Service.yaml @@ -0,0 +1,27 @@ +get: + parameters: [] + summary: GET / + description: Get metadata for the service. + tags: + - service metadata + responses: + '200': + description: OK + content: + application/json: + schema: + $ref: '../schemas/Service.yaml' + '400': + $ref: '../schemas/ErrorBadRequest.yaml' + '401': + $ref: '../schemas/ErrorUnauthorized.yaml' + '403': + $ref: '../schemas/ErrorForbidden.yaml' + '404': + $ref: '../schemas/ErrorNotFound.yaml' + '405': + $ref: '../schemas/ErrorMethodNotAllowed.yaml' + '429': + $ref: '../schemas/ErrorTooManyRequests.yaml' + '500': + $ref: '../schemas/ErrorInternalServerError.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/AcademicSession.yaml b/tests/e2e/open-education-api-v5/schemas/AcademicSession.yaml new file mode 100644 index 00000000..9ab552da --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/AcademicSession.yaml @@ -0,0 +1,80 @@ +type: object +description: | + A named period of time that can be used to communicate the various schedules and time periods an institution recognizes and uses to organize their education. AcademicSessions can be nested. + Offerings MAY be be linked to a specific AcademicSession to indicate that the specified Offering takes place during the AcademicSession, however this is not mandatory. +required: + - academicSessionId + - name + - startDate + - endDate +properties: + academicSessionId: + type: string + description: Unique id for this academic session + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + readOnly: true + academicSessionType: + $ref: '../enumerations/academicSessionType.yaml' + primaryCode: + description: The primary human readable identifier for this academic session. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: identifier + code: '2012-Q1' + name: + type: array + description: The name of this academic session + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Fall semester 2020 + startDate: + type: string + description: The day on which this academic session starts, RFC3339 (full-date) + format: date + example: '2020-08-17' + endDate: + type: string + description: The day on which this academic session ends, RFC3339 (full-date) + format: date + example: '2020-12-18' + parent: + description: The parent Academicsession of this session (e.g. fall semester 20xx where the current session is a week 40). This object is [`expandable`](#tag/academic_sessions_model) + oneOf: + - $ref: './Identifier.yaml' + title: academicSessionId + - $ref: './AcademicSession.yaml' + title: Expanded AcademicSession + children: + type: array + description: The list of Academicsession children of this Session (e.g. all academic sessions in fall semester 20xx). This object is [`expandable`](#tag/academic_sessions_model) + items: + oneOf: + - $ref: './Identifier.yaml' + title: academicSessionId + - $ref: './AcademicSession.yaml' + title: Expanded AcademicSession + year: + description: The top level year of this session (e.g. 20xx where the current session is a week 40 of a semester). This object is [`expandable`](#tag/academic_sessions_model) + oneOf: + - $ref: './Identifier.yaml' + title: academicSessionId + - $ref: './AcademicSession.yaml' + title: Expanded AcademicSession + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Address.yaml b/tests/e2e/open-education-api-v5/schemas/Address.yaml new file mode 100644 index 00000000..0ca44888 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Address.yaml @@ -0,0 +1,53 @@ +type: object +description: The full street address +required: + - addressType +properties: + addressType: + $ref: '../enumerations/addressType.yaml' + street: + type: string + description: The street name + example: Moreelsepark + streetNumber: + type: string + description: The street number + example: "48" + additional: + type: array + description: Further details like building name, suite, apartment number, etc. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: On the other side of the road + postalCode: + type: string + description: Postal code + example: 3511 EP + city: + type: string + description: name of the city / locality + example: Utrecht + countryCode: + type: string + description: the country code according to [iso-3166-1-alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + example: NL + geolocation: + type: object + description: Geolocation of the entrance of this address (WGS84 coordinate reference system) + required: + - latitude + - longitude + properties: + latitude: + type: number + format: double + example: 52.089123 + longitude: + type: number + format: double + example: 5.113337 + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Association.yaml b/tests/e2e/open-education-api-v5/schemas/Association.yaml new file mode 100644 index 00000000..99879d48 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Association.yaml @@ -0,0 +1,3 @@ +allOf: + - $ref: '../schemas/AssociationId.yaml' + - $ref: '../schemas/AssociationProperties.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/AssociationFull.yaml b/tests/e2e/open-education-api-v5/schemas/AssociationFull.yaml new file mode 100644 index 00000000..6f78db12 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/AssociationFull.yaml @@ -0,0 +1,26 @@ +# oneOf: +# - $ref: '../schemas/ComponentOfferingAssociation.yaml' +# - $ref: '../schemas/CourseOfferingAssociation.yaml' +# - $ref: '../schemas/ProgramOfferingAssociation.yaml' +oneOf: + - $ref: '../schemas/ProgramOfferingAssociation.yaml' + - $ref: '../schemas/CourseOfferingAssociation.yaml' + - $ref: '../schemas/ComponentOfferingAssociation.yaml' +properties: + person: + readOnly: true + oneOf: + - $ref: '../schemas/Identifier.yaml' + title: personId + - $ref: '../schemas/Person.yaml' + title: Person + offering: + oneOf: + - $ref: '../schemas/Identifier.yaml' + title: offeringId + - $ref: '../schemas/ComponentOffering.yaml' + title: ComponentOffering + - $ref: '../schemas/CourseOffering.yaml' + title: CourseOffering + - $ref: '../schemas/ProgramOffering.yaml' + title: ProgramOffering \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/AssociationId.yaml b/tests/e2e/open-education-api-v5/schemas/AssociationId.yaml new file mode 100644 index 00000000..ddf56d18 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/AssociationId.yaml @@ -0,0 +1,11 @@ +type: object +properties: + associationId: + type: string + description: Unique id of this association + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + readOnly: true +required: + - associationId + \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/AssociationProperties.yaml b/tests/e2e/open-education-api-v5/schemas/AssociationProperties.yaml new file mode 100644 index 00000000..f0ee1b42 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/AssociationProperties.yaml @@ -0,0 +1,33 @@ +type: object +description: A relationship between a person object and an offering +required: + - associationType + - role + - state +properties: + associationType: + type: string + description: The type of this association + enum: + - programOfferingAssociation + - courseOfferingAssociation + - componentOfferingAssociation + example: componentOfferingAssociation + readOnly: true + role: + $ref: '../enumerations/associationRole.yaml' + state: + $ref: '../enumerations/associationState.yaml' + readOnly: true + remoteState: + $ref: '../enumerations/remoteAssociationState.yaml' + writeOnly: true + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/AssociationWrite.yaml b/tests/e2e/open-education-api-v5/schemas/AssociationWrite.yaml new file mode 100644 index 00000000..918562ef --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/AssociationWrite.yaml @@ -0,0 +1,14 @@ +oneOf: + - $ref: '../schemas/ProgramOfferingAssociation.yaml' + - $ref: '../schemas/CourseOfferingAssociation.yaml' + - $ref: '../schemas/ComponentOfferingAssociation.yaml' +properties: + offering: + description: The offering this association is for + oneOf: + - $ref: '../schemas/ComponentOffering.yaml' + title: ComponentOffering + - $ref: '../schemas/CourseOffering.yaml' + title: CourseOffering + - $ref: '../schemas/ProgramOffering.yaml' + title: ProgramOffering diff --git a/tests/e2e/open-education-api-v5/schemas/Building.yaml b/tests/e2e/open-education-api-v5/schemas/Building.yaml new file mode 100644 index 00000000..f24c2a02 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Building.yaml @@ -0,0 +1,61 @@ +type: object +description: An object describing a building and the properties of a building. +required: + - buildingId + - name + - address + - primaryCode +properties: + buildingId: + type: string + description: Unique id of this building + format: uuid + example: 123e4567-e89b-12d3-a456-331214174000 + primaryCode: + description: The primary human readable identifier for this building. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: buildingId + code: '45' + abbreviation: + type: string + description: The abbreviation of the name of this building + maxLength: 256 + example: Bb + name: + type: array + description: The name of this building + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Beatrix building + description: + type: array + description: The description of this building. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: external rooms location for exams + address: + $ref: './Address.yaml' + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + example: + - codeType: bagId + code: '0344100000139910' + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Component.yaml b/tests/e2e/open-education-api-v5/schemas/Component.yaml new file mode 100644 index 00000000..e403f338 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Component.yaml @@ -0,0 +1,150 @@ +type: object +description: A component is a part of a course +required: + - componentId + - componentType + - name + - teachingLanguage + - abbreviation + - primaryCode +properties: + componentId: + type: string + description: Unique id of this component + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + readOnly: true + primaryCode: + description: The primary human readable identifier for this component. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: componentCode + code: INFOMQNM-WRKCLG-1 + readOnly: true + componentType: + $ref: '../enumerations/componentType.yaml' + name: + type: array + description: The name of this component + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Written test for INFOMQNM + abbreviation: + type: string + description: The abbreviation of this component + maxLength: 256 + example: Test-INFOMQNM + modeOfDelivery: + $ref: '../enumerations/modesOfDelivery.yaml' + duration: + type: string + description: The duration of this component. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339. + pattern: '^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$' + example: P1DT30H4S + description: + type: array + description: The description of this component. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: > + 'Prove executable knowledge of research methods, including: + Acquire knowledge of HCI research paradigms + Able to design suitable research studies (e.g., choose between within and between subject designs) + Define/apply/design metrics and scales + Define/produce materials (e.g., stimuli and questionnaires) + Define protocols for research studies + Understands and take in account concepts of reliability and validity + Analyze and improve methods and analysis of published scientific articles + Able to deliver scientific reports + + Prove executable knowledge of ­­­statistics, including: + Handle hypothesis testing with complex designs (e.g., including , dependent, independent, and co variates) + Data preparation (e.g., coding and feature selection) + Reason towards adequate techniques to ensure valid outcomes (e.g., be aware of type I, type II errors) + Select an appropriate sampling method (e.g., stratified) + Perform parametric tests (e.g., repeated measures (M)ANOVA) + Perform non-parametric tests (e.g., Chi-square, Mann-Whitney, and Kruskal-Wallis)' + teachingLanguage: + type: string + description: The (primary) teaching language in which this component is given, should be a three-letter language code as specified by ISO 639-2. + minLength: 3 + maxLength: 3 + pattern: "^[a-z]{3}$" + example: nld + learningOutcomes: + type: array + description: Statements that describe the knowledge or skills students should acquire by the end of a particular course (ECTS-learningoutcome). + items: + type: array + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: 'Executable knowledge of research methods, including: Acquire knowledge of HCI research paradigms.' + enrollment: + type: array + items: + $ref: './LanguageTypedString.yaml' + description: The extra information that is provided for enrollment + example: + - language: en-GB + value: enrollment through SIS. [The limited implementation of Git Hub Markdown syntax](#tag/formatting-and-displaying-results-from-API) MAY be used for rich text representation. + resources: + type: array + description: An overview of the literature and other resources that is used in this course (ECTS-recommended reading and other sources) + items: + type: string + example: ['book to be announced', 'on-line resource x'] + assessment: + type: array + description: A description of the way exams for this course are taken (ECTS-assessment method and criteria). + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Exam on campus + addresses: + type: array + description: Addresses for this component + items: + $ref: './Address.yaml' + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + course: + description: | + The course of which this component is a part. [`expandable`](#tag/course_model) + By default only the `courseId` (a string) is returned. If the client requested an expansion of `course` the full course object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: courseId + - $ref: './Course.yaml' + title: Course object + organization: + description: | + The organization which provides this component. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ComponentOffering.yaml b/tests/e2e/open-education-api-v5/schemas/ComponentOffering.yaml new file mode 100644 index 00000000..912ba213 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ComponentOffering.yaml @@ -0,0 +1,80 @@ +allOf: + - $ref: './Offering.yaml' + - type: object + required: + - startDateTime + - endDateTime + properties: + startDateTime: + type: string + description: The moment on which this offering starts, RFC3339 (date-time) + format: date-time + example: 2020-12-15 + endDateTime: + type: string + description: The moment on which this offering ends, RFC3339 (date-time) + format: date-time + example: 2020-12-16 + enrollStartDate: + type: string + description: The first day on which a student can enroll for this course. + format: date + enrollEndDate: + type: string + description: The last day on which a student can enroll for this course. + format: date + resultWeight: + type: integer + description: The result weight of this offering + minimum: 0 + maximum: 100 + example: 100 + addresses: + type: array + description: Addresses for this offering + items: + $ref: './Address.yaml' + priceInformation: + type: array + description: Price information for this offering. + items: + $ref: './Cost.yaml' + room: + $ref: './Room.yaml' + component: + description: | + The component that is offered in this componentoffering. [`expandable`](#tag/component_model) + By default only the `componentId` (a string) is returned. If the client requested an expansion of `component` the full component object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: componentId + - $ref: './Component.yaml' + title: Component object + courseOffering: + description: | + The courseoffering where this componentoffering is related to. [`expandable`](#tag/course_offering_model) + By default only the `courseOfferingId` (a string) is returned. If the client requested an expansion of `courseOffering` the full courseOffering object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: courseOfferingId + - $ref: './CourseOffering.yaml' + title: CourseOffering object + organization: + description: | + The organization that manages this componentoffering. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + academicSession: + description: | + The academicsession during which this componentoffering takes place. [`expandable`](#tag/academic_session_model) + By default only the `academicSessionId` (a string) is returned. If the client requested an expansion of `academicSession` the full academicsession object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: academicSessionId + - $ref: './AcademicSession.yaml' + title: AcademicSession object + diff --git a/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociation.yaml b/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociation.yaml new file mode 100644 index 00000000..6150c047 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociation.yaml @@ -0,0 +1,6 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './ComponentResult.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpandable.yaml b/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpandable.yaml new file mode 100644 index 00000000..740689c2 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpandable.yaml @@ -0,0 +1,8 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './ComponentResult.yaml' + person: + $ref: './PersonId.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpanded.yaml new file mode 100644 index 00000000..000970bb --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ComponentOfferingAssociationExpanded.yaml @@ -0,0 +1,16 @@ +allOf: + - $ref: '../schemas/ComponentOfferingAssociation.yaml' +properties: + person: + readOnly: true + oneOf: + - $ref: '../schemas/Identifier.yaml' + title: personId + - $ref: '../schemas/Person.yaml' + title: Person + offering: + oneOf: + - $ref: '../schemas/Identifier.yaml' + title: offeringId + - $ref: '../schemas/ComponentOffering.yaml' + title: ComponentOffering diff --git a/tests/e2e/open-education-api-v5/schemas/ComponentResult.yaml b/tests/e2e/open-education-api-v5/schemas/ComponentResult.yaml new file mode 100644 index 00000000..9eececac --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ComponentResult.yaml @@ -0,0 +1,13 @@ +allOf: + - $ref: './Result.yaml' + - type: object + required: + - weight + properties: + weight: + type: integer + description: The weight to 100 as total for this offering in the course + format: int32 + minimum: 0 + maximum: 100 + example: 100 diff --git a/tests/e2e/open-education-api-v5/schemas/Consumer.yaml b/tests/e2e/open-education-api-v5/schemas/Consumer.yaml new file mode 100644 index 00000000..01bb21b2 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Consumer.yaml @@ -0,0 +1,9 @@ +type: object +description: Object for communicating data to a specific consumer (destination). This object has no relationship with the `consumer` query parameter. +required: + - consumerKey +properties: + consumerKey: + description: The key of the consumer (destination) for which this information is intended. See the [consumer registry](https://open-education-api.github.io/specification/#/consumers) for more information. + type: string +additionalProperties: true diff --git a/tests/e2e/open-education-api-v5/schemas/Cost.yaml b/tests/e2e/open-education-api-v5/schemas/Cost.yaml new file mode 100644 index 00000000..7855e2c5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Cost.yaml @@ -0,0 +1,38 @@ +type: object +required: + - costType +properties: + costType: + $ref: '../enumerations/costType.yaml' + amount: + type: string + pattern: '^\d+(?:\.\d+)?$' + description: The total amount of the cost as a string. Use a '.' (dot) as an optional separator. The numbers before the separator signify the major units of the currency, after the dot the minor units. Only a single separator is allowed. Do not use a comma. + example: '340.84' + vatAmount: + type: string + pattern: '^\d+(?:\.\d+)?$' + description: The part of the cost that is VAT, as a string. Use a '.' (dot) as an optional separator. The numbers before the separator signify the major units of the currency, after the dot the minor units. Only a single separator is allowed. Do not use a comma. + example: '40' + amountWithoutVat: + type: string + pattern: '^\d+(?:\.\d+)?$' + description: The part of the cost that is non-VAT. as a string. Use a '.' (dot) as an optional separator. The numbers before the separator signify the major units of the currency, after the dot the minor units. Only a single separator is allowed. Do not use a comma. + example: '300.84' + currency: + type: string + description: The currency this cost is in. Should correspond to one of the currency codes from ISO 4217. + example: EUR + displayAmount: + type: array + items: + $ref: './LanguageTypedString.yaml' + description: An array of optional pre-formatted strings in different locales. Clients can choose to use this string instead of rendering their own based on the current locale of the user. + example: + - language: nl-NL + value: '€380,84' + - language: en-US + value: '$401.17' + ext: + $ref: './Ext.yaml' +additionalProperties: false diff --git a/tests/e2e/open-education-api-v5/schemas/Course.yaml b/tests/e2e/open-education-api-v5/schemas/Course.yaml new file mode 100644 index 00000000..92fbaf50 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Course.yaml @@ -0,0 +1,12 @@ +allOf: + - $ref: '../schemas/CourseId.yaml' + - $ref: '../schemas/CourseProperties.yaml' + - properties: + validFrom: + description: The first day this course is valid (inclusive). + type: string + format: date + validTo: + description: The day this course ceases to be valid (e.g. exclusive). + type: string + format: date diff --git a/tests/e2e/open-education-api-v5/schemas/CourseExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/CourseExpanded.yaml new file mode 100644 index 00000000..085bb5bf --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseExpanded.yaml @@ -0,0 +1,10 @@ +allOf: + - $ref: './Course.yaml' + - type: object + description: These properties are only present when explicitly included + properties: + timelineOverrides: + description: Timeline overrides allow an implementation to provide versions of entities that will be valid in the future or have been in the past. + type: array + items: + $ref: './TimelineOverrideCourse.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/CourseId.yaml b/tests/e2e/open-education-api-v5/schemas/CourseId.yaml new file mode 100644 index 00000000..5192d659 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseId.yaml @@ -0,0 +1,11 @@ +type: object +description: An object describing the metadata of a course +required: + - courseId +properties: + courseId: + type: string + description: Unique id of this course + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + readOnly: true diff --git a/tests/e2e/open-education-api-v5/schemas/CourseOffering.yaml b/tests/e2e/open-education-api-v5/schemas/CourseOffering.yaml new file mode 100644 index 00000000..c63f9e39 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseOffering.yaml @@ -0,0 +1,85 @@ +allOf: + - $ref: './Offering.yaml' + - type: object + required: + - modeOfStudy + - startDate + - endDate + properties: + startDate: + type: string + description: The moment on which this offering starts, RFC3339 (full-date) + format: date + example: 2019-08-21 + endDate: + type: string + description: The moment on which this offering ends, RFC3339 (full-date) + format: date + example: 2019-10-23 + enrollStartDate: + type: string + description: The first day on which a student can enroll for this course. + format: date + example: 2019-05-01 + enrollEndDate: + type: string + description: The last day on which a student can enroll for this course. + format: date + example: 2019-08-01 + flexibleEntryPeriodStart: + type: string + description: If this is a course wherein participants can start at various moments, without missing anything, use this attribute in combination with `flexibleEntryPeriodEnd`. + format: date + flexibleEntryPeriodEnd: + type: string + description: If this is a course wherein participants can start at various moments, without missing anything, use this attribute in combination with `flexibleEntryPeriodStart`. + format: date + addresses: + type: array + description: Addresses for this offering + items: + $ref: './Address.yaml' + priceInformation: + type: array + description: Price information for this offering. + items: + $ref: './Cost.yaml' + course: + description: | + The course that is offered in this courseoffering. [`expandable`](#tag/course_model) + By default only the `courseId` (a string) is returned. If the client requested an expansion of `course` the full course object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: courseId + - $ref: './Course.yaml' + title: Course object + programOffering: + description: | + The programoffering where this courseoffering is related to. [`expandable`](#tag/program_offering_model) + By default only the `programOfferingId` (a string) is returned. If the client requested an expansion of `programOffering` the full programOffering object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: programOfferingId + - $ref: './ProgramOffering.yaml' + title: ProgramOffering object + organization: + description: | + The organization that manages this courseoffering. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + academicSession: + description: | + The academicsession during which this courseoffering takes place. [`expandable`](#tag/academic_session_model) + By default only the `academicSessionId` (a string) is returned. If the client requested an expansion of `academicSession` the full academicsession object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: academicSessionId + - $ref: './AcademicSession.yaml' + title: AcademicSession object + + + diff --git a/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociation.yaml b/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociation.yaml new file mode 100644 index 00000000..a7588873 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociation.yaml @@ -0,0 +1,6 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './CourseResult.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpandable.yaml b/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpandable.yaml new file mode 100644 index 00000000..f6a6cf3c --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpandable.yaml @@ -0,0 +1,8 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './CourseResult.yaml' + person: + $ref: './PersonId.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpanded.yaml new file mode 100644 index 00000000..ee61c618 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseOfferingAssociationExpanded.yaml @@ -0,0 +1,13 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './CourseResult.yaml' + person: + description: The person this association is to + $ref: './Person.yaml' + offering: + description: The offering this association is for + $ref: './Offering.yaml' + \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/CourseProperties.yaml b/tests/e2e/open-education-api-v5/schemas/CourseProperties.yaml new file mode 100644 index 00000000..638e7197 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseProperties.yaml @@ -0,0 +1,172 @@ +type: object +description: An object describing the metadata of a course +required: + - name + - abbreviation + - description + - teachingLanguage + - level + - primaryCode +properties: + primaryCode: + description: The primary human readable identifier for this course. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + readOnly: true + name: + type: array + description: The name of this course (ECTS-title) + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Academic and Professional Writing + abbreviation: + type: string + description: The abbreviation or internal code used to identify this course (ECTS-code) + maxLength: 256 + example: INFOMQNM + studyLoad: + $ref: './StudyLoadDescriptor.yaml' + modeOfDelivery: + $ref: '../enumerations/modesOfDelivery.yaml' + duration: + type: string + description: The duration of this course. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339. + pattern: '^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$' + example: P1DT30H4S + firstStartDate: + type: string + description: The date when participants can follow this course for the first time. + format: date + description: + type: array + description: The description of this course (ECTS-description). + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: 'As with all empirical sciences, to assure valid outcomes, HCI studies heavily rely on research methods and statistics. This holds for the design of user interfaces, personalized recommender systems, and interaction paradigms for the internet of things. This course prepares you to do so by learning you to collect data, design experiments, and analyze the results. By the end of the course, you will have a detailed understanding of how to select and apply quantitative research methods and analysis to address virtually all HCI challenges. Quantitative research and data analysis will be taught in the context of state-of-the-art HCI challenges. Lectures will be alternated with hands-on learning, including work with predefined datasets (e.g., addressing facial features, cognitive load, and emotion). Additionally, students will set up their own research (e.g., using eye tracking). Data processing and analysis will be executed using R.' + teachingLanguage: + type: string + description: The (primary) teaching language in which this course is given, should be a three-letter language code as specified by ISO 639-2. + minLength: 3 + maxLength: 3 + pattern: "^[a-z]{3}$" + example: nld + fieldsOfStudy: + type: string + description: Field(s) of study (e.g. ISCED-F) (http://uis.unesco.org/sites/default/files/documents/isced-fields-of-education-and-training-2013-en.pdf. + maxLength: 4 + example: '0732' + learningOutcomes: + type: array + description: Statements that describe the knowledge or skills students should acquire by the end of a particular course (ECTS-learningoutcome). + items: + type: array + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: 'Executable knowledge of research methods, including: Acquire knowledge of HCI research paradigms.' + admissionRequirements: + type: array + description: This information may be given at an institutional level and/or at the level of individual programmes. Make sure that it is clear whether the information applies to fee-paying students (national and/or international) or to exchange students. + example: + - language: en-GB + value: Students need to be enrolled at qualifying institutions of higher education that participate in this alliance + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + qualificationRequirements: + type: array + description: Normally, students will receive a diploma when they have completed the (official) study program and have obtained the required number of credits. If there are any other specific requirements that students need to have fulfilled, mention them here. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + level: + $ref: '../enumerations/level.yaml' + enrollment: + type: array + items: + $ref: './LanguageTypedString.yaml' + description: The extra information that is provided for enrollment + example: + - language: en-GB + value: enrollment through SIS. [The limited implementation of Git Hub Markdown syntax](#tag/formatting-and-displaying-results-from-API) MAY be used for rich text representation. + resources: + type: array + description: An overview of the literature and other resources that is used in this course (ECTS-recommended reading and other sources) + items: + type: string + example: ['book to be announced', 'on-line resource x'] + assessment: + type: array + description: A description of the way exams for this course are taken (ECTS-assessment method and criteria). + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Exam on campus + link: + type: string + description: URL of the course's website + format: uri + maxLength: 2048 + example: https://osiris.uu.nl/osiris_student_uuprd/OnderwijsCatalogusZoekCursus.do#submitForm?cursuscode=INFOMQNM + educationSpecification: + description: The educationSpecification of which this course is a more concrete implementation. [`expandable`](#tag/education_specification_model) + oneOf: + - $ref: './Identifier.yaml' + title: educationSpecificationId + - $ref: './EducationSpecification.yaml' + title: EducationSpecification + addresses: + type: array + description: Addresses for this course + items: + $ref: './Address.yaml' + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/RIO/V1/examples/Course.yaml' + ext: + $ref: './Ext.yaml' + programs: + description: The program of which this course is a part of. This object is [`expandable`](#tag/program_model) + type: array # array is used because of implementation of alliances in program where courses can be part of regular education and alliances + items: + oneOf: + - $ref: './Identifier.yaml' + title: programId + - $ref: './Program.yaml' + title: Program object + coordinators: + description: The person(s) responsible for this course. This object is [`expandable`](#tag/person_model) + type: array + items: + oneOf: + - $ref: './Identifier.yaml' + title: personId + - $ref: './Person.yaml' + title: Person object + organization: + description: | + The organization that manages this group. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object diff --git a/tests/e2e/open-education-api-v5/schemas/CourseResult.yaml b/tests/e2e/open-education-api-v5/schemas/CourseResult.yaml new file mode 100644 index 00000000..ddd0fba3 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/CourseResult.yaml @@ -0,0 +1,8 @@ +allOf: + - $ref: './Result.yaml' + - type: object + required: + - studyLoad + properties: + studyLoad: + $ref: './StudyLoadDescriptor.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/EducationSpecification.yaml b/tests/e2e/open-education-api-v5/schemas/EducationSpecification.yaml new file mode 100644 index 00000000..edc532aa --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/EducationSpecification.yaml @@ -0,0 +1,12 @@ +allOf: + - $ref: '../schemas/EducationSpecificationId.yaml' + - $ref: '../schemas/EducationSpecificationProperties.yaml' + - properties: + validFrom: + description: The first day this EducationSpecification is valid (inclusive). + type: string + format: date + validTo: + description: The day this EducationSpecification ceases to be valid (e.g. exclusive). + type: string + format: date diff --git a/tests/e2e/open-education-api-v5/schemas/EducationSpecificationExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/EducationSpecificationExpanded.yaml new file mode 100644 index 00000000..409dfb85 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/EducationSpecificationExpanded.yaml @@ -0,0 +1,10 @@ +allOf: + - $ref: '../schemas/EducationSpecification.yaml' + - type: object + title: With timelineOverrides + properties: + timelineOverrides: + description: Timeline overrides allow an implementation to provide versions of entities that will be valid in the future or have been in the past. + type: array + items: + $ref: '../schemas/TimelineOverrideEducationSpecification.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/EducationSpecificationId.yaml b/tests/e2e/open-education-api-v5/schemas/EducationSpecificationId.yaml new file mode 100644 index 00000000..dd31240b --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/EducationSpecificationId.yaml @@ -0,0 +1,9 @@ +type: object +properties: + educationSpecificationId: + type: string + description: Unique id for this education specification + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 +required: + - educationSpecificationId diff --git a/tests/e2e/open-education-api-v5/schemas/EducationSpecificationProperties.yaml b/tests/e2e/open-education-api-v5/schemas/EducationSpecificationProperties.yaml new file mode 100644 index 00000000..5b703d5a --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/EducationSpecificationProperties.yaml @@ -0,0 +1,112 @@ +type: object +description: | + The specification of an education object. This specification allows for other education objects to be derived from it. + It is used to aggregate education objects from a supplying institution. + It clusters programs to a main educationSpecification that is used in registries such as RIO. +required: + - primaryCode + - educationSpecificationType + - name +properties: + primaryCode: + description: | + The primary human readable identifier for the entity. + This will often take the form of a human readable code as defined by the institution or region + $ref: './IdentifierEntry.yaml' + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + example: + - codeType: crohoCreboCode + code: '1234123' + educationSpecificationType: + $ref: '../enumerations/educationSpecificationType.yaml' + name: + type: array + items: + $ref: './LanguageTypedString.yaml' + description: The name of this education specification + example: + - language: en-GB + value: Bachelor Chemical technology + abbreviation: + type: string + description: The abbreviation of this program + maxLength: 256 + example: B Scheikundige Technologie + description: + type: array + items: + $ref: './LanguageTypedString.yaml' + description: The description of this program. [The limited implementation of Git Hub Markdown syntax](#tag/formatting-and-displaying-results-from-API) MAY be used for rich text representation. + example: + - language: en-GB + value: program that is a place holder for all courses that are made available for student mobility + formalDocument: + $ref: '../enumerations/formalDocument.yaml' + level: + $ref: '../enumerations/level.yaml' + sector: + $ref: '../enumerations/sector.yaml' + levelOfQualification: + $ref: '../enumerations/levelOfQualification.yaml' + fieldsOfStudy: + type: string + description: Field(s) of study (e.g. ISCED-F) (http://uis.unesco.org/sites/default/files/documents/isced-fields-of-education-and-training-2013-en.pdf. + maxLength: 4 + example: '0732' + studyLoad: + $ref: './StudyLoadDescriptor.yaml' + learningOutcomes: + type: array + description: Statements that describe the knowledge or skills students should acquire by the end of a particular course or program (ECTS-learningoutcome). + items: + type: array + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: 'Executable knowledge of Chemical technology, including: Acquire knowledge of research paradigms.' + link: + type: string + description: URL of the program's website + format: uri + maxLength: 2048 + example: https://bijvak.nl + parent: + description: The educationSpecification that is the parent of this educationSpecification if it exists. [`expandable`](#tag/education_specification_model) + oneOf: + - $ref: './Identifier.yaml' + title: educationSpecificationId + - $ref: './EducationSpecification.yaml' + title: EducationSpecification + children: + type: array + description: The EducationSpecifications that have this EducationSpecification as their parent. [`expandable`](#tag/education_specification_model) + items: + oneOf: + - $ref: './Identifier.yaml' + title: educationSpecificationId + - $ref: './EducationSpecification.yaml' + title: EducationSpecification + organization: + description: | + The organization that manages this group. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/RIO/V1/examples/EducationSpecification.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorBadRequest.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorBadRequest.yaml new file mode 100644 index 00000000..efe9aa1f --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorBadRequest.yaml @@ -0,0 +1,5 @@ +description: Bad request +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorForbidden.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorForbidden.yaml new file mode 100644 index 00000000..e3b4ac73 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorForbidden.yaml @@ -0,0 +1,5 @@ +description: Forbidden +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorInternalServerError.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorInternalServerError.yaml new file mode 100644 index 00000000..c6f3809a --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorInternalServerError.yaml @@ -0,0 +1,5 @@ +description: Internal Server Error +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorMethodNotAllowed.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorMethodNotAllowed.yaml new file mode 100644 index 00000000..23adf76f --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorMethodNotAllowed.yaml @@ -0,0 +1,5 @@ +description: Method not allowed +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorNotFound.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorNotFound.yaml new file mode 100644 index 00000000..778f4d92 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorNotFound.yaml @@ -0,0 +1,5 @@ +description: Not Found +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorTooManyRequests.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorTooManyRequests.yaml new file mode 100644 index 00000000..7e510147 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorTooManyRequests.yaml @@ -0,0 +1,5 @@ +description: Too many requests +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/ErrorUnauthorized.yaml b/tests/e2e/open-education-api-v5/schemas/ErrorUnauthorized.yaml new file mode 100644 index 00000000..beb48d3f --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ErrorUnauthorized.yaml @@ -0,0 +1,5 @@ +description: Unauthorized +content: + application/problem+json: + schema: + $ref: 'Problem.yaml' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/Ext.yaml b/tests/e2e/open-education-api-v5/schemas/Ext.yaml new file mode 100644 index 00000000..d6501ad7 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Ext.yaml @@ -0,0 +1,2 @@ +type: object +description: Object for additional non-standard attributes diff --git a/tests/e2e/open-education-api-v5/schemas/Group.yaml b/tests/e2e/open-education-api-v5/schemas/Group.yaml new file mode 100644 index 00000000..d08cb9ef --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Group.yaml @@ -0,0 +1,81 @@ +type: object +description: | + A group is simply a collection of persons. Groups can be used to accommodate various usecases. + + Groups MAY optionally have a relation to an Offering, however the meaning of such relations is left unspecified and is left up to the implementer. +required: + - groupId + - groupType + - name + - primaryCode +properties: + groupId: + type: string + description: Unique id for this group + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + primaryCode: + description: The primary human readable identifier for this group. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: groupCode + code: group-abc987 + groupType: + $ref: '../enumerations/groupType.yaml' + name: + type: array + description: The name of this group + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: statistics students + description: + type: array + description: The description of this group + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: The group of students that follow statistics classes + startDate: + type: string + description: The day on which this group starts being active, RFC3339 (full-date) + format: date + example: '2020-08-17' + endDate: + type: string + description: The day on which this group ends being active, RFC3339 (full-date) + format: date + example: '2020-12-18' + personCount: + type: number + description: The number of persons that are member of this group + format: int32 + minimum: 0 + example: 183 + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + organization: + description: | + The organization that manages this group. [`expandable`](.#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Expanded organization + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/GroupExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/GroupExpanded.yaml new file mode 100644 index 00000000..eaae9742 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/GroupExpanded.yaml @@ -0,0 +1,9 @@ +allOf: + - $ref: './Group.yaml' + - type: object + description: These properties are only present when explicitly included. This allows for categorizing of groups + properties: + organization: + allOf: # Use allOf to make sure description renders + - $ref: './Organization.yaml' + - description: The organization providing this group diff --git a/tests/e2e/open-education-api-v5/schemas/Identifier.yaml b/tests/e2e/open-education-api-v5/schemas/Identifier.yaml new file mode 100644 index 00000000..c9a73649 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Identifier.yaml @@ -0,0 +1,3 @@ +type: string +description: An identifier of another resource. +format: uuid \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/IdentifierEntry.yaml b/tests/e2e/open-education-api-v5/schemas/IdentifierEntry.yaml new file mode 100644 index 00000000..06d8dda5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/IdentifierEntry.yaml @@ -0,0 +1,14 @@ +type: object +properties: + codeType: + $ref: '../enumerations/codeType.yaml' + code: + description: Human readable value for the code/identifier + type: string +required: + - codeType + - code +additionalProperties: false +example: + codeType: 'identifier' + code: '1234qwe12' \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/LanguageTypedString.yaml b/tests/e2e/open-education-api-v5/schemas/LanguageTypedString.yaml new file mode 100644 index 00000000..17dbbd94 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/LanguageTypedString.yaml @@ -0,0 +1,13 @@ +type: object +description: A String with an associated language code. +properties: + language: + description: The language used in the described entity. A string formatted according to RFC3066. + type: string + pattern: "^[a-z]{2,4}(-[A-Z][a-z]{3})?(-([A-Z]{2}|[0-9]{3}))?$" + value: + description: String to describe the entity. + type: string +example: + language: en-GB + value: program that is a place holder for all courses that are made available for student mobility diff --git a/tests/e2e/open-education-api-v5/schemas/NewsFeed.yaml b/tests/e2e/open-education-api-v5/schemas/NewsFeed.yaml new file mode 100644 index 00000000..20a144a2 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/NewsFeed.yaml @@ -0,0 +1,52 @@ +type: object +description: A placeholder or collection of news items +required: + - newsFeedId + - newsFeedType + - name + - description +properties: + newsFeedId: + type: string + description: Unique id for this news feed + format: uuid + example: 123e4567-e89b-12d3-a456-134564174222 + newsFeedType: + type: string + description: The type of the object this news feed relates to + enum: + - organization + - program + - course + - component + - person + - building + - room + example: room + name: + type: array + description: The name for this news feed + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: room Bb 4.35 news + description: + type: array + description: The description of this news feed. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: all information on what happens in room Bb 4.35 + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/NewsItem.yaml b/tests/e2e/open-education-api-v5/schemas/NewsItem.yaml new file mode 100644 index 00000000..113a46cd --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/NewsItem.yaml @@ -0,0 +1,83 @@ +type: object +description: A newsitem contains the message and metadata of that message +required: + - newsItemId + - name +properties: + newsItemId: + type: string + description: Unique id for this news item + format: uuid + example: 123e4567-e89b-12d3-a456-122564174000 + newsItemType: + $ref: '../enumerations/newsItemType.yaml' + name: + type: array + description: The name for this news item + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Room Bb 4.35 will be un available from 2020-09-29 until 2020-09-30 + authors: + type: array + description: The authors of the article with this news item + items: + type: string + maxLength: 256 + example: ['admin@universiteitvanharderwijk.nl'] + image: + type: string + description: The url containing the address of the image belonging to this news item + format: uri + maxLength: 2048 + example: https://upload.wikimedia.org/wikipedia/commons/4/44/Antu_emblem-unavailable.svg + link: + type: string + description: The url containing the address of the article belonging to this news item + format: uri + maxLength: 2048 + example: https://www.universiteitvanharderwijk.nl/cms/ruimtegebrek + content: + type: array + description: The content of this news item. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: 'The room Bb 4.35 will be under maintenance' + newsFeeds: + description: The newsFeeds where this item can be found. [`expandable`](#tag/news_feed_model) + type: array + items: + oneOf: + - $ref: './Identifier.yaml' + title: newsFeedId + - $ref: './NewsFeed.yaml' + title: NewsFeed + validFrom: + type: string + description: The moment from which this news item is valid, RFC3339 (date-time) + format: date-time + example: 2020-09-28T08:30:00.000Z + validUntil: + type: string + description: The moment until which this news item is valid, RFC3339 (date-time) + format: date-time + example: 2020-09-30T20:00:00.000Z + lastModified: + type: string + description: The moment on which this news item was updated, RFC3339 (date-time) + format: date-time + example: 2020-09-28T00:00:00.000Z + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Offering.yaml b/tests/e2e/open-education-api-v5/schemas/Offering.yaml new file mode 100644 index 00000000..89126b6f --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Offering.yaml @@ -0,0 +1,3 @@ +allOf: + - $ref: '../schemas/OfferingId.yaml' + - $ref: '../schemas/OfferingProperties.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/OfferingId.yaml b/tests/e2e/open-education-api-v5/schemas/OfferingId.yaml new file mode 100644 index 00000000..d2f56481 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/OfferingId.yaml @@ -0,0 +1,11 @@ +type: object +description: ID of Either a program, course or component offering which descrbes the program, course or offering in time +required: + - offeringId +properties: + offeringId: + type: string + description: Unique id of this offering + format: uuid + example: 123e4567-e89b-12d3-a456-134564174000 + readOnly: true diff --git a/tests/e2e/open-education-api-v5/schemas/OfferingIdAndType.yaml b/tests/e2e/open-education-api-v5/schemas/OfferingIdAndType.yaml new file mode 100644 index 00000000..6fb07c98 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/OfferingIdAndType.yaml @@ -0,0 +1,11 @@ +type: object +description: ID and type of Either a program, course or component offering which descrbes the program, course or offering in time +required: + - offeringId +properties: + offeringId: + $ref: '../schemas/OfferingId.yaml' + offeringType: + $ref: '../enumerations/offeringType.yaml' + + diff --git a/tests/e2e/open-education-api-v5/schemas/OfferingProperties.yaml b/tests/e2e/open-education-api-v5/schemas/OfferingProperties.yaml new file mode 100644 index 00000000..2a2842bd --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/OfferingProperties.yaml @@ -0,0 +1,128 @@ +type: object +description: Either a program, course or component offering which descrbes the program, course or offering in time +required: + - primaryCode + - offeringType + - name + - description + - teachingLanguage + - resultExpected +properties: + primaryCode: + description: The primary human readable identifier for this offering. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: offeringCode + code: INFOMQNM-20FS + readOnly: true + offeringType: + type: string + description: The type of this offering + enum: + - program + - course + - component + example: component + academicSession: + $ref: './AcademicSession.yaml' + name: + type: array + description: The name of this offering + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Final written test for INFOMQNM for fall semseter 2020 + abbreviation: + type: string + description: The abbreviation or internal code used to identify this offering + maxLength: 256 + example: Test-INFOMQNM-20FS + description: + type: array + description: The description of this offering. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: | + 'Prove in writing knowledge of research methods, including: + Acquire knowledge of HCI research paradigms + Able to design suitable research studies (e.g., choose between within and between subject designs) + Define/apply/design metrics and scales + Define/produce materials (e.g., stimuli and questionnaires) + Define protocols for research studies + Understands and take in account concepts of reliability and validity + Analyze and improve methods and analysis of published scientific articles + Able to deliver scientific reports + Prove in writing knowledge of ­­­statistics, including: + Handle hypothesis testing with complex designs (e.g., including , dependent, independent, and co variates) + Data preparation (e.g., coding and feature selection) + Reason towards adequate techniques to ensure valid outcomes (e.g., be aware of type I, type II errors) + Select an appropriate sampling method (e.g., stratified) + Perform parametric tests (e.g., repeated measures (M)ANOVA) + Perform non-parametric tests (e.g., Chi-square, Mann-Whitney, and Kruskal-Wallis)' + teachingLanguage: + type: string + description: The (primary) teaching language in which this offering is given, should be a three-letter language code as specified by ISO 639-2. + minLength: 3 + maxLength: 3 + pattern: "^[a-z]{3}$" + example: nld + modeOfDelivery: + $ref: '../enumerations/modesOfDelivery.yaml' + maxNumberStudents: + type: number + description: The maximum number of students allowed to enroll for this offering + format: int32 + minimum: 0 + example: 200 + enrolledNumberStudents: + type: number + description: The number of students that have already enrolled for this offering + format: int32 + minimum: 0 + example: 150 + pendingNumberStudents: + type: number + description: The number of students that have a pending enrollment request for this offering + format: int32 + minimum: 0 + example: 50 + minNumberStudents: + type: number + description: The minimum number of students needed for this offering to proceed + format: int32 + minimum: 0 + example: 15 + resultExpected: + type: boolean + description: | + resultExpected, previously knwon as isLineItem is used so the specific instance of the object is identified as being an element that CAN contain “grade” information. + Offerings do not always have to result in a grade or an other type of result. + If there is a result expected from a programOffering/courseOffering/componentOffering the is resultExpected field should parse true + example: true + resultValueType: + $ref: '../enumerations/resultValueType.yaml' + link: + type: string + description: URL of this offering's webpage. + format: uri + maxLength: 2048 + example: https://osiris.uu.nl/osiris_student_uuprd/OnderwijsCatalogusZoekCursus.do#submitForm?cursuscode=INFOMQNM + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/RIO/V1/examples/Offering.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Organization.yaml b/tests/e2e/open-education-api-v5/schemas/Organization.yaml new file mode 100644 index 00000000..5797f1be --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Organization.yaml @@ -0,0 +1,104 @@ +type: object +description: A description of a group of people working together to achieve a goal +required: + - organizationId + - organizationType + - name + - shortName + - primaryCode +properties: + organizationId: + type: string + description: Unique id of this organization + format: uuid + example: 123e4567-e89b-12d3-a456-123514174000 + readOnly: true + primaryCode: + description: The primary human readable identifier for the organization. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: orgId + code: Org01-Root + readOnly: true + organizationType: + $ref: '../enumerations/organizationType.yaml' + name: + type: array + description: The name of the organization + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: nl-NL + value: Coöperatie SURF U.A. + shortName: + type: string + description: Short name of the organization + maxLength: 256 + example: SURF + description: + type: array + description: Any general description of the organization should clearly mention the type of higher education organization, especially in the case of a binary system. In Dutch; universiteit (university) or hogeschool (university of applied sciences). + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: nl-NL + value: SURF is een coöperatieve vereniging van Nederlandse onderwijs- en onderzoeksinstellingen waarin de leden hun krachten bundelen. De leden zijn eigenaar van SURF. + addresses: + type: array + description: Addresses of this organization + items: + $ref: './Address.yaml' + link: + type: string + description: URL of the organization's website + format: uri + maxLength: 2048 + example: https://surf.nl + logo: + type: string + description: Logo of this organization + format: uri + maxLength: 2048 + example: https://www.surf.nl/themes/surf/logo.svg + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + minItems: 1 + items: + $ref: './IdentifierEntry.yaml' + example: + - codeType: brin + code: 00AA + - codeType: kvk + code: '12345678' + parent: + description: | + The organizational unit which is the parent of this organization. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + children: + type: array + description: | + All the organizational units for which this organization is the parent. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + items: + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Pagination.yaml b/tests/e2e/open-education-api-v5/schemas/Pagination.yaml new file mode 100644 index 00000000..f3650fa6 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Pagination.yaml @@ -0,0 +1,32 @@ +type: object +required: + - pageSize + - pageNumber + - hasPreviousPage + - hasNextPage + - items +properties: + pageSize: + type: integer + format: int32 + description: The number of items per page + example: 10 + pageNumber: + type: integer + format: int32 + description: The current page number + example: 1 + minimum: 1 + hasPreviousPage: + type: boolean + description: Whether there is a previous page + example: false + hasNextPage: + type: boolean + description: Whether there is a previous page + example: true + totalPages: + type: integer + format: int32 + description: Total number of pages + example: 8 diff --git a/tests/e2e/open-education-api-v5/schemas/Person.yaml b/tests/e2e/open-education-api-v5/schemas/Person.yaml new file mode 100644 index 00000000..5647c2e5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Person.yaml @@ -0,0 +1,3 @@ +allOf: + - $ref: '../schemas/PersonId.yaml' + - $ref: '../schemas/PersonProperties.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/PersonId.yaml b/tests/e2e/open-education-api-v5/schemas/PersonId.yaml new file mode 100644 index 00000000..d7ed81a6 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/PersonId.yaml @@ -0,0 +1,11 @@ +type: object +# description: ID of a person that has a relationship with this institution +properties: + personId: + type: string + description: Unique id of this person + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 +required: + - personId + \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/PersonProperties.yaml b/tests/e2e/open-education-api-v5/schemas/PersonProperties.yaml new file mode 100644 index 00000000..400e0929 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/PersonProperties.yaml @@ -0,0 +1,154 @@ +type: object +description: A person that has a relationship with this institution +required: + - givenName + - surname + - displayName + - affiliations + - mail + - primaryCode + - activeEnrollment +properties: + primaryCode: + description: The primary human readable identifier for the person. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: studentNumber + code: 0000000 + # Returned by GET, not used in POST/PUT/PATCH + readOnly: true + givenName: + type: string + description: The first name of this person + maxLength: 256 + example: Maartje + surnamePrefix: + type: string + description: The prefix of the family name of this person + example: van + surname: + type: string + description: The family name of this person + maxLength: 256 + example: Damme + displayName: + type: string + description: The name of this person which will be displayed + maxLength: 256 + example: Maartje van Damme + initials: + type: string + description: The initials of this person + example: MCW + activeEnrollment: + type: boolean + description: Whether this person has an active enrollment. + example: false + dateOfBirth: + type: string + description: The date of birth of this person, RFC3339 (full-date) + format: date + example: '2003-09-30' + cityOfBirth: + type: string + description: The city of birth of this person + example: Utrecht + countryOfBirth: + type: string + description: The country of birth of this person the country code according to [iso-3166-1-alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) + example: NL + nationality: + type: string + description: The nationality of this person the nationality according to https://gist.github.com/zspine/2365808 + example: Dutch + dateOfNationality: + type: string + description: The date of nationality of this person, RFC3339 (full-date) + format: date + example: '2003-09-30' + affiliations: + $ref: '../enumerations/personAffiliations.yaml' + mail: + type: string + description: The primary e-mailaddress of this person + format: email + maxLength: 256 + example: vandamme.mcw@universiteitvanharderwijk.nl + secondaryMail: + type: string + description: The secondary e-mailaddress of this person + format: email + maxLength: 256 + example: poekie@xyz.nl + telephoneNumber: + type: string + description: The telephone number of this person + maxLength: 256 + example: +31 123 456 789 + mobileNumber: + type: string + description: The mobile number of this person + maxLength: 256 + example: +31 612 345 678 + photoSocial: + type: string + description: The url of the informal picture of this person + format: uri + maxLength: 2048 + example: https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Placeholder_female_superhero_c.png/203px-Placeholder_female_superhero_c.png + photoOfficial: + type: string + description: The url of the official picture of this person + format: uri + maxLength: 2048 + example: https://upload.wikimedia.org/wikipedia/commons/6/66/Johannes_Vermeer_%281632-1675%29_-_The_Girl_With_The_Pearl_Earring_%281665%29.jpg + gender: + $ref: '../enumerations/gender.yaml' + titlePrefix: + type: string + description: A title prefix to be used for this person + example: drs + titleSuffix: + type: string + description: A title suffix to be used for this person + example: BSc + office: + type: string + description: The name of the office where this person is located + address: + $ref: './Address.yaml' + ICEName: + type: string + description: Full name of In Case of Emergency contact + maxLength: 256 + example: Janne + ICEPhoneNumber: + type: string + description: Phone number of In Case of Emergency contact + maxLength: 256 + example: +31 623 456 789 + ICERelation: + $ref: '../enumerations/ICERelationType.yaml' + languageOfChoice: + type: array + description: The language(s) of choice for this person, RFC3066 + items: + type: string + example: nl-NL + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + example: + - codeType: nationalIdentityNumber + code: '00000' + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/PostResponse.yaml b/tests/e2e/open-education-api-v5/schemas/PostResponse.yaml new file mode 100644 index 00000000..ca6b7e4a --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/PostResponse.yaml @@ -0,0 +1,18 @@ +type: object +description: A system message as a response to a POST message +required: + - message +properties: + message: + description: information displayed to user + type: array + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Your enrollment was partly succesful, you have been placed on the waitinglist + redirect: + description: URL where additional information can be found e.g. by use of deeplink + type: string + format: uri \ No newline at end of file diff --git a/tests/e2e/open-education-api-v5/schemas/Problem.yaml b/tests/e2e/open-education-api-v5/schemas/Problem.yaml new file mode 100644 index 00000000..f1460c50 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Problem.yaml @@ -0,0 +1,17 @@ +type: object +description: A system message including the error code and an explanation +required: + - status + - title +properties: + status: + type: string + description: The HTTP status code + example: '404' + title: + type: string + description: A short, human-readable summary of the problem type + example: Resource not found + detail: + type: string + description: A human-readable explanation specific to this occurrence of the problem diff --git a/tests/e2e/open-education-api-v5/schemas/Program.yaml b/tests/e2e/open-education-api-v5/schemas/Program.yaml new file mode 100644 index 00000000..d2170d0c --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Program.yaml @@ -0,0 +1,12 @@ +allOf: + - $ref: '../schemas/ProgramId.yaml' + - $ref: '../schemas/ProgramProperties.yaml' + - properties: + validFrom: + description: The first day this program is valid (inclusive). + type: string + format: date + validTo: + description: The day this program ceases to be valid (e.g. exclusive). + type: string + format: date diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramExpanded.yaml new file mode 100644 index 00000000..88f681d7 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramExpanded.yaml @@ -0,0 +1,10 @@ +allOf: + - $ref: './Program.yaml' + - type: object + description: These properties are only present when explicitly included. This allows for creating and displaying structures of programs + properties: + timelineOverrides: + description: Timeline overrides allow an implementation to provide versions of entities that will be valid in the future or have been in the past. + type: array + items: + $ref: './TimelineOverrideProgram.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramId.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramId.yaml new file mode 100644 index 00000000..726364b1 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramId.yaml @@ -0,0 +1,11 @@ +type: object +description: A collection of courses that lead to a certifiable learning outcome +required: + - programId +properties: + programId: + type: string + description: Unique id for this program + format: uuid + example: 123e4567-e89b-12d3-a456-426614174000 + readOnly: true diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramOffering.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramOffering.yaml new file mode 100644 index 00000000..279aeaf5 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramOffering.yaml @@ -0,0 +1,74 @@ +allOf: + - $ref: './Offering.yaml' + - type: object + required: + - modeOfStudy + - startDate + - endDate + properties: + startDate: + type: string + description: The moment on which this offering starts, RFC3339 (full-date) + format: date + example: 2019-08-21 + endDate: + type: string + description: The moment on which this offering ends, RFC3339 (full-date) + format: date + example: 2023-06-15 + enrollStartDate: + type: string + description: The first day on which a student can enroll for this program. + format: date + example: 2019-05-01 + enrollEndDate: + type: string + description: The last day on which a student can enroll for this program. + format: date + example: 2019-08-01 + flexibleEntryPeriodStart: + type: string + description: If this is a program wherein participants can start at various moments, without missing anything, use this attribute in combination with `flexibleEntryPeriodEnd`. + format: date + flexibleEntryPeriodEnd: + type: string + description: If this is a program wherein participants can start at various moments, without missing anything, use this attribute in combination with `flexibleEntryPeriodStart`. + format: date + addresses: + type: array + description: Addresses for this offering + items: + $ref: './Address.yaml' + priceInformation: + type: array + description: Price information for this offering. + items: + $ref: './Cost.yaml' + minItems: 1 + program: + description: | + The Program that is offered in this programoffering. [`expandable`](#tag/program_model) + By default only the `programId` (a string) is returned. If the client requested an expansion of `program` the full program object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: programId + - $ref: './Program.yaml' + title: Program object + organization: + description: | + The organization that manages this programeoffering. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + academicSession: + description: | + The academicsession during which this programoffering takes place. [`expandable`](#tag/academic_session_model) + By default only the `academicSessionId` (a string) is returned. If the client requested an expansion of `academicSession` the full academicsession object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: academicSessionId + - $ref: './AcademicSession.yaml' + title: AcademicSession object diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociation.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociation.yaml new file mode 100644 index 00000000..b750379f --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociation.yaml @@ -0,0 +1,6 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './ProgramResult.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpandable.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpandable.yaml new file mode 100644 index 00000000..5954b7f7 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpandable.yaml @@ -0,0 +1,9 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './ProgramResult.yaml' + person: + $ref: './PersonId.yaml' + diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpanded.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpanded.yaml new file mode 100644 index 00000000..e2e478d1 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramOfferingAssociationExpanded.yaml @@ -0,0 +1,12 @@ +allOf: + - $ref: './Association.yaml' + - type: object + properties: + result: + $ref: './ProgramResult.yaml' + person: + description: The person this association is to + $ref: './Person.yaml' + offering: + description: The offering this association is for + $ref: './Offering.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramProperties.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramProperties.yaml new file mode 100644 index 00000000..879efd4b --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramProperties.yaml @@ -0,0 +1,195 @@ +type: object +description: A collection of courses that lead to a certifiable learning outcome +required: + - programType + - name + - abbreviation + - description + - primaryCode + - teachingLanguage +properties: + primaryCode: + description: The primary human readable identifier for the program. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: programCode + code: BIO + readOnly: true + programType: + $ref: '../enumerations/programType.yaml' + name: + description: The name of this program + type: array + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Biology + abbreviation: + type: string + description: The abbreviation of this program + maxLength: 256 + example: BIO + description: + type: array + description: The description of this program + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: The study of life + teachingLanguage: + type: string + description: The (primary) teaching language in which this program is given, should be a three-letter language code as specified by ISO 639-2. + minLength: 3 + maxLength: 3 + pattern: "^[a-z]{3}$" + example: nld + studyLoad: + $ref: './StudyLoadDescriptor.yaml' + qualificationAwarded: + $ref: '../enumerations/qualificationAwarded.yaml' + modeOfStudy: + $ref: '../enumerations/modeOfStudy.yaml' + modeOfDelivery: + $ref: '../enumerations/modesOfDelivery.yaml' + duration: + type: string + description: The duration of this program. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339. + pattern: '^(-?)P(?=\d|T\d)(?:(\d+)Y)?(?:(\d+)M)?(?:(\d+)([DW]))?(?:T(?:(\d+)H)?(?:(\d+)M)?(?:(\d+(?:\.\d+)?)S)?)?$' + example: P1DT30H4S + firstStartDate: + type: string + description: The date when participants can follow this program for the first time. + format: date + levelOfQualification: + $ref: '../enumerations/levelOfQualification.yaml' + level: + $ref: '../enumerations/level.yaml' + sector: + $ref: '../enumerations/sector.yaml' + fieldsOfStudy: + type: string + description: Field(s) of study (e.g. ISCED-F) (http://uis.unesco.org/sites/default/files/documents/isced-fields-of-education-and-training-2013-en.pdf. + maxLength: 4 + example: '0732' + enrollment: + type: array + items: + $ref: './LanguageTypedString.yaml' + description: The extra information that is provided for enrollment + example: + - language: en-GB + value: enrollment through SIS. [The limited implementation of Git Hub Markdown syntax](#tag/formatting-and-displaying-results-from-API) MAY be used for rich text representation. + resources: + type: array + description: An overview of the literature and other resources that is used in this course (ECTS-recommended reading and other sources) + items: + type: string + example: ['book to be announced', 'on-line resource x'] + learningOutcomes: + type: array + description: List of learning outcomes at program level. It is advisable to limit the number of learning outcomes to approximately 20. It is also advisable to make sure that the program learning outcomes in the course catalogue correspond with those on the Diploma Supplement. + items: + type: array + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: 'Executable knowledge of research methods, including: Acquire knowledge of HCI research paradigms.' + assessment: + type: array + description: A description of the way exams for this course are taken (ECTS-assessment method and criteria). + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Exam on campus + admissionRequirements: + type: array + description: This information may be given at an institutional level and/or at the level of individual programmes. Make sure that it is clear whether the information applies to fee-paying students (national and/or international) or to exchange students. + example: + - language: en-GB + value: Students need to be enrolled at qualifying institutions of higher education that participate in this alliance + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + qualificationRequirements: + type: array + description: Normally, students will receive a diploma when they have completed the (official) study program and have obtained the required number of credits. If there are any other specific requirements that students need to have fulfilled, mention them here. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + link: + type: string + description: URL of the program's website + format: uri + maxLength: 2048 + example: https://bijvak.nl + educationSpecification: + description: The educationSpecification of which this program is a more concrete implementation. [`expandable`](#tag/education_specification_model) + oneOf: + - $ref: './Identifier.yaml' + title: educationSpecificationId + - $ref: './EducationSpecification.yaml' + title: EducationSpecification + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + example: + - codeType: crohoCreboCode + code: '59312' + addresses: + type: array + description: Addresses for this program + items: + $ref: './Address.yaml' + parent: + description: Parent program of which the current program is a child. This object is [`expandable`](#tag/program_model) + oneOf: + - $ref: './Identifier.yaml' + title: programId + - $ref: './Program.yaml' + title: Expanded Program + children: + type: array + description: Programs which are a part of this program (e.g specializations). This object is [`expandable`](#tag/program_model) + items: + oneOf: + - $ref: './Identifier.yaml' + title: programId + - $ref: './Program.yaml' + title: Expanded Program + coordinators: + description: The person(s) responsible for this program. This object is [`expandable`](#tag/person_model) + type: array + items: + oneOf: + - $ref: './Identifier.yaml' + title: personId + - $ref: './Person.yaml' + title: Person object + organization: + description: | + The organization providing this program. [`expandable`](#tag/organization_model) + By default only the `organizationId` (a string) is returned. If the client requested an expansion of `organization` the full organization object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: organizationId + - $ref: './Organization.yaml' + title: Organization object + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/RIO/V1/examples/Program.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/ProgramResult.yaml b/tests/e2e/open-education-api-v5/schemas/ProgramResult.yaml new file mode 100644 index 00000000..a3f169e9 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/ProgramResult.yaml @@ -0,0 +1,8 @@ +allOf: + - $ref: './Result.yaml' + - type: object + required: + - studyLoad + properties: + studyLoad: + $ref: './StudyLoadDescriptor.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Result.yaml b/tests/e2e/open-education-api-v5/schemas/Result.yaml new file mode 100644 index 00000000..0e905e37 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Result.yaml @@ -0,0 +1,25 @@ +type: object +description: A result as part of an association +required: + - state + - resultDate +properties: + state: + $ref: '../enumerations/resultState.yaml' +# added state based on request by CACI + pass: + $ref: '../enumerations/passState.yaml' + comment: + type: string + description: The comment on this result + score: + type: string + description: The score of this program/course/component association (based on resultValueType in offering) + example: '9' + resultDate: + type: string + description: The date this result has been published, RFC3339 (full-date) + format: date + example: 2020-09-28 + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Room.yaml b/tests/e2e/open-education-api-v5/schemas/Room.yaml new file mode 100644 index 00000000..d90382a1 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Room.yaml @@ -0,0 +1,100 @@ +type: object +description: An area within a building where education can take place +required: + - roomId + - roomType + - name + - primaryCode +properties: + roomId: + type: string + description: Unique id for this room + format: uuid + example: 123e4567-e89b-12d3-a456-332114174000 + primaryCode: + description: The primary human readable identifier for the room. This is often the source identifier as defined by the institution. + $ref: './IdentifierEntry.yaml' + example: + codeType: roomCode + code: Bb4.54 + roomType: + $ref: '../enumerations/roomType.yaml' + abbreviation: + type: string + description: The abbreviation of the name of this room + maxLength: 256 + example: Bb4.54 + name: + type: array + description: The name of this room + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: Beatrix building room 4.54 + description: + type: array + description: The description of this room. [The limited implementation of Git Hub Markdown syntax](#tag/formatting-and-displaying-results-from-API) MAY be used for rich text representation. + minItems: 1 + items: + $ref: './LanguageTypedString.yaml' + example: + - language: en-GB + value: External education and exam room 4.54 + totalSeats: + type: integer + format: int32 + description: The total number of seats located in the room + example: 300 + availableSeats: + type: integer + format: int32 + description: The total number of available (=non-reserved) seats in the room + example: 200 + floor: + type: string + description: The floor on which this room is located + example: '4' + wing: + type: string + description: The wing in which this room is located + example: None + geolocation: + type: object + description: Geolocation of the entrance of this room (WGS84 coordinate reference system) + required: + - latitude + - longitude + properties: + latitude: + type: number + format: double + example: 52.088255 + longitude: + type: number + format: double + example: 5.106669 + otherCodes: + type: array + description: An array of additional human readable codes/identifiers for the entity being described. + items: + $ref: './IdentifierEntry.yaml' + building: + description: | + The building in which the room is located. [`expandable`](#tag/building_model) + By default only the `buildingId` (a string) is returned. If the client requested an expansion of `building` the full building object should be returned. + oneOf: + - $ref: './Identifier.yaml' + title: buildingId + - $ref: './Building.yaml' + title: Building object + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/Service.yaml b/tests/e2e/open-education-api-v5/schemas/Service.yaml new file mode 100644 index 00000000..4eee321e --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/Service.yaml @@ -0,0 +1,34 @@ +type: object +description: A metadataset providing details on the provider of this OOAPI implementation +required: + - contactEmail + - specification + - documentation +properties: + contactEmail: + type: string + description: Contact e-mail address of the service owner + format: email + maxLength: 256 + example: admin@universiteitvanharderwijk.nl + specification: + type: string + description: URL of the API specification (YAML or JSON, compliant with [Open API Specification v3](https://github.com/OAI/OpenAPI-Specification/)) + format: uri + maxLength: 2048 + example: https://rawgit.com/open-education-api/specification/v3/docs.html#tag/course-offerings/paths/~1course-offerings/get + documentation: + type: string + description: URL of the API documentation, including general terms and privacy statement + format: uri + maxLength: 2048 + example: https://open-education-api.github.io/specification/v4/docs.html + consumers: + description: The additional consumer elements that can be provided, see the [documentation on support for specific consumers](https://open-education-api.github.io/specification/#/consumers) for more information about this mechanism. + type: array + items: + $ref: './Consumer.yaml' + example: + $ref: '../consumers/TEST/V1/examples/TestConsumer.yaml' + ext: + $ref: './Ext.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/StudyLoadDescriptor.yaml b/tests/e2e/open-education-api-v5/schemas/StudyLoadDescriptor.yaml new file mode 100644 index 00000000..3bbc5a86 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/StudyLoadDescriptor.yaml @@ -0,0 +1,26 @@ +type: object +description: The amount of effort to complete this education in the specified unit. +properties: + studyLoadUnit: + description: | + The unit in which the studyload is specfied + - contacttime: CONTACTUUR amount of time spent in classes + - ects: ECTS_PUNT European Credit Transfer System + - sbu: SBU studentloadhours + - sp: STUDIEPUNT studentpoints + - hour: UUR hours + type: string + enum: + - contacttime + - ects + - sbu + - sp + - hour + example: ects + value: + description: The amount of load depicted in numbers + type: number + example: 3 +example: + studyLoadUnit: ects + value: 3 diff --git a/tests/e2e/open-education-api-v5/schemas/TimelineOverrideCourse.yaml b/tests/e2e/open-education-api-v5/schemas/TimelineOverrideCourse.yaml new file mode 100644 index 00000000..3c99d457 --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/TimelineOverrideCourse.yaml @@ -0,0 +1,18 @@ +type: object +required: + - validFrom + - course +description: A timeline override of the course. +properties: + validFrom: + type: string + description: The day on which this timelineOverride starts (inclusive), RFC3339 (date) + format: date + example: '2021-09-01' + validTo: + type: string + description: The day on which this timelineOverride ends (exclusive), RFC3339 (date) + format: date + example: '2022-08-31' + course: + $ref: './CourseProperties.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/TimelineOverrideEducationSpecification.yaml b/tests/e2e/open-education-api-v5/schemas/TimelineOverrideEducationSpecification.yaml new file mode 100644 index 00000000..b332943a --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/TimelineOverrideEducationSpecification.yaml @@ -0,0 +1,18 @@ +type: object +description: A timeline override of the EducationSpecification. +required: + - validFrom + - educationSpecification +properties: + validFrom: + type: string + description: The day on which this timelineOverride starts (inclusive), RFC3339 (date) + format: date + example: '2021-09-01' + validTo: + type: string + description: The day on which this timelineOverride ends (exclusive), RFC3339 (date) + format: date + example: '2022-08-31' + educationSpecification: + $ref: './EducationSpecificationProperties.yaml' diff --git a/tests/e2e/open-education-api-v5/schemas/TimelineOverrideProgram.yaml b/tests/e2e/open-education-api-v5/schemas/TimelineOverrideProgram.yaml new file mode 100644 index 00000000..85678f6a --- /dev/null +++ b/tests/e2e/open-education-api-v5/schemas/TimelineOverrideProgram.yaml @@ -0,0 +1,18 @@ +type: object +description: A time-line override of the program. +required: + - validFrom + - program +properties: + validFrom: + type: string + description: The day on which this timelineOverride starts (inclusive), RFC3339 (date) + format: date + example: '2021-09-01' + validTo: + type: string + description: The day on which this timelineOverride ends (exclusive), RFC3339 (date) + format: date + example: '2022-08-31' + program: + $ref: './ProgramProperties.yaml' diff --git a/tests/e2e/open-education-api-v5/spec.yaml b/tests/e2e/open-education-api-v5/spec.yaml new file mode 100644 index 00000000..36821de4 --- /dev/null +++ b/tests/e2e/open-education-api-v5/spec.yaml @@ -0,0 +1,355 @@ +openapi: "3.0.3" +info: + version: "5.0.0" + title: Open Education API + description: | + OpenAPI (fka Swagger) specification for the Open Education API. + +
+ + OOAPI information model that feeds OOAPI specification + +
OOAPI information model that feeds OOAPI specification (click to enlage)
+
+ + The model provides an overview of how the objects on which the API is specified are related. The overarching concept educations is not found in the in the end points of the API. The smaller concepts of programOffering, courseOffering and conceptOffering are all found in the offering endpoint. The different types of association can all be found in the association endpoint. + + The original file for this model can be found here + + The program relations object is not found as a separate endpoint but relations between programs can be found within the program endpoint by expanding that endpoint. + + Information about earlier meetings and presentations can be found here + + Information on the EDU-API model that was also used for this api is shown here + + + + x-logo: + url: ../logo.png + +servers: + - url: http://demo01.eduapi.nl/v5 + description: SURF demo implementation + +tags: + - name: service metadata + description: The service API provides additional metadata needed to make the OOAPI fit for this organization. + - name: academic sessions + description: The academic sessions API provides information about the different time periods a program can be offered. + - name: associations + description: | + The associations API provides information about the association between an offering and a person (e.g. students, lecturers, etc). + Associations can be posted between institutions This requires information details on the offering and the persons. + To allow for this information a complete person object and offering object can be part of the API. + The structure is explained in the following model: + + + + + + + + + + + + + + + + + + + + + +
offering
studentexternal
internalPOST /associations/external/me gets student details from .wellknown at home institution. It passes offering details (provided by external institution) to the home institution so the home institution can create a placeholder for the offering and its results. +
externalno support needed
+ Direct update of current information: PATCH /associations/{associationId} + This call is currently limited to passing results and a remote state. For future use other association resource information could be passed. + More information on the support for student mobility can be found + here + + - name: buildings + description: The building API provides a building that is currently used by the organization. Including all location details. + - name: courses + description: The courses API provides a self-contained and formally structured learning experience. Aimed at providing learning outcomes to students. Usually placed in the context of a program. + - name: components + description: The components API provides information about components being part of parent courses. + - name: education specifications + description: | + The education specification API provides information on the specification of an education object. + This specification allows for other education objects to be derived from it. + It is used to aggregate education objects from a supplying institution. + It clusters programs to a main educationSpecification that is used in registries such as RIO. + - name: groups + description: The groups API provides information about groups that are related to organizations, persons and offerings. Groups of students that are related to an offering are typically used for rostering. The rostering application assigns students based on these groups. For example, class 1b will be assigned to the course offering on monday morning. Not all groups are related to an offering. A group of people can also be a team that is working on a task outside the OOAPI scope. These can be teams of students, but also teams of employees. + - name: news + description: The news API provides news feeds and items regarding a specific subject. + - name: offerings + description: The offerings API provides information about offerings which have a global timeframe, e.g. a period to which students can enroll. + - name: organizations + description: The organizations API provides the organizations that are responsible for the execution and recognition of education. + - name: persons + description: The persons API provides information about persons related to an organization. + - name: programs + description: The programs API provides a coherent set of educational components, aimed at the realization of competences or objectives in the field of knowledge, insight, attitudes and skills that the person who completes the program must have. + - name: rooms + description: The rooms API provides the part of a building where an activity can take place. Including detail information on the resources available, number of seats, etc. (Updated continuously) + + - name: service_model + x-displayName: Service + description: | + + - name: education_specification_model + x-displayName: EducationSpecification + description: | + + - name: program_model + x-displayName: Program + description: | + + - name: course_model + x-displayName: Course + description: | + + - name: component_model + x-displayName: Component + description: | + + - name: program_offering_model + x-displayName: ProgramOffering + description: | + + - name: course_offering_model + x-displayName: CourseOffering + description: | + + - name: component_offering_model + x-displayName: ComponentOffering + description: | + + - name: association_model + x-displayName: Association + description: | + + - name: person_model + x-displayName: Person + description: | + + - name: group_model + x-displayName: Group + description: | + + - name: academic_session_model + x-displayName: AcademicSession + description: | + + - name: organization_model + x-displayName: Organization + description: | + + - name: building_model + x-displayName: Building + description: | + + - name: room_model + x-displayName: Room + description: | + + - name: news_feed_model + x-displayName: NewsFeed + description: | + + - name: news_item_model + x-displayName: NewsItem + description: | + + +x-tagGroups: + - name: Requests and respones + tags: + - service metadata + - academic sessions + - associations + - buildings + - courses + - components + - education specifications + - groups + - news + - offerings + - organizations + - persons + - programs + - rooms + - name: Models + tags: + - service_model + - academic_session_model + - association_model + - building_model + - component_model + - component_offering_model + - course_model + - course_offering_model + - education_specification_model + - group_model + - news_feed_model + - news_item_model + - organization_model + - person_model + - program_model + - program_offering_model + - room_model + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + openId: + type: openIdConnect + openIdConnectUrl: https://example.nl/.well-known/openid-configuration + schemas: + # allOf: + # - $ref: 'schemas/Service.yaml' + # - $ref: schemas/AcademicSession.yaml + # - $ref: schemas/Building.yaml + # - $ref: schemas/Component.yaml + # - $ref: schemas/ComponentOffering.yaml + # - $ref: schemas/Course.yaml + # - $ref: schemas/CourseOffering.yaml + # - $ref: schemas/EducationSpecification.yaml + # - $ref: schemas/Group.yaml + # - $ref: schemas/NewsFeed.yaml + # - $ref: schemas/NewsItem.yaml + # - $ref: schemas/Organization.yaml + # - $ref: schemas/Person.yaml + # - $ref: schemas/Program.yaml + # - $ref: schemas/ProgramOffering.yaml + # - $ref: schemas/Room.yaml + # - $ref: schemas/AssociationFull.yaml + +paths: + /: + $ref: paths/Service.yaml + /persons: + $ref: paths/PersonCollection.yaml + /persons/me: + $ref: paths/PersonMe.yaml + /persons/{personId}: + $ref: paths/PersonInstance.yaml + /persons/{personId}/associations: + $ref: paths/PersonAssociationCollection.yaml + /persons/{personId}/groups: + $ref: paths/PersonGroupCollection.yaml + /organizations: + $ref: paths/OrganizationCollection.yaml + /organizations/{organizationId}: + $ref: paths/OrganizationInstance.yaml + /organizations/{organizationId}/programs: + $ref: paths/OrganizationProgramCollection.yaml + /organizations/{organizationId}/courses: + $ref: paths/OrganizationCourseCollection.yaml + /organizations/{organizationId}/components: + $ref: paths/OrganizationComponentCollection.yaml + /organizations/{organizationId}/offerings: + $ref: paths/OrganizationOfferingCollection.yaml + /organizations/{organizationId}/groups: + $ref: paths/OrganizationGroupCollection.yaml + /organizations/{organizationId}/education-specifications: + $ref: paths/OrganizationEducationSpecificationCollection.yaml + /academic-sessions: + $ref: paths/AcademicSessionCollection.yaml + /academic-sessions/{academicSessionId}: + $ref: paths/AcademicSessionInstance.yaml + /academic-sessions/{academicSessionId}/offerings: + $ref: paths/AcademicSessionOfferingCollection.yaml + /programs: + $ref: paths/ProgramCollection.yaml + /programs/{programId}: + $ref: paths/ProgramInstance.yaml + /programs/{programId}/programs: + $ref: paths/ProgramProgramCollection.yaml + /programs/{programId}/courses: + $ref: paths/ProgramCourseCollection.yaml + /programs/{programId}/offerings: + $ref: paths/ProgramOfferingCollection.yaml + /courses: + $ref: paths/CourseCollection.yaml + /courses/{courseId}: + $ref: paths/CourseInstance.yaml + /courses/{courseId}/components: + $ref: paths/CourseComponentCollection.yaml + /courses/{courseId}/offerings: + $ref: paths/CourseOfferingCollection.yaml + /components/{componentId}: + $ref: paths/ComponentInstance.yaml + /components/{componentId}/offerings: + $ref: paths/ComponentOfferingCollection.yaml + /offerings/{offeringId}: + $ref: paths/OfferingInstance.yaml + /offerings/{offeringId}/associations: + $ref: paths/OfferingAssociationCollection.yaml + # /offerings/{offeringId}/associations/me: + # $ref: paths/OfferingAssociationInstanceMe.yaml + /offerings/{offeringId}/groups: + $ref: paths/OfferingGroupCollection.yaml + /associations/{associationId}: + $ref: paths/AssociationInstance.yaml + # /associations/me: + # $ref: paths/AssociationInstanceMe.yaml + /associations/external/me: + $ref: paths/AssociationInstanceExternalMe.yaml + /buildings: + $ref: paths/BuildingCollection.yaml + /buildings/{buildingId}: + $ref: paths/BuildingInstance.yaml + /buildings/{buildingId}/rooms: + $ref: paths/BuildingRoomCollection.yaml + /rooms: + $ref: paths/RoomCollection.yaml + /rooms/{roomId}: + $ref: paths/RoomInstance.yaml + /news-feeds: + $ref: paths/NewsFeedCollection.yaml + /news-feeds/{newsFeedId}: + $ref: paths/NewsFeedInstance.yaml + /news-feeds/{newsFeedId}/news-items: + $ref: paths/NewsFeedItemCollection.yaml + /news-items/{newsItemId}: + $ref: paths/NewsItemInstance.yaml + /education-specifications: + $ref: paths/EducationSpecificationCollection.yaml + /education-specifications/{educationSpecificationId}: + $ref: paths/EducationSpecificationInstance.yaml + /education-specifications/{educationSpecificationId}/education-specifications: + $ref: paths/EducationSpecificationEducationSpecificationCollection.yaml + /education-specifications/{educationSpecificationId}/courses: + $ref: paths/EducationSpecificationCourseCollection.yaml + /education-specifications/{educationSpecificationId}/programs: + $ref: paths/EducationSpecificationProgramCollection.yaml + /groups: + $ref: paths/GroupCollection.yaml + /groups/{groupId}: + $ref: paths/GroupInstance.yaml + /groups/{groupId}/persons: + $ref: paths/GroupPersonCollection.yaml diff --git a/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php b/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php new file mode 100644 index 00000000..9384ed84 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php @@ -0,0 +1,270 @@ +id; + } + + public function getAcademicSessionId(): AcademicSession + { + return $this->academicSessionId; + } + + public function setAcademicSessionType(string $academicSessionType): void + { + $this->academicSessionType = $academicSessionType; + } + + public function getAcademicSessionType(): string + { + return $this->academicSessionType; + } + + public function setPrimaryCode(string $primaryCode): void + { + $this->primaryCode = $primaryCode; + } + + public function getPrimaryCode(): string + { + return $this->primaryCode; + } + + public function addName(string $name): void + { + $this->name[] = $name; + } + + public function removeName(string $name): void + { + if (false !== $key = array_search($name, $this->name, true)) { + unset($this->name[$key]); + } + } + + public function getName(): array + { + return $this->name; + } + + public function setStartDate(\DateTimeInterface $startDate): void + { + $this->startDate = $startDate; + } + + public function getStartDate(): \DateTimeInterface + { + return $this->startDate; + } + + public function setEndDate(\DateTimeInterface $endDate): void + { + $this->endDate = $endDate; + } + + public function getEndDate(): \DateTimeInterface + { + return $this->endDate; + } + + public function setParent(string $parent): void + { + $this->parent = $parent; + } + + public function getParent(): string + { + return $this->parent; + } + + public function addChild(string $child): void + { + $this->children[] = $child; + } + + public function removeChild(string $child): void + { + if (false !== $key = array_search($child, $this->children, true)) { + unset($this->children[$key]); + } + } + + /** + * @return (uuid|object)[] + */ + public function getChildren(): array + { + return $this->children; + } + + public function setYear(string $year): void + { + $this->year = $year; + } + + public function getYear(): string + { + return $this->year; + } + + public function addOtherCod(string $otherCod): void + { + $this->otherCodes[] = $otherCod; + } + + public function removeOtherCod(string $otherCod): void + { + if (false !== $key = array_search($otherCod, $this->otherCodes, true)) { + unset($this->otherCodes[$key]); + } + } + + public function getOtherCodes(): array + { + return $this->otherCodes; + } + + public function addConsumer(string $consumer): void + { + $this->consumers[] = $consumer; + } + + public function removeConsumer(string $consumer): void + { + if (false !== $key = array_search($consumer, $this->consumers, true)) { + unset($this->consumers[$key]); + } + } + + public function getConsumers(): array + { + return $this->consumers; + } + + public function setExt(string $ext): void + { + $this->ext = $ext; + } + + public function getExt(): string + { + return $this->ext; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/Association.php b/tests/e2e/original/App/OpenApi/Entity/Association.php new file mode 100644 index 00000000..c1c52a39 --- /dev/null +++ b/tests/e2e/original/App/OpenApi/Entity/Association.php @@ -0,0 +1,192 @@ +id; + } + + public function getAssociationId(): Association + { + return $this->associationId; + } + + public function getAssociationType(): string + { + return $this->associationType; + } + + public function setRole(string $role): void + { + $this->role = $role; + } + + public function getRole(): string + { + return $this->role; + } + + public function setState(string $state): void + { + $this->state = $state; + } + + public function getState(): string + { + return $this->state; + } + + public function setRemoteState(string $remoteState): void + { + $this->remoteState = $remoteState; + } + + public function getRemoteState(): string + { + return $this->remoteState; + } + + public function addConsumer(string $consumer): void + { + $this->consumers[] = $consumer; + } + + public function removeConsumer(string $consumer): void + { + if (false !== $key = array_search($consumer, $this->consumers, true)) { + unset($this->consumers[$key]); + } + } + + public function getConsumers(): array + { + return $this->consumers; + } + + public function setExt(string $ext): void + { + $this->ext = $ext; + } + + public function getExt(): string + { + return $this->ext; + } + + public function setResult(string $result): void + { + $this->result = $result; + } + + public function getResult(): string + { + return $this->result; + } + + public function getPerson(): Person + { + return $this->person; + } + + public function setOffering(Offering $offering): void + { + $this->offering = $offering; + } + + public function getOffering(): Offering + { + return $this->offering; + } +} diff --git a/tests/e2e/original/App/OpenApi/Entity/Pet.php b/tests/e2e/original/App/OpenApi/Entity/Pet.php index 705897cc..e7b46b7b 100644 --- a/tests/e2e/original/App/OpenApi/Entity/Pet.php +++ b/tests/e2e/original/App/OpenApi/Entity/Pet.php @@ -33,13 +33,12 @@ class Pet /** * @var string[] */ + #[ORM\Column(type: 'json')] #[ApiProperty] #[Assert\NotNull] private array $photoUrls = []; - /** - * @var string[] - */ + #[ORM\Column(type: 'json')] #[ApiProperty] #[Assert\NotNull] private array $tags = []; @@ -110,9 +109,6 @@ public function removeTag(string $tag): void } } - /** - * @return string[] - */ public function getTags(): array { return $this->tags; diff --git a/tests/e2e/schema_open_education_api.yml b/tests/e2e/schema_open_education_api.yml new file mode 100644 index 00000000..2dc75f83 --- /dev/null +++ b/tests/e2e/schema_open_education_api.yml @@ -0,0 +1,7 @@ +namespaces: + entity: App\OpenApi\Entity + enum: App\OpenApi\Enum + interface: App\OpenApi\Model + +openApi: + file: './open-education-api-v5/spec.yaml' From 8b66b379ff1166c98824ff72237cbebd6c2c0256 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 13 Dec 2022 18:05:12 +0100 Subject: [PATCH 237/258] ci: use box 4.2.0 --- .github/workflows/ci.yml | 2 +- .github/workflows/release.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 47ac4d71..90da1a07 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,7 +44,7 @@ jobs: - name: Install prerequisites run: | - wget -O box.phar https://github.com/humbug/box/releases/download/4.0.2/box.phar + wget -O box.phar https://github.com/humbug/box/releases/download/4.2.0/box.phar echo "BOX_BIN=$(pwd)/box.phar" >> $GITHUB_ENV sudo chown -R $(whoami):$(whoami) . diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 3a98fd1d..949ee0b4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -27,7 +27,7 @@ jobs: run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Download box.phar - run: wget -O box.phar https://github.com/humbug/box/releases/download/4.0.2/box.phar + run: wget -O box.phar https://github.com/humbug/box/releases/download/4.2.0/box.phar - name: Compile project run: php ./box.phar compile From 2f7098733d9d111d171730a1f412068db738d272 Mon Sep 17 00:00:00 2001 From: Alan Poulain Date: Tue, 3 Jan 2023 11:16:29 +0100 Subject: [PATCH 238/258] chore: bump deps (#402) --- composer.json | 2 +- composer.lock | 564 ++++++++++++++++++++++++++------------------------ 2 files changed, 291 insertions(+), 275 deletions(-) diff --git a/composer.json b/composer.json index 83b530e6..8c7cbc23 100644 --- a/composer.json +++ b/composer.json @@ -45,7 +45,7 @@ "symfony/filesystem": "^5.2 || ^6.0", "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0", - "nette/utils": "^3.1 || ^4.0-dev", + "nette/utils": "^3.1", "nikic/php-parser": "^4.13", "cebe/php-openapi": "^1.6", "symfony/string": "^5.2 || ^6.0" diff --git a/composer.lock b/composer.lock index 1e9fb6ec..2c3cdcb3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "e015c44d59c43f760d99f9c278ce5c96", + "content-hash": "2551b877faadb75da63c885587caf20d", "packages": [ { "name": "cebe/php-openapi", @@ -295,32 +295,35 @@ }, { "name": "doctrine/annotations", - "version": "1.13.3", + "version": "1.14.2", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0" + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/648b0343343565c4a056bfc8392201385e8d89f0", - "reference": "648b0343343565c4a056bfc8392201385e8d89f0", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", + "doctrine/lexer": "^1 || ^2", "ext-tokenizer": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^1.4.10 || ^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.0 || ^9.1.5", - "symfony/cache": "^4.4 || ^5.2", + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "symfony/cache": "^4.4 || ^5.4 || ^6", "vimeo/psalm": "^4.10" }, + "suggest": { + "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" + }, "type": "library", "autoload": { "psr-4": { @@ -362,9 +365,52 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.13.3" + "source": "https://github.com/doctrine/annotations/tree/1.14.2" }, - "time": "2022-07-02T10:48:51+00:00" + "time": "2022-12-15T06:48:22+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "v1.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "shasum": "" + }, + "require": { + "php": "^7.1|^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpunit/phpunit": "^7.5|^8.5|^9.5", + "psr/log": "^1|^2|^3" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + }, + "time": "2022-05-02T15:47:09+00:00" }, { "name": "doctrine/inflector", @@ -459,31 +505,33 @@ }, { "name": "doctrine/lexer", - "version": "1.2.3", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229" + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/c268e882d4dbdd85e36e4ad69e02dc284f89d229", - "reference": "c268e882d4dbdd85e36e4ad69e02dc284f89d229", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.0", "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9.0", + "doctrine/coding-standard": "^9 || ^10", "phpstan/phpstan": "^1.3", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.11" + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" + "Doctrine\\Common\\Lexer\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -515,7 +563,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/1.2.3" + "source": "https://github.com/doctrine/lexer/tree/2.1.0" }, "funding": [ { @@ -531,20 +579,20 @@ "type": "tidelift" } ], - "time": "2022-02-28T11:07:21+00:00" + "time": "2022-12-14T08:49:07+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.13.0", + "version": "v3.13.2", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1" + "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/a6232229a8309e8811dc751c28b91cb34b2943e1", - "reference": "a6232229a8309e8811dc751c28b91cb34b2943e1", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3952f08a81bd3b1b15e11c3de0b6bf037faa8496", + "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496", "shasum": "" }, "require": { @@ -612,7 +660,7 @@ "description": "A tool to automatically fix PHP code style", "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.2" }, "funding": [ { @@ -620,7 +668,7 @@ "type": "github" } ], - "time": "2022-10-31T19:28:50+00:00" + "time": "2023-01-02T23:53:50+00:00" }, { "name": "justinrainbow/json-schema", @@ -851,28 +899,28 @@ }, { "name": "nette/utils", - "version": "dev-master", + "version": "v3.2.8", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "7c2a4deaf2ebf54315fdb204911534f97cb19d18" + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/7c2a4deaf2ebf54315fdb204911534f97cb19d18", - "reference": "7c2a4deaf2ebf54315fdb204911534f97cb19d18", + "url": "https://api.github.com/repos/nette/utils/zipball/02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", "shasum": "" }, "require": { - "php": ">=8.0 <8.3" + "php": ">=7.2 <8.3" }, "conflict": { "nette/di": "<3.0.6" }, "require-dev": { - "nette/tester": "^2.4", + "nette/tester": "~2.0", "phpstan/phpstan": "^1.0", - "tracy/tracy": "^2.8" + "tracy/tracy": "^2.3" }, "suggest": { "ext-gd": "to use Image", @@ -883,11 +931,10 @@ "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", "ext-xml": "to use Strings::length() etc. when mbstring is not available" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "3.2-dev" } }, "autoload": { @@ -931,9 +978,9 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/master" + "source": "https://github.com/nette/utils/tree/v3.2.8" }, - "time": "2022-12-04T22:52:36+00:00" + "time": "2022-09-12T23:36:20+00:00" }, { "name": "nikic/php-parser", @@ -1417,16 +1464,16 @@ }, { "name": "symfony/console", - "version": "v6.2.1", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "58f6cef5dc5f641b7bbdbf8b32b44cc926c35f3f" + "reference": "0f579613e771dba2dbb8211c382342a641f5da06" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/58f6cef5dc5f641b7bbdbf8b32b44cc926c35f3f", - "reference": "58f6cef5dc5f641b7bbdbf8b32b44cc926c35f3f", + "url": "https://api.github.com/repos/symfony/console/zipball/0f579613e771dba2dbb8211c382342a641f5da06", + "reference": "0f579613e771dba2dbb8211c382342a641f5da06", "shasum": "" }, "require": { @@ -1493,7 +1540,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.2.1" + "source": "https://github.com/symfony/console/tree/v6.2.3" }, "funding": [ { @@ -1509,7 +1556,7 @@ "type": "tidelift" } ], - "time": "2022-12-01T13:44:20+00:00" + "time": "2022-12-28T14:26:22+00:00" }, { "name": "symfony/deprecation-contracts", @@ -1580,16 +1627,16 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.2.0", + "version": "v6.2.2", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "9efb1618fabee89515fe031314e8ed5625f85a53" + "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/9efb1618fabee89515fe031314e8ed5625f85a53", - "reference": "9efb1618fabee89515fe031314e8ed5625f85a53", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ffeb31139b49bf6ef0bc09d1db95eac053388d1", + "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1", "shasum": "" }, "require": { @@ -1643,7 +1690,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.2" }, "funding": [ { @@ -1659,7 +1706,7 @@ "type": "tidelift" } ], - "time": "2022-11-02T09:08:04+00:00" + "time": "2022-12-14T16:11:27+00:00" }, { "name": "symfony/event-dispatcher-contracts", @@ -1805,16 +1852,16 @@ }, { "name": "symfony/finder", - "version": "v6.2.0", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "eb2355f69519e4ef33f1835bca4c935f5d42e570" + "reference": "81eefbddfde282ee33b437ba5e13d7753211ae8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/eb2355f69519e4ef33f1835bca4c935f5d42e570", - "reference": "eb2355f69519e4ef33f1835bca4c935f5d42e570", + "url": "https://api.github.com/repos/symfony/finder/zipball/81eefbddfde282ee33b437ba5e13d7753211ae8e", + "reference": "81eefbddfde282ee33b437ba5e13d7753211ae8e", "shasum": "" }, "require": { @@ -1849,7 +1896,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.2.0" + "source": "https://github.com/symfony/finder/tree/v6.2.3" }, "funding": [ { @@ -1865,7 +1912,7 @@ "type": "tidelift" } ], - "time": "2022-10-09T08:55:40+00:00" + "time": "2022-12-22T17:55:15+00:00" }, { "name": "symfony/options-resolver", @@ -2489,16 +2536,16 @@ }, { "name": "symfony/service-contracts", - "version": "v3.1.1", + "version": "v3.2.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239" + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/925e713fe8fcacf6bc05e936edd8dd5441a21239", - "reference": "925e713fe8fcacf6bc05e936edd8dd5441a21239", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", "shasum": "" }, "require": { @@ -2514,7 +2561,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.1-dev" + "dev-main": "3.3-dev" }, "thanks": { "name": "symfony/contracts", @@ -2554,7 +2601,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.1.1" + "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" }, "funding": [ { @@ -2570,7 +2617,7 @@ "type": "tidelift" } ], - "time": "2022-05-30T19:18:58+00:00" + "time": "2022-11-25T10:21:52+00:00" }, { "name": "symfony/stopwatch", @@ -2636,16 +2683,16 @@ }, { "name": "symfony/string", - "version": "v6.2.0", + "version": "v6.2.2", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "145702685e0d12f81d755c71127bfff7582fdd36" + "reference": "863219fd713fa41cbcd285a79723f94672faff4d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/145702685e0d12f81d755c71127bfff7582fdd36", - "reference": "145702685e0d12f81d755c71127bfff7582fdd36", + "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d", + "reference": "863219fd713fa41cbcd285a79723f94672faff4d", "shasum": "" }, "require": { @@ -2702,7 +2749,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.2.0" + "source": "https://github.com/symfony/string/tree/v6.2.2" }, "funding": [ { @@ -2718,20 +2765,20 @@ "type": "tidelift" } ], - "time": "2022-11-30T17:13:47+00:00" + "time": "2022-12-14T16:11:27+00:00" }, { "name": "symfony/yaml", - "version": "v6.2.0", + "version": "v6.2.2", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "f2570f21bd4adc3589aa3133323273995109bae0" + "reference": "6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/f2570f21bd4adc3589aa3133323273995109bae0", - "reference": "f2570f21bd4adc3589aa3133323273995109bae0", + "url": "https://api.github.com/repos/symfony/yaml/zipball/6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3", + "reference": "6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3", "shasum": "" }, "require": { @@ -2776,7 +2823,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.2.0" + "source": "https://github.com/symfony/yaml/tree/v6.2.2" }, "funding": [ { @@ -2792,20 +2839,20 @@ "type": "tidelift" } ], - "time": "2022-11-25T19:00:27+00:00" + "time": "2022-12-14T16:11:27+00:00" }, { "name": "twig/twig", - "version": "v3.4.3", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58" + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/c38fd6b0b7f370c198db91ffd02e23b517426b58", - "reference": "c38fd6b0b7f370c198db91ffd02e23b517426b58", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", "shasum": "" }, "require": { @@ -2820,7 +2867,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "3.5-dev" } }, "autoload": { @@ -2856,7 +2903,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.4.3" + "source": "https://github.com/twigphp/Twig/tree/v3.5.0" }, "funding": [ { @@ -2868,7 +2915,7 @@ "type": "tidelift" } ], - "time": "2022-09-28T08:42:51+00:00" + "time": "2022-12-27T12:28:18+00:00" } ], "packages-dev": [ @@ -3136,32 +3183,34 @@ }, { "name": "doctrine/collections", - "version": "1.8.0", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e" + "reference": "db8cda536a034337f7dd63febecc713d4957f9ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/2b44dd4cbca8b5744327de78bafef5945c7e7b5e", - "reference": "2b44dd4cbca8b5744327de78bafef5945c7e7b5e", + "url": "https://api.github.com/repos/doctrine/collections/zipball/db8cda536a034337f7dd63febecc713d4957f9ee", + "reference": "db8cda536a034337f7dd63febecc713d4957f9ee", "shasum": "" }, "require": { - "doctrine/deprecations": "^0.5.3 || ^1", - "php": "^7.1.3 || ^8.0" + "doctrine/deprecations": "^1", + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9.0 || ^10.0", - "phpstan/phpstan": "^1.4.8", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.1.5", + "doctrine/coding-standard": "^10.0", + "ext-json": "*", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5", "vimeo/psalm": "^4.22" }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\Collections\\": "lib/Doctrine/Common/Collections" + "Doctrine\\Common\\Collections\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3200,9 +3249,23 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/1.8.0" + "source": "https://github.com/doctrine/collections/tree/2.1.2" }, - "time": "2022-09-01T20:12:10+00:00" + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcollections", + "type": "tidelift" + } + ], + "time": "2022-12-27T23:41:38+00:00" }, { "name": "doctrine/common", @@ -3297,16 +3360,16 @@ }, { "name": "doctrine/dbal", - "version": "3.5.1", + "version": "3.5.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5" + "reference": "63e513cebbbaf96a6795e5c5ee34d205831bfc85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/f38ee8aaca2d58ee88653cb34a6a3880c23f38a5", - "reference": "f38ee8aaca2d58ee88653cb34a6a3880c23f38a5", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/63e513cebbbaf96a6795e5c5ee34d205831bfc85", + "reference": "63e513cebbbaf96a6795e5c5ee34d205831bfc85", "shasum": "" }, "require": { @@ -3319,16 +3382,16 @@ "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "10.0.0", - "jetbrains/phpstorm-stubs": "2022.2", - "phpstan/phpstan": "1.8.10", + "doctrine/coding-standard": "11.0.0", + "jetbrains/phpstorm-stubs": "2022.3", + "phpstan/phpstan": "1.9.2", "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "9.5.25", - "psalm/plugin-phpunit": "0.17.0", + "phpunit/phpunit": "9.5.27", + "psalm/plugin-phpunit": "0.18.4", "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", - "vimeo/psalm": "4.29.0" + "vimeo/psalm": "4.30.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -3388,7 +3451,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.5.1" + "source": "https://github.com/doctrine/dbal/tree/3.5.2" }, "funding": [ { @@ -3404,77 +3467,33 @@ "type": "tidelift" } ], - "time": "2022-10-24T07:26:18+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "v1.0.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "shasum": "" - }, - "require": { - "php": "^7.1|^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" - }, - "time": "2022-05-02T15:47:09+00:00" + "time": "2022-12-19T08:17:34+00:00" }, { "name": "doctrine/event-manager", - "version": "1.2.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520" + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/95aa4cb529f1e96576f3fda9f5705ada4056a520", - "reference": "95aa4cb529f1e96576f3fda9f5705ada4056a520", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", + "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", "shasum": "" }, "require": { - "doctrine/deprecations": "^0.5.3 || ^1", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "conflict": { "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.8", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.24" + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.8", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^4.28" }, "type": "library", "autoload": { @@ -3523,7 +3542,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.2.0" + "source": "https://github.com/doctrine/event-manager/tree/2.0.0" }, "funding": [ { @@ -3539,34 +3558,34 @@ "type": "tidelift" } ], - "time": "2022-10-12T20:51:15+00:00" + "time": "2022-10-12T20:59:15+00:00" }, { "name": "doctrine/instantiator", - "version": "1.4.1", + "version": "1.5.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc" + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/10dcfce151b967d20fde1b34ae6640712c3891bc", - "reference": "10dcfce151b967d20fde1b34ae6640712c3891bc", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", + "doctrine/coding-standard": "^9 || ^11", "ext-pdo": "*", "ext-phar": "*", "phpbench/phpbench": "^0.16 || ^1", "phpstan/phpstan": "^1.4", "phpstan/phpstan-phpunit": "^1", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^4.30 || ^5.4" }, "type": "library", "autoload": { @@ -3593,7 +3612,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.4.1" + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" }, "funding": [ { @@ -3609,55 +3628,56 @@ "type": "tidelift" } ], - "time": "2022-03-03T08:28:38+00:00" + "time": "2022-12-30T00:15:36+00:00" }, { "name": "doctrine/orm", - "version": "2.13.4", + "version": "2.14.0", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "a5a6cc6630ce497290396d5f206887227820a634" + "reference": "f82485e651763fbd1b34879726f4d3b91c358bd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/a5a6cc6630ce497290396d5f206887227820a634", - "reference": "a5a6cc6630ce497290396d5f206887227820a634", + "url": "https://api.github.com/repos/doctrine/orm/zipball/f82485e651763fbd1b34879726f4d3b91c358bd9", + "reference": "f82485e651763fbd1b34879726f4d3b91c358bd9", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5", + "doctrine/collections": "^1.5 || ^2.0", "doctrine/common": "^3.0.3", "doctrine/dbal": "^2.13.1 || ^3.2", "doctrine/deprecations": "^0.5.3 || ^1", - "doctrine/event-manager": "^1.1", + "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3", - "doctrine/lexer": "^1.2.3", + "doctrine/lexer": "^1.2.3 || ^2", "doctrine/persistence": "^2.4 || ^3", "ext-ctype": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "symfony/console": "^4.2 || ^5.0 || ^6.0", "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.16" }, "conflict": { - "doctrine/annotations": "<1.13 || >= 2.0" + "doctrine/annotations": "<1.13 || >= 3.0" }, "require-dev": { - "doctrine/annotations": "^1.13", - "doctrine/coding-standard": "^9.0.2 || ^10.0", + "doctrine/annotations": "^1.13 || ^2", + "doctrine/coding-standard": "^9.0.2 || ^11.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.9.2", + "phpstan/phpstan": "~1.4.10 || 1.9.4", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.1", "symfony/cache": "^4.4 || ^5.4 || ^6.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0" + "vimeo/psalm": "4.30.0 || 5.3.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -3707,22 +3727,22 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.13.4" + "source": "https://github.com/doctrine/orm/tree/2.14.0" }, - "time": "2022-11-20T18:53:31+00:00" + "time": "2022-12-19T21:51:58+00:00" }, { "name": "doctrine/persistence", - "version": "3.1.0", + "version": "3.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "2a9c70a5e21f8968c5a46b79f819ea52f322080b" + "reference": "b44d128311af55275dbed6a4558ca59a2b9f9387" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/2a9c70a5e21f8968c5a46b79f819ea52f322080b", - "reference": "2a9c70a5e21f8968c5a46b79f819ea52f322080b", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/b44d128311af55275dbed6a4558ca59a2b9f9387", + "reference": "b44d128311af55275dbed6a4558ca59a2b9f9387", "shasum": "" }, "require": { @@ -3731,20 +3751,18 @@ "psr/cache": "^1.0 || ^2.0 || ^3.0" }, "conflict": { - "doctrine/annotations": "<1.7 || >=2.0", "doctrine/common": "<2.10" }, "require-dev": { "composer/package-versions-deprecated": "^1.11", - "doctrine/annotations": "^1.7", - "doctrine/coding-standard": "^10", + "doctrine/coding-standard": "^11", "doctrine/common": "^3.0", - "phpstan/phpstan": "1.8.8", + "phpstan/phpstan": "1.9.4", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", "phpunit/phpunit": "^8.5 || ^9.5", "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.29.0" + "vimeo/psalm": "4.30.0 || 5.3.0" }, "type": "library", "autoload": { @@ -3793,7 +3811,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.1.0" + "source": "https://github.com/doctrine/persistence/tree/3.1.2" }, "funding": [ { @@ -3809,7 +3827,7 @@ "type": "tidelift" } ], - "time": "2022-11-18T14:10:19+00:00" + "time": "2022-12-19T13:58:18+00:00" }, { "name": "myclabs/deep-copy", @@ -4330,16 +4348,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.9.2", + "version": "1.9.5", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa" + "reference": "4d18c5d98965029c2aa1ccbd91dc22e7ba8c5034" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d6fdf01c53978b6429f1393ba4afeca39cc68afa", - "reference": "d6fdf01c53978b6429f1393ba4afeca39cc68afa", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4d18c5d98965029c2aa1ccbd91dc22e7ba8c5034", + "reference": "4d18c5d98965029c2aa1ccbd91dc22e7ba8c5034", "shasum": "" }, "require": { @@ -4369,7 +4387,7 @@ ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.9.2" + "source": "https://github.com/phpstan/phpstan/tree/1.9.5" }, "funding": [ { @@ -4385,20 +4403,20 @@ "type": "tidelift" } ], - "time": "2022-11-10T09:56:11+00:00" + "time": "2023-01-02T21:35:42+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.19", + "version": "9.2.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559" + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/c77b56b63e3d2031bd8997fcec43c1925ae46559", - "reference": "c77b56b63e3d2031bd8997fcec43c1925ae46559", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", "shasum": "" }, "require": { @@ -4454,7 +4472,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.19" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" }, "funding": [ { @@ -4462,7 +4480,7 @@ "type": "github" } ], - "time": "2022-11-18T07:47:47+00:00" + "time": "2022-12-28T12:41:10+00:00" }, { "name": "phpunit/php-file-iterator", @@ -5763,16 +5781,16 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.2.0", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "11c13fff0cd2fe1528ea1e60638fb23c9a0c748f" + "reference": "f0f0d9d81a172a334c29f536500475c741a5d4c0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/11c13fff0cd2fe1528ea1e60638fb23c9a0c748f", - "reference": "11c13fff0cd2fe1528ea1e60638fb23c9a0c748f", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/f0f0d9d81a172a334c29f536500475c741a5d4c0", + "reference": "f0f0d9d81a172a334c29f536500475c741a5d4c0", "shasum": "" }, "require": { @@ -5800,7 +5818,7 @@ "symfony/validator": "<5.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4", + "doctrine/annotations": "^1.10.4|^2", "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", @@ -5858,7 +5876,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.0" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.3" }, "funding": [ { @@ -5874,20 +5892,20 @@ "type": "tidelift" } ], - "time": "2022-11-28T12:28:19+00:00" + "time": "2022-12-20T16:41:15+00:00" }, { "name": "symfony/error-handler", - "version": "v6.2.1", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "b4e41f62c1124378863ff2705158a60da3e4c6b9" + "reference": "0926124c95d220499e2baf0fb465772af3a4eddb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/b4e41f62c1124378863ff2705158a60da3e4c6b9", - "reference": "b4e41f62c1124378863ff2705158a60da3e4c6b9", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/0926124c95d220499e2baf0fb465772af3a4eddb", + "reference": "0926124c95d220499e2baf0fb465772af3a4eddb", "shasum": "" }, "require": { @@ -5929,7 +5947,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.2.1" + "source": "https://github.com/symfony/error-handler/tree/v6.2.3" }, "funding": [ { @@ -5945,20 +5963,20 @@ "type": "tidelift" } ], - "time": "2022-12-01T21:07:46+00:00" + "time": "2022-12-19T14:33:49+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.2.1", + "version": "v6.2.2", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "d0bbd5a7e81b38f32504399b9199f265505b7bac" + "reference": "ddf4dd35de1623e7c02013523e6c2137b67b636f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/d0bbd5a7e81b38f32504399b9199f265505b7bac", - "reference": "d0bbd5a7e81b38f32504399b9199f265505b7bac", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ddf4dd35de1623e7c02013523e6c2137b67b636f", + "reference": "ddf4dd35de1623e7c02013523e6c2137b67b636f", "shasum": "" }, "require": { @@ -6007,7 +6025,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.2.1" + "source": "https://github.com/symfony/http-foundation/tree/v6.2.2" }, "funding": [ { @@ -6023,20 +6041,20 @@ "type": "tidelift" } ], - "time": "2022-12-04T18:26:13+00:00" + "time": "2022-12-14T16:11:27+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.2.1", + "version": "v6.2.4", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "bcbd2ea12fee651a4c8bff4f6f00cce2ac1f8404" + "reference": "74f2e638ec3fa0315443bd85fab7fc8066b77f83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/bcbd2ea12fee651a4c8bff4f6f00cce2ac1f8404", - "reference": "bcbd2ea12fee651a4c8bff4f6f00cce2ac1f8404", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/74f2e638ec3fa0315443bd85fab7fc8066b77f83", + "reference": "74f2e638ec3fa0315443bd85fab7fc8066b77f83", "shasum": "" }, "require": { @@ -6118,7 +6136,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.2.1" + "source": "https://github.com/symfony/http-kernel/tree/v6.2.4" }, "funding": [ { @@ -6134,20 +6152,20 @@ "type": "tidelift" } ], - "time": "2022-12-06T17:28:26+00:00" + "time": "2022-12-29T19:05:08+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.2.0", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "1bd3b17db6d2ec284efbdc916600e880d6d858df" + "reference": "3766b8269d3bac5c214a04ebd6870e71e52bcb60" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/1bd3b17db6d2ec284efbdc916600e880d6d858df", - "reference": "1bd3b17db6d2ec284efbdc916600e880d6d858df", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/3766b8269d3bac5c214a04ebd6870e71e52bcb60", + "reference": "3766b8269d3bac5c214a04ebd6870e71e52bcb60", "shasum": "" }, "require": { @@ -6201,7 +6219,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.0" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.3" }, "funding": [ { @@ -6217,7 +6235,7 @@ "type": "tidelift" } ], - "time": "2022-11-18T19:08:09+00:00" + "time": "2022-12-28T14:26:22+00:00" }, { "name": "symfony/polyfill-php72", @@ -6297,16 +6315,16 @@ }, { "name": "symfony/property-access", - "version": "v6.2.0", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "ed937ca8e103fdcefb43020c8784f87d3e5d09c3" + "reference": "9c267d87dd665d5d33e897290bbb9f64ae905b94" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/ed937ca8e103fdcefb43020c8784f87d3e5d09c3", - "reference": "ed937ca8e103fdcefb43020c8784f87d3e5d09c3", + "url": "https://api.github.com/repos/symfony/property-access/zipball/9c267d87dd665d5d33e897290bbb9f64ae905b94", + "reference": "9c267d87dd665d5d33e897290bbb9f64ae905b94", "shasum": "" }, "require": { @@ -6357,7 +6375,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.2.0" + "source": "https://github.com/symfony/property-access/tree/v6.2.3" }, "funding": [ { @@ -6373,20 +6391,20 @@ "type": "tidelift" } ], - "time": "2022-10-28T16:24:13+00:00" + "time": "2022-12-23T08:18:26+00:00" }, { "name": "symfony/property-info", - "version": "v6.2.0", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "ddfa5c49812d7bcfea21f9ad5341092daa82e4cc" + "reference": "b4cbbbcc8679460cfeb1d5bdcb8127a2e85c376c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/ddfa5c49812d7bcfea21f9ad5341092daa82e4cc", - "reference": "ddfa5c49812d7bcfea21f9ad5341092daa82e4cc", + "url": "https://api.github.com/repos/symfony/property-info/zipball/b4cbbbcc8679460cfeb1d5bdcb8127a2e85c376c", + "reference": "b4cbbbcc8679460cfeb1d5bdcb8127a2e85c376c", "shasum": "" }, "require": { @@ -6399,7 +6417,7 @@ "symfony/dependency-injection": "<5.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4", + "doctrine/annotations": "^1.10.4|^2", "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.0", "symfony/cache": "^5.4|^6.0", @@ -6446,7 +6464,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.2.0" + "source": "https://github.com/symfony/property-info/tree/v6.2.3" }, "funding": [ { @@ -6462,20 +6480,20 @@ "type": "tidelift" } ], - "time": "2022-11-25T07:37:13+00:00" + "time": "2022-12-20T16:41:15+00:00" }, { "name": "symfony/serializer", - "version": "v6.2.1", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "e7655a4697c2af2416f0abc6c9f41189ae3eaf0e" + "reference": "9cb1e8fd22f9ff40b9580ae822f44c13317ddb20" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/e7655a4697c2af2416f0abc6c9f41189ae3eaf0e", - "reference": "e7655a4697c2af2416f0abc6c9f41189ae3eaf0e", + "url": "https://api.github.com/repos/symfony/serializer/zipball/9cb1e8fd22f9ff40b9580ae822f44c13317ddb20", + "reference": "9cb1e8fd22f9ff40b9580ae822f44c13317ddb20", "shasum": "" }, "require": { @@ -6493,7 +6511,7 @@ "symfony/yaml": "<5.4" }, "require-dev": { - "doctrine/annotations": "^1.12", + "doctrine/annotations": "^1.12|^2", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", @@ -6547,7 +6565,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.2.1" + "source": "https://github.com/symfony/serializer/tree/v6.2.3" }, "funding": [ { @@ -6563,7 +6581,7 @@ "type": "tidelift" } ], - "time": "2022-12-04T18:26:13+00:00" + "time": "2022-12-20T16:41:15+00:00" }, { "name": "symfony/translation-contracts", @@ -6648,16 +6666,16 @@ }, { "name": "symfony/validator", - "version": "v6.2.0", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "0f74ad1cab71f5899dca8233db774a50f8656de0" + "reference": "bd44a9ae3b19ae81c723b5a5fff6a1a36844ee01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/0f74ad1cab71f5899dca8233db774a50f8656de0", - "reference": "0f74ad1cab71f5899dca8233db774a50f8656de0", + "url": "https://api.github.com/repos/symfony/validator/zipball/bd44a9ae3b19ae81c723b5a5fff6a1a36844ee01", + "reference": "bd44a9ae3b19ae81c723b5a5fff6a1a36844ee01", "shasum": "" }, "require": { @@ -6680,7 +6698,7 @@ "symfony/yaml": "<5.4" }, "require-dev": { - "doctrine/annotations": "^1.13", + "doctrine/annotations": "^1.13|^2", "egulias/email-validator": "^2.1.10|^3", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", @@ -6736,7 +6754,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.2.0" + "source": "https://github.com/symfony/validator/tree/v6.2.3" }, "funding": [ { @@ -6752,20 +6770,20 @@ "type": "tidelift" } ], - "time": "2022-11-25T08:42:40+00:00" + "time": "2022-12-22T17:55:15+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.2.1", + "version": "v6.2.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "1e7544c8698627b908657e5276854d52ab70087a" + "reference": "fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/1e7544c8698627b908657e5276854d52ab70087a", - "reference": "1e7544c8698627b908657e5276854d52ab70087a", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0", + "reference": "fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0", "shasum": "" }, "require": { @@ -6824,7 +6842,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.2.1" + "source": "https://github.com/symfony/var-dumper/tree/v6.2.3" }, "funding": [ { @@ -6840,7 +6858,7 @@ "type": "tidelift" } ], - "time": "2022-12-03T22:32:58+00:00" + "time": "2022-12-22T17:55:15+00:00" }, { "name": "symfony/web-link", @@ -7095,9 +7113,7 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": { - "nette/utils": 20 - }, + "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { From f81efd3bb0fc4ca549b79e6834e78f05ff21c779 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:40:29 +0200 Subject: [PATCH 239/258] fix: CS --- scoper.inc.php | 4 +-- .../AbstractAnnotationGenerator.php | 27 ------------------- .../PhpDocAnnotationGenerator.php | 27 ------------------- .../AbstractAttributeGenerator.php | 12 --------- .../ApiPlatformCoreAttributeGenerator.php | 9 ------- .../ConfigurationAttributeGenerator.php | 13 ++------- .../ConstraintAttributeGenerator.php | 9 ------- .../DoctrineMongoDBAttributeGenerator.php | 9 ------- ...mAssociationOverrideAttributeGenerator.php | 3 --- .../DoctrineOrmAttributeGenerator.php | 9 ------- src/CardinalitiesExtractor.php | 11 +++----- src/Command/DumpConfigurationCommand.php | 6 ----- src/Command/ExtractCardinalitiesCommand.php | 8 +----- src/Command/GenerateCommand.php | 6 ----- src/FilesGenerator.php | 2 +- src/Model/Attribute.php | 6 ++--- src/Model/Class_.php | 2 +- src/Model/Property.php | 6 ++--- src/Model/Type/ArrayType.php | 2 +- src/Model/Use_.php | 2 +- .../PropertyGenerator/IdPropertyGenerator.php | 4 +-- .../PropertyGenerator/PropertyGenerator.php | 4 +-- src/PhpTypeConverterInterface.php | 2 +- src/PropertyGenerator/IdPropertyGenerator.php | 2 +- .../IdPropertyGeneratorInterface.php | 2 +- src/PropertyGenerator/PropertyGenerator.php | 2 +- .../PropertyGeneratorInterface.php | 2 +- src/Schema/Generator.php | 2 +- .../PropertyGenerator/IdPropertyGenerator.php | 4 +-- .../PropertyGenerator/PropertyGenerator.php | 8 +++--- src/Schema/TypeConverter.php | 6 ++--- src/SchemaGeneratorConfiguration.php | 5 +--- src/TypesGenerator.php | 4 +-- tests/ClassMutator/ClassParentMutatorTest.php | 2 +- .../ClassPropertiesAppenderTest.php | 2 +- 35 files changed, 43 insertions(+), 181 deletions(-) diff --git a/scoper.inc.php b/scoper.inc.php index c3d7757d..f7f60184 100644 --- a/scoper.inc.php +++ b/scoper.inc.php @@ -36,7 +36,7 @@ function (string $filePath, string $prefix, string $content): string { // TODO: Temporary patch until the issue is fixed upstream // @link https://github.com/humbug/php-scoper/issues/285 function (string $filePath, string $prefix, string $content): string { - if (false === strpos($content, '@')) { + if (!str_contains($content, '@')) { return $content; } @@ -52,7 +52,7 @@ function (string $filePath, string $prefix, string $content): string { ); }, function (string $filePath, string $prefix, string $content): string { - if (0 !== strpos($filePath, 'src/AnnotationGenerator/')) { + if (!str_starts_with($filePath, 'src/AnnotationGenerator/')) { return $content; } diff --git a/src/AnnotationGenerator/AbstractAnnotationGenerator.php b/src/AnnotationGenerator/AbstractAnnotationGenerator.php index 5bc7d70b..d059763d 100644 --- a/src/AnnotationGenerator/AbstractAnnotationGenerator.php +++ b/src/AnnotationGenerator/AbstractAnnotationGenerator.php @@ -48,73 +48,46 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, Inflect $this->classes = $classes; } - /** - * {@inheritdoc} - */ public function generateClassAnnotations(Class_ $class): array { return []; } - /** - * {@inheritdoc} - */ public function generateInterfaceAnnotations(Class_ $class): array { return []; } - /** - * {@inheritdoc} - */ public function generateConstantAnnotations(Constant $constant): array { return []; } - /** - * {@inheritdoc} - */ public function generatePropertyAnnotations(Property $property, string $className): array { return []; } - /** - * {@inheritdoc} - */ public function generateGetterAnnotations(Property $property): array { return []; } - /** - * {@inheritdoc} - */ public function generateSetterAnnotations(Property $property): array { return []; } - /** - * {@inheritdoc} - */ public function generateAdderAnnotations(Property $property): array { return []; } - /** - * {@inheritdoc} - */ public function generateRemoverAnnotations(Property $property): array { return []; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { return []; diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index 44e725b4..ba42d9e5 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -31,9 +31,6 @@ final class PhpDocAnnotationGenerator extends AbstractAnnotationGenerator private HtmlConverter $htmlToMarkdown; - /** - * {@inheritdoc} - */ public function __construct(PhpTypeConverterInterface $phpTypeConverter, InflectorInterface $inflector, array $config, array $classes) { parent::__construct($phpTypeConverter, $inflector, $config, $classes); @@ -41,25 +38,16 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, Inflect $this->htmlToMarkdown = new HtmlConverter(); } - /** - * {@inheritdoc} - */ public function generateClassAnnotations(Class_ $class): array { return $this->generateDoc($class); } - /** - * {@inheritdoc} - */ public function generateInterfaceAnnotations(Class_ $class): array { return $this->generateDoc($class, true); } - /** - * {@inheritdoc} - */ public function generateConstantAnnotations(Constant $constant): array { $annotations = $this->formatDoc($constant->comment(), true); @@ -68,9 +56,6 @@ public function generateConstantAnnotations(Constant $constant): array return $annotations; } - /** - * {@inheritdoc} - */ public function generatePropertyAnnotations(Property $property, string $className): array { $description = $this->formatDoc((string) $property->description(), true); @@ -92,9 +77,6 @@ public function generatePropertyAnnotations(Property $property, string $classNam return $annotations; } - /** - * {@inheritdoc} - */ public function generateGetterAnnotations(Property $property): array { if (!$this->isDocUseful($property)) { @@ -104,9 +86,6 @@ public function generateGetterAnnotations(Property $property): array return [sprintf('@return %s', $this->toPhpDocType($property))]; } - /** - * {@inheritdoc} - */ public function generateSetterAnnotations(Property $property): array { if (!$this->isDocUseful($property)) { @@ -116,9 +95,6 @@ public function generateSetterAnnotations(Property $property): array return [sprintf('@param %s $%s', $this->toPhpDocType($property), $property->name())]; } - /** - * {@inheritdoc} - */ public function generateAdderAnnotations(Property $property): array { if (!$this->isDocUseful($property, true)) { @@ -128,9 +104,6 @@ public function generateAdderAnnotations(Property $property): array return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; } - /** - * {@inheritdoc} - */ public function generateRemoverAnnotations(Property $property): array { if (!$this->isDocUseful($property, true)) { diff --git a/src/AttributeGenerator/AbstractAttributeGenerator.php b/src/AttributeGenerator/AbstractAttributeGenerator.php index 622e60d4..c972a940 100644 --- a/src/AttributeGenerator/AbstractAttributeGenerator.php +++ b/src/AttributeGenerator/AbstractAttributeGenerator.php @@ -47,33 +47,21 @@ public function __construct(PhpTypeConverterInterface $phpTypeConverter, Inflect $this->classes = $classes; } - /** - * {@inheritdoc} - */ public function generateClassAttributes(Class_ $class): array { return []; } - /** - * {@inheritdoc} - */ public function generatePropertyAttributes(Property $property, string $className): array { return []; } - /** - * {@inheritdoc} - */ public function generateLateClassAttributes(Class_ $class): array { return []; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { return []; diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index c9afbf79..039d1dea 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -39,9 +39,6 @@ */ final class ApiPlatformCoreAttributeGenerator extends AbstractAttributeGenerator { - /** - * {@inheritdoc} - */ public function generateClassAttributes(Class_ $class): array { if ($class->hasChild || $class->isEnum()) { @@ -110,9 +107,6 @@ private function validateClassOperations(array $operations): array return $resolver->resolve($operations); } - /** - * {@inheritdoc} - */ public function generatePropertyAttributes(Property $property, string $className): array { $arguments = []; @@ -128,9 +122,6 @@ public function generatePropertyAttributes(Property $property, string $className return $property->isCustom ? [] : [new Attribute('ApiProperty', $arguments)]; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { if ($this->config['apiPlatformOldAttributes']) { diff --git a/src/AttributeGenerator/ConfigurationAttributeGenerator.php b/src/AttributeGenerator/ConfigurationAttributeGenerator.php index 30d7d46a..e06c2dfb 100644 --- a/src/AttributeGenerator/ConfigurationAttributeGenerator.php +++ b/src/AttributeGenerator/ConfigurationAttributeGenerator.php @@ -21,9 +21,6 @@ final class ConfigurationAttributeGenerator extends AbstractAttributeGenerator { - /** - * {@inheritdoc} - */ public function generateClassAttributes(Class_ $class): array { $typeAttributes = $this->config['types'][$class->name()]['attributes'] ?? [[]]; @@ -44,8 +41,8 @@ public function generateClassAttributes(Class_ $class): array // An attribute from a vocabulary cannot be appended if a same one has not // previously been generated or if the same one is not mergeable. // It allows vocabulary attributes configuration to only merge the attributes args. - 'alwaysGenerate' => !\in_array($name, $vocabAttributesNames, true) || - \in_array($name, $typeAttributesNames, true), + 'alwaysGenerate' => !\in_array($name, $vocabAttributesNames, true) + || \in_array($name, $typeAttributesNames, true), // Custom explicitly configured attributes is not mergeable with next one // but treated as repeated if given more than once. 'mergeable' => false, @@ -69,9 +66,6 @@ public function generateClassAttributes(Class_ $class): array return $attributes; } - /** - * {@inheritdoc} - */ public function generatePropertyAttributes(Property $property, string $className): array { $typeConfig = $this->config['types'][$className] ?? null; @@ -90,9 +84,6 @@ public function generatePropertyAttributes(Property $property, string $className return $attributes; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { $uses = []; diff --git a/src/AttributeGenerator/ConstraintAttributeGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php index a5ea99d6..6c8e18cd 100644 --- a/src/AttributeGenerator/ConstraintAttributeGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -27,9 +27,6 @@ */ final class ConstraintAttributeGenerator extends AbstractAttributeGenerator { - /** - * {@inheritdoc} - */ public function generatePropertyAttributes(Property $property, string $className): array { if ($property->isId) { @@ -84,9 +81,6 @@ public function generatePropertyAttributes(Property $property, string $className return $asserts; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { if ($class->isEnum()) { @@ -113,9 +107,6 @@ public function generateUses(Class_ $class): array return $uses; } - /** - * {@inheritdoc} - */ public function generateClassAttributes(Class_ $class): array { if ($class->isEnum()) { diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index e75fe6af..1ee8ae89 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -30,9 +30,6 @@ */ final class DoctrineMongoDBAttributeGenerator extends AbstractAttributeGenerator { - /** - * {@inheritdoc} - */ public function generateClassAttributes(Class_ $class): array { if ($class->isEnum()) { @@ -72,9 +69,6 @@ public function generateClassAttributes(Class_ $class): array return $attributes; } - /** - * {@inheritdoc} - */ public function generatePropertyAttributes(Property $property, string $className): array { if (null === $property->type && null === $property->reference) { @@ -146,9 +140,6 @@ public function generatePropertyAttributes(Property $property, string $className return []; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { return $class->isEnum() ? [] : [new Use_('Doctrine\ODM\MongoDB\Mapping\Annotations', 'MongoDB')]; diff --git a/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php index 72a81fc2..f36944b7 100644 --- a/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAssociationOverrideAttributeGenerator.php @@ -21,9 +21,6 @@ final class DoctrineOrmAssociationOverrideAttributeGenerator extends AbstractAtt { use GenerateIdentifierNameTrait; - /** - * {@inheritdoc} - */ public function generateLateClassAttributes(Class_ $class): array { if ($class->isAbstract || !($parentName = $class->parent())) { diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 6ddad3f9..0959d109 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -34,9 +34,6 @@ final class DoctrineOrmAttributeGenerator extends AbstractAttributeGenerator private const RESERVED_KEYWORDS = ['ABORT', 'ABORTSESSION', 'ABS', 'ABSOLUTE', 'ACCESS', 'ACCESSIBLE', 'ACCESS_LOCK', 'ACCOUNT', 'ACOS', 'ACOSH', 'ACTION', 'ADD', 'ADD_MONTHS', 'ADMIN', 'AFTER', 'AGGREGATE', 'ALIAS', 'ALL', 'ALLOCATE', 'ALLOW', 'ALTER', 'ALTERAND', 'AMP', 'ANALYSE', 'ANALYZE', 'AND', 'ANSIDATE', 'ANY', 'ARE', 'ARRAY', 'ARRAY_AGG', 'ARRAY_EXISTS', 'ARRAY_MAX_CARDINALITY', 'AS', 'ASC', 'ASENSITIVE', 'ASIN', 'ASINH', 'ASSERTION', 'ASSOCIATE', 'ASUTIME', 'ASYMMETRIC', 'AT', 'ATAN', 'ATAN2', 'ATANH', 'ATOMIC', 'AUDIT', 'AUTHORIZATION', 'AUX', 'AUXILIARY', 'AVE', 'AVERAGE', 'AVG', 'BACKUP', 'BEFORE', 'BEGIN', 'BEGIN_FRAME', 'BEGIN_PARTITION', 'BETWEEN', 'BIGINT', 'BINARY', 'BIT', 'BLOB', 'BOOLEAN', 'BOTH', 'BREADTH', 'BREAK', 'BROWSE', 'BT', 'BUFFERPOOL', 'BULK', 'BUT', 'BY', 'BYTE', 'BYTEINT', 'BYTES', 'CALL', 'CALLED', 'CAPTURE', 'CARDINALITY', 'CASCADE', 'CASCADED', 'CASE', 'CASESPECIFIC', 'CASE_N', 'CAST', 'CATALOG', 'CCSID', 'CD', 'CEIL', 'CEILING', 'CHANGE', 'CHAR', 'CHAR2HEXINT', 'CHARACTER', 'CHARACTERS', 'CHARACTER_LENGTH', 'CHARS', 'CHAR_LENGTH', 'CHECK', 'CHECKPOINT', 'CLASS', 'CLASSIFIER', 'CLOB', 'CLONE', 'CLOSE', 'CLUSTER', 'CLUSTERED', 'CM', 'COALESCE', 'COLLATE', 'COLLATION', 'COLLECT', 'COLLECTION', 'COLLID', 'COLUMN', 'COLUMN_VALUE', 'COMMENT', 'COMMIT', 'COMPLETION', 'COMPRESS', 'COMPUTE', 'CONCAT', 'CONCURRENTLY', 'CONDITION', 'CONNECT', 'CONNECTION', 'CONSTRAINT', 'CONSTRAINTS', 'CONSTRUCTOR', 'CONTAINS', 'CONTAINSTABLE', 'CONTENT', 'CONTINUE', 'CONVERT', 'CONVERT_TABLE_HEADER', 'COPY', 'CORR', 'CORRESPONDING', 'COS', 'COSH', 'COUNT', 'COVAR_POP', 'COVAR_SAMP', 'CREATE', 'CROSS', 'CS', 'CSUM', 'CT', 'CUBE', 'CUME_DIST', 'CURRENT', 'CURRENT_CATALOG', 'CURRENT_DATE', 'CURRENT_DEFAULT_TRANSFORM_GROUP', 'CURRENT_LC_CTYPE', 'CURRENT_PATH', 'CURRENT_ROLE', 'CURRENT_ROW', 'CURRENT_SCHEMA', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_TRANSFORM_GROUP_FOR_TYPE', 'CURRENT_USER', 'CURRVAL', 'CURSOR', 'CV', 'CYCLE', 'DATA', 'DATABASE', 'DATABASES', 'DATABLOCKSIZE', 'DATE', 'DATEFORM', 'DAY', 'DAYS', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DBCC', 'DBINFO', 'DEALLOCATE', 'DEC', 'DECFLOAT', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DEFERRABLE', 'DEFERRED', 'DEFINE', 'DEGREES', 'DEL', 'DELAYED', 'DELETE', 'DENSE_RANK', 'DENY', 'DEPTH', 'DEREF', 'DESC', 'DESCRIBE', 'DESCRIPTOR', 'DESTROY', 'DESTRUCTOR', 'DETERMINISTIC', 'DIAGNOSTIC', 'DIAGNOSTICS', 'DICTIONARY', 'DISABLE', 'DISABLED', 'DISALLOW', 'DISCONNECT', 'DISK', 'DISTINCT', 'DISTINCTROW', 'DISTRIBUTED', 'DIV', 'DO', 'DOCUMENT', 'DOMAIN', 'DOUBLE', 'DROP', 'DSSIZE', 'DUAL', 'DUMP', 'DYNAMIC', 'EACH', 'ECHO', 'EDITPROC', 'ELEMENT', 'ELSE', 'ELSEIF', 'EMPTY', 'ENABLED', 'ENCLOSED', 'ENCODING', 'ENCRYPTION', 'END', 'END-EXEC', 'ENDING', 'END_FRAME', 'END_PARTITION', 'EQ', 'EQUALS', 'ERASE', 'ERRLVL', 'ERROR', 'ERRORFILES', 'ERRORTABLES', 'ESCAPE', 'ESCAPED', 'ET', 'EVERY', 'EXCEPT', 'EXCEPTION', 'EXCLUSIVE', 'EXEC', 'EXECUTE', 'EXISTS', 'EXIT', 'EXP', 'EXPLAIN', 'EXTERNAL', 'EXTRACT', 'FALLBACK', 'FALSE', 'FASTEXPORT', 'FENCED', 'FETCH', 'FIELDPROC', 'FILE', 'FILLFACTOR', 'FILTER', 'FINAL', 'FIRST', 'FIRST_VALUE', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FLOOR', 'FOR', 'FORCE', 'FOREIGN', 'FORMAT', 'FOUND', 'FRAME_ROW', 'FREE', 'FREESPACE', 'FREETEXT', 'FREETEXTTABLE', 'FREEZE', 'FROM', 'FULL', 'FULLTEXT', 'FUNCTION', 'FUSION', 'GE', 'GENERAL', 'GENERATED', 'GET', 'GIVE', 'GLOBAL', 'GO', 'GOTO', 'GRANT', 'GRAPHIC', 'GROUP', 'GROUPING', 'GROUPS', 'GT', 'HANDLER', 'HASH', 'HASHAMP', 'HASHBAKAMP', 'HASHBUCKET', 'HASHROW', 'HAVING', 'HELP', 'HIGH_PRIORITY', 'HOLD', 'HOLDLOCK', 'HOST', 'HOUR', 'HOURS', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IDENTIFIED', 'IDENTITY', 'IDENTITYCOL', 'IDENTITY_INSERT', 'IF', 'IGNORE', 'ILIKE', 'IMMEDIATE', 'IN', 'INCLUSIVE', 'INCONSISTENT', 'INCREMENT', 'INDEX', 'INDICATOR', 'INFILE', 'INHERIT', 'INITIAL', 'INITIALIZE', 'INITIALLY', 'INITIATE', 'INNER', 'INOUT', 'INPUT', 'INS', 'INSENSITIVE', 'INSERT', 'INSTEAD', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTEGERDATE', 'INTERSECT', 'INTERSECTION', 'INTERVAL', 'INTO', 'IO_AFTER_GTIDS', 'IO_BEFORE_GTIDS', 'IS', 'ISNULL', 'ISOBID', 'ISOLATION', 'ITERATE', 'JAR', 'JOIN', 'JOURNAL', 'JSON_ARRAY', 'JSON_ARRAYAGG', 'JSON_EXISTS', 'JSON_OBJECT', 'JSON_OBJECTAGG', 'JSON_QUERY', 'JSON_TABLE', 'JSON_TABLE_PRIMITIVE', 'JSON_VALUE', 'KEEP', 'KEY', 'KEYS', 'KILL', 'KURTOSIS', 'LABEL', 'LAG', 'LANGUAGE', 'LARGE', 'LAST', 'LAST_VALUE', 'LATERAL', 'LC_CTYPE', 'LE', 'LEAD', 'LEADING', 'LEAVE', 'LEFT', 'LESS', 'LEVEL', 'LIKE', 'LIKE_REGEX', 'LIMIT', 'LINEAR', 'LINENO', 'LINES', 'LISTAGG', 'LN', 'LOAD', 'LOADING', 'LOCAL', 'LOCALE', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATOR', 'LOCATORS', 'LOCK', 'LOCKING', 'LOCKMAX', 'LOCKSIZE', 'LOG', 'LOG10', 'LOGGING', 'LOGON', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOWER', 'LOW_PRIORITY', 'LT', 'MACRO', 'MAINTAINED', 'MAP', 'MASTER_BIND', 'MASTER_SSL_VERIFY_SERVER_CERT', 'MATCH', 'MATCHES', 'MATCH_NUMBER', 'MATCH_RECOGNIZE', 'MATERIALIZED', 'MAVG', 'MAX', 'MAXEXTENTS', 'MAXIMUM', 'MAXVALUE', 'MCHARACTERS', 'MDIFF', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MEMBER', 'MERGE', 'METHOD', 'MICROSECOND', 'MICROSECONDS', 'MIDDLEINT', 'MIN', 'MINDEX', 'MINIMUM', 'MINUS', 'MINUTE', 'MINUTES', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MLINREG', 'MLOAD', 'MLSLABEL', 'MOD', 'MODE', 'MODIFIES', 'MODIFY', 'MODULE', 'MONITOR', 'MONRESOURCE', 'MONSESSION', 'MONTH', 'MONTHS', 'MSUBSTR', 'MSUM', 'MULTISET', 'NAMED', 'NAMES', 'NATIONAL', 'NATURAL', 'NCHAR', 'NCLOB', 'NE', 'NESTED_TABLE_ID', 'NEW', 'NEW_TABLE', 'NEXT', 'NEXTVAL', 'NO', 'NOAUDIT', 'NOCHECK', 'NOCOMPRESS', 'NONCLUSTERED', 'NONE', 'NORMALIZE', 'NOT', 'NOTNULL', 'NOWAIT', 'NO_WRITE_TO_BINLOG', 'NTH_VALUE', 'NTILE', 'NULL', 'NULLIF', 'NULLIFZERO', 'NULLS', 'NUMBER', 'NUMERIC', 'NUMPARTS', 'OBID', 'OBJECT', 'OBJECTS', 'OCCURRENCES_REGEX', 'OCTET_LENGTH', 'OF', 'OFF', 'OFFLINE', 'OFFSET', 'OFFSETS', 'OLD', 'OLD_TABLE', 'OMIT', 'ON', 'ONE', 'ONLINE', 'ONLY', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPERATION', 'OPTIMIZATION', 'OPTIMIZE', 'OPTIMIZER_COSTS', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'ORDINALITY', 'ORGANIZATION', 'OUT', 'OUTER', 'OUTFILE', 'OUTPUT', 'OVER', 'OVERLAPS', 'OVERLAY', 'OVERRIDE', 'PACKAGE', 'PAD', 'PADDED', 'PARAMETER', 'PARAMETERS', 'PART', 'PARTIAL', 'PARTITION', 'PARTITIONED', 'PARTITIONING', 'PASSWORD', 'PATH', 'PATTERN', 'PCTFREE', 'PER', 'PERCENT', 'PERCENTILE_CONT', 'PERCENTILE_DISC', 'PERCENT_RANK', 'PERIOD', 'PERM', 'PERMANENT', 'PIECESIZE', 'PIVOT', 'PLACING', 'PLAN', 'PORTION', 'POSITION', 'POSITION_REGEX', 'POSTFIX', 'POWER', 'PRECEDES', 'PRECISION', 'PREFIX', 'PREORDER', 'PREPARE', 'PRESERVE', 'PREVVAL', 'PRIMARY', 'PRINT', 'PRIOR', 'PRIQTY', 'PRIVATE', 'PRIVILEGES', 'PROC', 'PROCEDURE', 'PROFILE', 'PROGRAM', 'PROPORTIONAL', 'PROTECTION', 'PSID', 'PTF', 'PUBLIC', 'PURGE', 'QUALIFIED', 'QUALIFY', 'QUANTILE', 'QUERY', 'QUERYNO', 'RADIANS', 'RAISERROR', 'RANDOM', 'RANGE', 'RANGE_N', 'RANK', 'RAW', 'READ', 'READS', 'READTEXT', 'READ_WRITE', 'REAL', 'RECONFIGURE', 'RECURSIVE', 'REF', 'REFERENCES', 'REFERENCING', 'REFRESH', 'REGEXP', 'REGR_AVGX', 'REGR_AVGY', 'REGR_COUNT', 'REGR_INTERCEPT', 'REGR_R2', 'REGR_SLOPE', 'REGR_SXX', 'REGR_SXY', 'REGR_SYY', 'RELATIVE', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REPLICATION', 'REPOVERRIDE', 'REQUEST', 'REQUIRE', 'RESIGNAL', 'RESOURCE', 'RESTART', 'RESTORE', 'RESTRICT', 'RESULT', 'RESULT_SET_LOCATOR', 'RESUME', 'RET', 'RETRIEVE', 'RETURN', 'RETURNING', 'RETURNS', 'REVALIDATE', 'REVERT', 'REVOKE', 'RIGHT', 'RIGHTS', 'RLIKE', 'ROLE', 'ROLLBACK', 'ROLLFORWARD', 'ROLLUP', 'ROUND_CEILING', 'ROUND_DOWN', 'ROUND_FLOOR', 'ROUND_HALF_DOWN', 'ROUND_HALF_EVEN', 'ROUND_HALF_UP', 'ROUND_UP', 'ROUTINE', 'ROW', 'ROWCOUNT', 'ROWGUIDCOL', 'ROWID', 'ROWNUM', 'ROWS', 'ROWSET', 'ROW_NUMBER', 'RULE', 'RUN', 'RUNNING', 'SAMPLE', 'SAMPLEID', 'SAVE', 'SAVEPOINT', 'SCHEMA', 'SCHEMAS', 'SCOPE', 'SCRATCHPAD', 'SCROLL', 'SEARCH', 'SECOND', 'SECONDS', 'SECOND_MICROSECOND', 'SECQTY', 'SECTION', 'SECURITY', 'SECURITYAUDIT', 'SEEK', 'SEL', 'SELECT', 'SEMANTICKEYPHRASETABLE', 'SEMANTICSIMILARITYDETAILSTABLE', 'SEMANTICSIMILARITYTABLE', 'SENSITIVE', 'SEPARATOR', 'SEQUENCE', 'SESSION', 'SESSION_USER', 'SET', 'SETRESRATE', 'SETS', 'SETSESSRATE', 'SETUSER', 'SHARE', 'SHOW', 'SHUTDOWN', 'SIGNAL', 'SIMILAR', 'SIMPLE', 'SIN', 'SINH', 'SIZE', 'SKEW', 'SKIP', 'SMALLINT', 'SOME', 'SOUNDEX', 'SOURCE', 'SPACE', 'SPATIAL', 'SPECIFIC', 'SPECIFICTYPE', 'SPOOL', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLTEXT', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SQRT', 'SS', 'SSL', 'STANDARD', 'START', 'STARTING', 'STARTUP', 'STATE', 'STATEMENT', 'STATIC', 'STATISTICS', 'STAY', 'STDDEV_POP', 'STDDEV_SAMP', 'STEPINFO', 'STOGROUP', 'STORED', 'STORES', 'STRAIGHT_JOIN', 'STRING_CS', 'STRUCTURE', 'STYLE', 'SUBMULTISET', 'SUBSCRIBER', 'SUBSET', 'SUBSTR', 'SUBSTRING', 'SUBSTRING_REGEX', 'SUCCEEDS', 'SUCCESSFUL', 'SUM', 'SUMMARY', 'SUSPEND', 'SYMMETRIC', 'SYNONYM', 'SYSDATE', 'SYSTEM', 'SYSTEM_TIME', 'SYSTEM_USER', 'SYSTIMESTAMP', 'TABLE', 'TABLESAMPLE', 'TABLESPACE', 'TAN', 'TANH', 'TBL_CS', 'TEMPORARY', 'TERMINATE', 'TERMINATED', 'TEXTSIZE', 'THAN', 'THEN', 'THRESHOLD', 'TIME', 'TIMESTAMP', 'TIMEZONE_HOUR', 'TIMEZONE_MINUTE', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TITLE', 'TO', 'TOP', 'TRACE', 'TRAILING', 'TRAN', 'TRANSACTION', 'TRANSLATE', 'TRANSLATE_CHK', 'TRANSLATE_REGEX', 'TRANSLATION', 'TREAT', 'TRIGGER', 'TRIM', 'TRIM_ARRAY', 'TRUE', 'TRUNCATE', 'TRY_CONVERT', 'TSEQUAL', 'TYPE', 'UC', 'UESCAPE', 'UID', 'UNDEFINED', 'UNDER', 'UNDO', 'UNION', 'UNIQUE', 'UNKNOWN', 'UNLOCK', 'UNNEST', 'UNPIVOT', 'UNSIGNED', 'UNTIL', 'UPD', 'UPDATE', 'UPDATETEXT', 'UPPER', 'UPPERCASE', 'USAGE', 'USE', 'USER', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALIDATE', 'VALIDPROC', 'VALUE', 'VALUES', 'VALUE_OF', 'VARBINARY', 'VARBYTE', 'VARCHAR', 'VARCHAR2', 'VARCHARACTER', 'VARGRAPHIC', 'VARIABLE', 'VARIADIC', 'VARIANT', 'VARYING', 'VAR_POP', 'VAR_SAMP', 'VCAT', 'VERBOSE', 'VERSIONING', 'VIEW', 'VIRTUAL', 'VOLATILE', 'VOLUMES', 'WAIT', 'WAITFOR', 'WHEN', 'WHENEVER', 'WHERE', 'WHILE', 'WIDTH_BUCKET', 'WINDOW', 'WITH', 'WITHIN', 'WITHIN_GROUP', 'WITHOUT', 'WLM', 'WORK', 'WRITE', 'WRITETEXT', 'XMLCAST', 'XMLEXISTS', 'XMLNAMESPACES', 'XOR', 'YEAR', 'YEARS', 'YEAR_MONTH', 'ZEROFILL', 'ZEROIFNULL', 'ZONE']; - /** - * {@inheritdoc} - */ public function generateClassAttributes(Class_ $class): array { if ($class->isEnum()) { @@ -88,9 +85,6 @@ public function generateClassAttributes(Class_ $class): array return $attributes; } - /** - * {@inheritdoc} - */ public function generatePropertyAttributes(Property $property, string $className): array { if (null === $property->type && null === $property->reference) { @@ -242,9 +236,6 @@ public function generatePropertyAttributes(Property $property, string $className return $attributes; } - /** - * {@inheritdoc} - */ public function generateUses(Class_ $class): array { return $class->isEnum() ? [] : [new Use_('Doctrine\ORM\Mapping', 'ORM')]; diff --git a/src/CardinalitiesExtractor.php b/src/CardinalitiesExtractor.php index 78df057f..343b0ee4 100644 --- a/src/CardinalitiesExtractor.php +++ b/src/CardinalitiesExtractor.php @@ -96,7 +96,7 @@ private function extractForProperty(RdfResource $property): string return self::CARDINALITY_0_N; } - if (0 !== strpos($property->getUri(), 'https://schema.org/')) { + if (!str_starts_with($property->getUri(), 'https://schema.org/')) { return self::CARDINALITY_UNKNOWN; } @@ -117,19 +117,16 @@ private function extractForProperty(RdfResource $property): string if ( // https://schema.org/acceptedOffer, https://schema.org/acceptedPaymentMethod, https://schema.org/exerciseType preg_match('/\(s\)/', $comment) - || // https://schema.org/follows - preg_match('/^The most generic uni-directional social relation./', $comment) - || - preg_match('/one or more/i', $comment) + || preg_match('/^The most generic uni-directional social relation./', $comment) + || preg_match('/one or more/i', $comment) ) { return self::CARDINALITY_0_N; } if ( preg_match('/^is/', $localName) - || - preg_match('/^The /', $comment) + || preg_match('/^The /', $comment) ) { return self::CARDINALITY_0_1; } diff --git a/src/Command/DumpConfigurationCommand.php b/src/Command/DumpConfigurationCommand.php index 04b00026..e9b31798 100644 --- a/src/Command/DumpConfigurationCommand.php +++ b/src/Command/DumpConfigurationCommand.php @@ -26,9 +26,6 @@ */ final class DumpConfigurationCommand extends Command { - /** - * {@inheritdoc} - */ protected function configure(): void { $this @@ -36,9 +33,6 @@ protected function configure(): void ->setDescription('Dump configuration'); } - /** - * {@inheritdoc} - */ protected function execute(InputInterface $input, OutputInterface $output): int { $configuration = new SchemaGeneratorConfiguration(); diff --git a/src/Command/ExtractCardinalitiesCommand.php b/src/Command/ExtractCardinalitiesCommand.php index 3170be67..7701f729 100644 --- a/src/Command/ExtractCardinalitiesCommand.php +++ b/src/Command/ExtractCardinalitiesCommand.php @@ -29,9 +29,6 @@ */ final class ExtractCardinalitiesCommand extends Command { - /** - * {@inheritdoc} - */ protected function configure(): void { $this @@ -42,9 +39,6 @@ protected function configure(): void ; } - /** - * {@inheritdoc} - */ protected function execute(InputInterface $input, OutputInterface $output): int { $vocabFile = $input->getOption('vocabulary-file'); @@ -53,7 +47,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int $graph = new RdfGraph(); $format = pathinfo($vocabFile, \PATHINFO_EXTENSION) ?: 'guess'; - if (0 === strpos($vocabFile, 'http://') || 0 === strpos($vocabFile, 'https://')) { + if (str_starts_with($vocabFile, 'http://') || str_starts_with($vocabFile, 'https://')) { $graph->load($input->getOption('vocabulary-file'), $format); } else { $graph->parseFile($input->getOption('vocabulary-file'), $format); diff --git a/src/Command/GenerateCommand.php b/src/Command/GenerateCommand.php index 23989e86..35f55fec 100644 --- a/src/Command/GenerateCommand.php +++ b/src/Command/GenerateCommand.php @@ -38,9 +38,6 @@ final class GenerateCommand extends Command private ?string $namespacePrefix = null; private ?string $defaultOutput = null; - /** - * {@inheritdoc} - */ protected function configure(): void { $this->readComposer(); @@ -72,9 +69,6 @@ private function readComposer(): void } } - /** - * {@inheritdoc} - */ protected function execute(InputInterface $input, OutputInterface $output): int { $io = new SymfonyStyle($input, $output); diff --git a/src/FilesGenerator.php b/src/FilesGenerator.php index 58201119..a2c17ac6 100644 --- a/src/FilesGenerator.php +++ b/src/FilesGenerator.php @@ -128,7 +128,7 @@ public function generate(array $classes, array $config): void */ private function namespaceToDir(string $namespace, array $config): string { - if (null !== ($prefix = $config['namespaces']['prefix'] ?? null) && 0 === strpos($namespace, $prefix)) { + if (null !== ($prefix = $config['namespaces']['prefix'] ?? null) && str_starts_with($namespace, $prefix)) { $namespace = substr($namespace, \strlen($prefix)); } diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php index 4562056a..290f2f1a 100644 --- a/src/Model/Attribute.php +++ b/src/Model/Attribute.php @@ -22,7 +22,7 @@ final class Attribute private string $name; - /** @var (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] */ + /** @var (int|bool|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[]|null)[] */ private array $args; /** @@ -40,7 +40,7 @@ final class Attribute public bool $mergeable = true; /** - * @param (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] $args + * @param (int|bool|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[]|null)[] $args */ public function __construct(string $name, array $args = []) { @@ -60,7 +60,7 @@ public function name(): string } /** - * @return (int|bool|null|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[])[] + * @return (int|bool|string|string[]|string[][]|\Nette\PhpGenerator\Literal|\Nette\PhpGenerator\Literal[]|null)[] */ public function args(): array { diff --git a/src/Model/Class_.php b/src/Model/Class_.php index a7003fc8..89075432 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -214,7 +214,7 @@ public function isParentEnum(): bool /** * @param Configuration $config */ - public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFile $file = null): PhpFile + public function toNetteFile(array $config, InflectorInterface $inflector, PhpFile $file = null): PhpFile { $useDoctrineCollections = $config['doctrine']['useCollection']; $useAccessors = $config['accessorMethods']; diff --git a/src/Model/Property.php b/src/Model/Property.php index 27c27226..9378e88e 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -29,8 +29,8 @@ abstract class Property public string $cardinality; /** @var ?Type the data types (object is not one) */ public ?Type $type = null; - /** @var mixed */ - public $defaultValue = null; + + public $defaultValue; public ?Class_ $reference = null; public bool $isReadable = true; public bool $isWritable = true; @@ -139,7 +139,7 @@ public function markAsCustom(): self return $this; } - public function toNetteProperty(PhpNamespace $namespace, string $visibility = null, bool $useDoctrineCollections = true, ?NetteProperty $property = null): NetteProperty + public function toNetteProperty(PhpNamespace $namespace, string $visibility = null, bool $useDoctrineCollections = true, NetteProperty $property = null): NetteProperty { $property ??= new NetteProperty($this->name); diff --git a/src/Model/Type/ArrayType.php b/src/Model/Type/ArrayType.php index f6e496d1..4413373c 100644 --- a/src/Model/Type/ArrayType.php +++ b/src/Model/Type/ArrayType.php @@ -17,7 +17,7 @@ final class ArrayType implements Type { public ?Type $type; - public function __construct(?Type $type = null) + public function __construct(Type $type = null) { $this->type = $type; } diff --git a/src/Model/Use_.php b/src/Model/Use_.php index 849146a7..e6c8483c 100644 --- a/src/Model/Use_.php +++ b/src/Model/Use_.php @@ -19,7 +19,7 @@ final class Use_ private ?string $alias; - public function __construct(string $name, ?string $alias = null) + public function __construct(string $name, string $alias = null) { $this->name = $name; $this->alias = $alias; diff --git a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php index 830f2c77..2ba458e9 100644 --- a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php @@ -24,12 +24,12 @@ final class IdPropertyGenerator implements IdPropertyGeneratorInterface { private IdPropertyGeneratorInterface $idPropertyGenerator; - public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = null) + public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator = null) { $this->idPropertyGenerator = $idPropertyGenerator ?? new CommonIdPropertyGenerator(); } - public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property { $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new OpenApiProperty('id')); diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index ef0d0135..d7ab22de 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -33,7 +33,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface private PropertyGeneratorInterface $propertyGenerator; - public function __construct(?PropertyGeneratorInterface $propertyGenerator = null) + public function __construct(PropertyGeneratorInterface $propertyGenerator = null) { $this->propertyGenerator = $propertyGenerator ?? new CommonPropertyGenerator(); } @@ -42,7 +42,7 @@ public function __construct(?PropertyGeneratorInterface $propertyGenerator = nul * @param Configuration $config * @param array{schema: Schema, property: Schema} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, Property $property = null): ?Property { $schema = $context['schema']; $schemaProperty = $context['property']; diff --git a/src/PhpTypeConverterInterface.php b/src/PhpTypeConverterInterface.php index 3e492725..3007f097 100644 --- a/src/PhpTypeConverterInterface.php +++ b/src/PhpTypeConverterInterface.php @@ -30,7 +30,7 @@ interface PhpTypeConverterInterface * Gets the PHP type of this field. * * @param Configuration|array{} $config - * @param Class_[] $classes + * @param Class_[] $classes */ public function getPhpType(Property $property, array $config = [], array $classes = []): ?string; diff --git a/src/PropertyGenerator/IdPropertyGenerator.php b/src/PropertyGenerator/IdPropertyGenerator.php index 2559f7b1..2f09b9bd 100644 --- a/src/PropertyGenerator/IdPropertyGenerator.php +++ b/src/PropertyGenerator/IdPropertyGenerator.php @@ -19,7 +19,7 @@ final class IdPropertyGenerator implements IdPropertyGeneratorInterface { - public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property { if (!$property) { throw new \LogicException('A property must be given.'); diff --git a/src/PropertyGenerator/IdPropertyGeneratorInterface.php b/src/PropertyGenerator/IdPropertyGeneratorInterface.php index 77b16ca8..df7c1d20 100644 --- a/src/PropertyGenerator/IdPropertyGeneratorInterface.php +++ b/src/PropertyGenerator/IdPropertyGeneratorInterface.php @@ -17,5 +17,5 @@ interface IdPropertyGeneratorInterface { - public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property; + public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property; } diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index 0df61662..e59ad5d8 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -22,7 +22,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface * @param Configuration $config * @param array{} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, Property $property = null): ?Property { if (!$property) { throw new \LogicException('A property must be given.'); diff --git a/src/PropertyGenerator/PropertyGeneratorInterface.php b/src/PropertyGenerator/PropertyGeneratorInterface.php index e82c13f0..c1025284 100644 --- a/src/PropertyGenerator/PropertyGeneratorInterface.php +++ b/src/PropertyGenerator/PropertyGeneratorInterface.php @@ -28,6 +28,6 @@ public function __invoke( Class_ $class, array $context, bool $isCustom = false, - ?Property $property = null + Property $property = null ): ?Property; } diff --git a/src/Schema/Generator.php b/src/Schema/Generator.php index ce34b1a6..81b84a0e 100644 --- a/src/Schema/Generator.php +++ b/src/Schema/Generator.php @@ -36,7 +36,7 @@ public function generate(array $configuration, OutputInterface $output, SymfonyS $graphs = []; foreach ($configuration['vocabularies'] as $uri => $vocab) { $graph = new RdfGraph($uri); - if (0 === strpos($uri, 'http://') || 0 === strpos($uri, 'https://')) { + if (str_starts_with($uri, 'http://') || str_starts_with($uri, 'https://')) { $graph->load($uri, $vocab['format']); } else { $graph->parseFile($uri, $vocab['format']); diff --git a/src/Schema/PropertyGenerator/IdPropertyGenerator.php b/src/Schema/PropertyGenerator/IdPropertyGenerator.php index 93cd83a7..00413794 100644 --- a/src/Schema/PropertyGenerator/IdPropertyGenerator.php +++ b/src/Schema/PropertyGenerator/IdPropertyGenerator.php @@ -25,12 +25,12 @@ final class IdPropertyGenerator implements IdPropertyGeneratorInterface { private IdPropertyGeneratorInterface $idPropertyGenerator; - public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = null) + public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator = null) { $this->idPropertyGenerator = $idPropertyGenerator ?? new CommonIdPropertyGenerator(); } - public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property { $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new SchemaProperty('id')); diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 124e88cf..47e2634b 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -42,7 +42,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface private TypeConverter $typeConverter; private PropertyGeneratorInterface $propertyGenerator; - public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, ?PropertyGeneratorInterface $propertyGenerator = null) + public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, PropertyGeneratorInterface $propertyGenerator = null) { $this->goodRelationsBridge = $goodRelationsBridge; $this->typeConverter = $typeConverter; @@ -59,7 +59,7 @@ public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConver * property: RdfResource * } $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, Property $property = null): ?Property { $type = $context['type']; $typeConfig = $context['typeConfig']; @@ -200,8 +200,8 @@ private function getRanges(RdfResource $range, ?array $propertyConfig, array $co } if ( - (!isset($propertyConfig['range']) || $propertyConfig['range'] === $localName) && - (empty($config['types']) || isset($config['types'][$localName]) || $dataType) + (!isset($propertyConfig['range']) || $propertyConfig['range'] === $localName) + && (empty($config['types']) || isset($config['types'][$localName]) || $dataType) ) { return [$range]; } diff --git a/src/Schema/TypeConverter.php b/src/Schema/TypeConverter.php index 6b0a515b..cc8f4382 100644 --- a/src/Schema/TypeConverter.php +++ b/src/Schema/TypeConverter.php @@ -109,9 +109,9 @@ private function getUri(RdfResource $range): string return $onDatatype->getUri(); } - if ($range->isBNode() && - null !== ($unionOf = $range->get('owl:unionOf')) && - null !== ($rdfFirst = $unionOf->get('rdf:first'))) { + if ($range->isBNode() + && null !== ($unionOf = $range->get('owl:unionOf')) + && null !== ($rdfFirst = $unionOf->get('rdf:first'))) { return $rdfFirst->getUri(); } diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index fda78da9..3195e7a1 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -36,14 +36,11 @@ final class SchemaGeneratorConfiguration implements ConfigurationInterface private ?string $defaultPrefix; - public function __construct(?string $defaultPrefix = null) + public function __construct(string $defaultPrefix = null) { $this->defaultPrefix = $defaultPrefix; } - /** - * {@inheritdoc} - */ public function getConfigTreeBuilder(): TreeBuilder { $namespacePrefix = $this->defaultPrefix ?? 'App\\'; diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index d7d26ca3..7547dc47 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -379,8 +379,8 @@ private function createPropertiesMap(array $graphs, array $types, array $config) /** * @param array{resources: RdfResource[], uris: string[], names: string[]}[] $typesResources - * @param Configuration $config - * @param array $map + * @param Configuration $config + * @param array $map */ private function addPropertyToMap(RdfResource $property, RdfResource $domain, array $typesResources, array $config, array &$map): void { diff --git a/tests/ClassMutator/ClassParentMutatorTest.php b/tests/ClassMutator/ClassParentMutatorTest.php index 82598fbc..2d12ab7f 100644 --- a/tests/ClassMutator/ClassParentMutatorTest.php +++ b/tests/ClassMutator/ClassParentMutatorTest.php @@ -53,7 +53,7 @@ protected function setUp(): void /** * @dataProvider provideInvokeTestCases */ - public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?string $loggerMessage = null): void + public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, string $loggerMessage = null): void { if ($loggerMessage) { $this->loggerProphecy->info($loggerMessage)->shouldBeCalled(); diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index bf4c2e26..8cbe5003 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -75,7 +75,7 @@ protected function setUp(): void /** * @dataProvider provideInvokeTestCases */ - public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, RdfGraph &$graph = null, ?string $loggerMessage = null): void + public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, RdfGraph &$graph = null, string $loggerMessage = null): void { if ($graph) { $this->graph = $graph; From 91822574b3773fa60fa5138d635f1da28481cbb1 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:44:19 +0200 Subject: [PATCH 240/258] fix: phpstan --- src/Model/Property.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Model/Property.php b/src/Model/Property.php index 9378e88e..c44f1944 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -30,6 +30,7 @@ abstract class Property /** @var ?Type the data types (object is not one) */ public ?Type $type = null; + /** @phpstan-ignore-next-line */ public $defaultValue; public ?Class_ $reference = null; public bool $isReadable = true; From d2e95bdda092f49d1bd8f766ca6ba14b76060a9a Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:45:54 +0200 Subject: [PATCH 241/258] docs: update changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb8ad65b..4faebb78 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 5.2.0 + +* feat: improve type detection + ## 5.1.1 * fix: missing unique for self-referencing relations From d1f05035b2b3bddf922a6a34984a2c745d6b776b Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:46:27 +0200 Subject: [PATCH 242/258] chore: add GitHub concurrency --- .github/workflows/ci.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 90da1a07..1db1a212 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -4,6 +4,10 @@ on: push: pull_request: +concurrency: + group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} + cancel-in-progress: true + env: COVERAGE: '0' From d1370421092a6fd67c2f2d334774b078333a77d7 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:59:29 +0200 Subject: [PATCH 243/258] fix: e2e tests --- tests/e2e/customized/App/Schema/Enum/GenderType.php | 6 +++--- tests/e2e/original/App/Schema/Enum/GenderType.php | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/e2e/customized/App/Schema/Enum/GenderType.php b/tests/e2e/customized/App/Schema/Enum/GenderType.php index f2a24993..cbe6dbe4 100644 --- a/tests/e2e/customized/App/Schema/Enum/GenderType.php +++ b/tests/e2e/customized/App/Schema/Enum/GenderType.php @@ -13,9 +13,9 @@ */ class GenderType extends Enum { - /** @var string The female gender. */ - public const FEMALE = 'https://schema.org/Female'; - /** @var string The male gender. */ public const MALE = 'https://schema.org/Male'; + + /** @var string The female gender. */ + public const FEMALE = 'https://schema.org/Female'; } diff --git a/tests/e2e/original/App/Schema/Enum/GenderType.php b/tests/e2e/original/App/Schema/Enum/GenderType.php index f2a24993..cbe6dbe4 100644 --- a/tests/e2e/original/App/Schema/Enum/GenderType.php +++ b/tests/e2e/original/App/Schema/Enum/GenderType.php @@ -13,9 +13,9 @@ */ class GenderType extends Enum { - /** @var string The female gender. */ - public const FEMALE = 'https://schema.org/Female'; - /** @var string The male gender. */ public const MALE = 'https://schema.org/Male'; + + /** @var string The female gender. */ + public const FEMALE = 'https://schema.org/Female'; } From 3adab34da0da003fb834f477cda5daf13c193add Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 15:04:24 +0200 Subject: [PATCH 244/258] fix: replace deprecated GitHub command ::set-output --- .github/workflows/ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1db1a212..7063c239 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,7 +29,7 @@ jobs: - name: Get Composer Cache Directory id: composer-cache - run: echo "::set-output name=dir::$(composer config cache-files-dir)" + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - uses: actions/cache@v3 with: From ef6e444285a3998eb0ceb1fe6e5c59b3dd8d48f7 Mon Sep 17 00:00:00 2001 From: Vincent Chalamon <407859+vincentchalamon@users.noreply.github.com> Date: Thu, 29 Jun 2023 14:36:01 +0200 Subject: [PATCH 245/258] fix(#405): allow to declare multiple operations using the same class --- .../ApiPlatformCoreAttributeGenerator.php | 7 +++++++ src/Model/Class_.php | 2 +- .../ApiPlatformCoreAttributeGeneratorTest.php | 7 +++++++ 3 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 039d1dea..0688e2b5 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -78,6 +78,13 @@ public function generateClassAttributes(Class_ $class): array } else { $arguments['operations'] = []; foreach ($class->operations as $operationMetadataClass => $methodConfig) { + // https://github.com/api-platform/schema-generator/issues/405 + if (\array_key_exists('class', $methodConfig ?? [])) { + /** @var string $operationMetadataClass */ + $operationMetadataClass = $methodConfig['class']; + unset($methodConfig['class']); + } + $arguments['operations'][] = new Literal(sprintf('new %s(...?:)', $operationMetadataClass, ), [$methodConfig ?? []]); diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 89075432..7d892af5 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -47,7 +47,7 @@ abstract class Class_ public bool $isAbstract = false; public bool $hasChild = false; public bool $isEmbeddable = false; - /** @var array> */ + /** @var array> */ public array $operations = []; /** diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index 0f46ca1b..c2a4e637 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -71,6 +71,13 @@ public function provideGenerateClassAttributesCases(): \Generator ]; yield 'with operations' => [$class, [new Attribute('ApiResource', ['types' => ['https://schema.org/WithOperations'], 'operations' => [new Literal('new Get(...?:)', [['routeName' => 'api_about_get']])]])]]; + $class = new SchemaClass('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); + $class->operations = [ + ['class' => 'Get', 'routeName' => 'api_about_get'], + ['class' => 'Get', 'routeName' => 'api_alternate_get'], + ]; + yield 'with numeric operations' => [$class, [new Attribute('ApiResource', ['types' => ['https://schema.org/WithOperations'], 'operations' => [new Literal('new Get(...?:)', [['routeName' => 'api_about_get']]), new Literal('new Get(...?:)', [['routeName' => 'api_alternate_get']])]])]]; + $class = new SchemaClass('WithOperations', new RdfResource('https://schema.org/WithOperations', new RdfGraph())); $class->operations = [ 'item' => ['get' => ['route_name' => 'api_about_get']], From 43e30591ad4aa1012aced6491422ede1c80a9134 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 19 Jul 2023 23:00:32 +0200 Subject: [PATCH 246/258] chore: bump deps and fix CI (#410) * chore: bump deps * fix PHPStan * fix ci * fix e2e tests --- .github/workflows/ci.yml | 4 +- composer.json | 3 +- composer.lock | 1399 ++++++++++------- .../ApiPlatformCoreAttributeGenerator.php | 1 + .../App/OpenApi/Entity/AcademicSession.php | 8 +- .../original/App/Schema/Enum/GenderType.php | 6 +- 6 files changed, 847 insertions(+), 574 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 7063c239..093606b2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -24,6 +24,7 @@ jobs: include: - php: '8.1' coverage: true + phpstan: true steps: - uses: actions/checkout@v3 @@ -48,7 +49,7 @@ jobs: - name: Install prerequisites run: | - wget -O box.phar https://github.com/humbug/box/releases/download/4.2.0/box.phar + wget -O box.phar https://github.com/humbug/box/releases/download/4.3.8/box.phar echo "BOX_BIN=$(pwd)/box.phar" >> $GITHUB_ENV sudo chown -R $(whoami):$(whoami) . @@ -77,6 +78,7 @@ jobs: run: php-cs-fixer fix --dry-run --format=checkstyle --ansi | cs2pr - name: Run phpstan + if: matrix.phpstan run: vendor/bin/phpstan analyse --ansi - name: Run e2e tests diff --git a/composer.json b/composer.json index 8c7cbc23..390e8357 100644 --- a/composer.json +++ b/composer.json @@ -45,13 +45,12 @@ "symfony/filesystem": "^5.2 || ^6.0", "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0", - "nette/utils": "^3.1", "nikic/php-parser": "^4.13", "cebe/php-openapi": "^1.6", "symfony/string": "^5.2 || ^6.0" }, "require-dev": { - "api-platform/core": "^v2.7", + "api-platform/core": "^2.7 || ^3.0", "doctrine/orm": "^2.7", "myclabs/php-enum": "^1.7", "symfony/doctrine-bridge": "^5.2 || ^6.0", diff --git a/composer.lock b/composer.lock index 2c3cdcb3..f2be83b3 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "2551b877faadb75da63c885587caf20d", + "content-hash": "8d7ec2ad8dc62f26690b53d1dbf22ae8", "packages": [ { "name": "cebe/php-openapi", @@ -295,30 +295,30 @@ }, { "name": "doctrine/annotations", - "version": "1.14.2", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/annotations.git", - "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b" + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/ad785217c1e9555a7d6c6c8c9f406395a5e2882b", - "reference": "ad785217c1e9555a7d6c6c8c9f406395a5e2882b", + "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", + "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", "shasum": "" }, "require": { - "doctrine/lexer": "^1 || ^2", + "doctrine/lexer": "^2 || ^3", "ext-tokenizer": "*", - "php": "^7.1 || ^8.0", + "php": "^7.2 || ^8.0", "psr/cache": "^1 || ^2 || ^3" }, "require-dev": { - "doctrine/cache": "^1.11 || ^2.0", - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "~1.4.10 || ^1.8.0", + "doctrine/cache": "^2.0", + "doctrine/coding-standard": "^10", + "phpstan/phpstan": "^1.8.0", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6", + "symfony/cache": "^5.4 || ^6", "vimeo/psalm": "^4.10" }, "suggest": { @@ -365,31 +365,35 @@ ], "support": { "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/1.14.2" + "source": "https://github.com/doctrine/annotations/tree/2.0.1" }, - "time": "2022-12-15T06:48:22+00:00" + "time": "2023-02-02T22:02:53+00:00" }, { "name": "doctrine/deprecations", - "version": "v1.0.0", + "version": "v1.1.1", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de" + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", - "reference": "0e2a4f1f8cdfc7a92ec3b01c9334898c806b30de", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", + "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", "shasum": "" }, "require": { - "php": "^7.1|^8.0" + "php": "^7.1 || ^8.0" }, "require-dev": { "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5|^8.5|^9.5", - "psr/log": "^1|^2|^3" + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -408,34 +412,34 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.0.0" + "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" }, - "time": "2022-05-02T15:47:09+00:00" + "time": "2023-06-03T09:27:29+00:00" }, { "name": "doctrine/inflector", - "version": "2.0.6", + "version": "2.0.8", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024" + "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", - "reference": "d9d313a36c872fd6ee06d9a6cbcf713eaa40f024", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff", + "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff", "shasum": "" }, "require": { "php": "^7.2 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^10", + "doctrine/coding-standard": "^11.0", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", "phpstan/phpstan-strict-rules": "^1.3", "phpunit/phpunit": "^8.5 || ^9.5", - "vimeo/psalm": "^4.25" + "vimeo/psalm": "^4.25 || ^5.4" }, "type": "library", "autoload": { @@ -485,7 +489,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.6" + "source": "https://github.com/doctrine/inflector/tree/2.0.8" }, "funding": [ { @@ -501,7 +505,7 @@ "type": "tidelift" } ], - "time": "2022-10-20T09:10:12+00:00" + "time": "2023-06-16T13:40:37+00:00" }, { "name": "doctrine/lexer", @@ -583,51 +587,53 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.13.2", + "version": "v3.22.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496" + "reference": "92b019f6c8d79aa26349d0db7671d37440dc0ff3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/3952f08a81bd3b1b15e11c3de0b6bf037faa8496", - "reference": "3952f08a81bd3b1b15e11c3de0b6bf037faa8496", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/92b019f6c8d79aa26349d0db7671d37440dc0ff3", + "reference": "92b019f6c8d79aa26349d0db7671d37440dc0ff3", "shasum": "" }, "require": { - "composer/semver": "^3.2", + "composer/semver": "^3.3", "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^1.13", + "doctrine/annotations": "^2", + "doctrine/lexer": "^2 || ^3", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0", + "sebastian/diff": "^4.0 || ^5.0", "symfony/console": "^5.4 || ^6.0", "symfony/event-dispatcher": "^5.4 || ^6.0", "symfony/filesystem": "^5.4 || ^6.0", "symfony/finder": "^5.4 || ^6.0", "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.23", - "symfony/polyfill-php80": "^1.25", - "symfony/polyfill-php81": "^1.25", + "symfony/polyfill-mbstring": "^1.27", + "symfony/polyfill-php80": "^1.27", + "symfony/polyfill-php81": "^1.27", "symfony/process": "^5.4 || ^6.0", "symfony/stopwatch": "^5.4 || ^6.0" }, "require-dev": { + "facile-it/paraunit": "^1.3 || ^2.0", "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^2.0", - "mikey179/vfsstream": "^1.6.10", - "php-coveralls/php-coveralls": "^2.5.2", + "mikey179/vfsstream": "^1.6.11", + "php-coveralls/php-coveralls": "^2.5.3", "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.15", + "phpspec/prophecy": "^1.16", "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.5", "phpunitgoodpractices/polyfill": "^1.6", "phpunitgoodpractices/traits": "^1.9.2", - "symfony/phpunit-bridge": "^6.0", + "symfony/phpunit-bridge": "^6.2.3", "symfony/yaml": "^5.4 || ^6.0" }, "suggest": { @@ -658,9 +664,15 @@ } ], "description": "A tool to automatically fix PHP code style", + "keywords": [ + "Static code analysis", + "fixer", + "standards", + "static analysis" + ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.13.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.22.0" }, "funding": [ { @@ -668,7 +680,7 @@ "type": "github" } ], - "time": "2023-01-02T23:53:50+00:00" + "time": "2023-07-16T23:08:06+00:00" }, { "name": "justinrainbow/json-schema", @@ -742,16 +754,16 @@ }, { "name": "league/html-to-markdown", - "version": "5.1.0", + "version": "5.1.1", "source": { "type": "git", "url": "https://github.com/thephpleague/html-to-markdown.git", - "reference": "e0fc8cf07bdabbcd3765341ecb50c34c271d64e1" + "reference": "0b4066eede55c48f38bcee4fb8f0aa85654390fd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/e0fc8cf07bdabbcd3765341ecb50c34c271d64e1", - "reference": "e0fc8cf07bdabbcd3765341ecb50c34c271d64e1", + "url": "https://api.github.com/repos/thephpleague/html-to-markdown/zipball/0b4066eede55c48f38bcee4fb8f0aa85654390fd", + "reference": "0b4066eede55c48f38bcee4fb8f0aa85654390fd", "shasum": "" }, "require": { @@ -761,11 +773,11 @@ }, "require-dev": { "mikehaertl/php-shellcommand": "^1.1.0", - "phpstan/phpstan": "^0.12.99", + "phpstan/phpstan": "^1.8.8", "phpunit/phpunit": "^8.5 || ^9.2", "scrutinizer/ocular": "^1.6", - "unleashedtech/php-coding-standard": "^2.7", - "vimeo/psalm": "^4.22" + "unleashedtech/php-coding-standard": "^2.7 || ^3.0", + "vimeo/psalm": "^4.22 || ^5.0" }, "bin": [ "bin/html-to-markdown" @@ -807,7 +819,7 @@ ], "support": { "issues": "https://github.com/thephpleague/html-to-markdown/issues", - "source": "https://github.com/thephpleague/html-to-markdown/tree/5.1.0" + "source": "https://github.com/thephpleague/html-to-markdown/tree/5.1.1" }, "funding": [ { @@ -827,27 +839,28 @@ "type": "tidelift" } ], - "time": "2022-03-02T17:24:08+00:00" + "time": "2023-07-12T21:21:09+00:00" }, { "name": "nette/php-generator", - "version": "v4.0.5", + "version": "v4.0.7", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "a8d6abeae5d8c7202cd69600e086a7a72877fc86" + "reference": "de1843fbb692125e307937c85d43937d0dc0c1d4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/a8d6abeae5d8c7202cd69600e086a7a72877fc86", - "reference": "a8d6abeae5d8c7202cd69600e086a7a72877fc86", + "url": "https://api.github.com/repos/nette/php-generator/zipball/de1843fbb692125e307937c85d43937d0dc0c1d4", + "reference": "de1843fbb692125e307937c85d43937d0dc0c1d4", "shasum": "" }, "require": { - "nette/utils": "^3.2.7 || ^4.0", + "nette/utils": "^3.2.9 || ^4.0", "php": ">=8.0 <8.3" }, "require-dev": { + "jetbrains/phpstorm-attributes": "dev-master", "nette/tester": "^2.4", "nikic/php-parser": "^4.15", "phpstan/phpstan": "^1.0", @@ -893,34 +906,36 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.0.5" + "source": "https://github.com/nette/php-generator/tree/v4.0.7" }, - "time": "2022-11-02T20:37:46+00:00" + "time": "2023-04-26T15:09:53+00:00" }, { "name": "nette/utils", - "version": "v3.2.8", + "version": "v4.0.0", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368" + "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", - "reference": "02a54c4c872b99e4ec05c4aec54b5a06eb0f6368", + "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e", + "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e", "shasum": "" }, "require": { - "php": ">=7.2 <8.3" + "php": ">=8.0 <8.3" }, "conflict": { - "nette/di": "<3.0.6" + "nette/finder": "<3", + "nette/schema": "<1.2.2" }, "require-dev": { - "nette/tester": "~2.0", + "jetbrains/phpstorm-attributes": "dev-master", + "nette/tester": "^2.4", "phpstan/phpstan": "^1.0", - "tracy/tracy": "^2.3" + "tracy/tracy": "^2.9" }, "suggest": { "ext-gd": "to use Image", @@ -934,7 +949,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -978,22 +993,22 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v3.2.8" + "source": "https://github.com/nette/utils/tree/v4.0.0" }, - "time": "2022-09-12T23:36:20+00:00" + "time": "2023-02-02T10:41:53+00:00" }, { "name": "nikic/php-parser", - "version": "v4.15.2", + "version": "v4.16.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc" + "reference": "19526a33fb561ef417e822e85f08a00db4059c17" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", - "reference": "f59bbe44bf7d96f24f3e2b4ddc21cd52c1d2adbc", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", + "reference": "19526a33fb561ef417e822e85f08a00db4059c17", "shasum": "" }, "require": { @@ -1034,9 +1049,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" }, - "time": "2022-11-12T15:38:23+00:00" + "time": "2023-06-25T14:52:30+00:00" }, { "name": "psr/cache", @@ -1190,6 +1205,59 @@ }, "time": "2019-01-08T18:20:26+00:00" }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, { "name": "psr/log", "version": "3.0.0", @@ -1242,16 +1310,16 @@ }, { "name": "sebastian/diff", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d" + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/3461e3fccc7cfdfc2720be910d3bd73c69be590d", - "reference": "3461e3fccc7cfdfc2720be910d3bd73c69be590d", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", "shasum": "" }, "require": { @@ -1296,7 +1364,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" }, "funding": [ { @@ -1304,20 +1372,20 @@ "type": "github" } ], - "time": "2020-10-26T13:10:38+00:00" + "time": "2023-05-07T05:35:17+00:00" }, { "name": "sweetrdf/easyrdf", - "version": "1.7.1", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/sweetrdf/easyrdf.git", - "reference": "19ba21288e0aa344227267cab7f8f9c565eee426" + "reference": "feaeb6f602d989c6bc6e482d27426a212e76289a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/19ba21288e0aa344227267cab7f8f9c565eee426", - "reference": "19ba21288e0aa344227267cab7f8f9c565eee426", + "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/feaeb6f602d989c6bc6e482d27426a212e76289a", + "reference": "feaeb6f602d989c6bc6e482d27426a212e76289a", "shasum": "" }, "require": { @@ -1326,19 +1394,21 @@ "ext-pcre": "*", "ext-xmlreader": "*", "lib-libxml": "*", - "php": "^7.1|^8.0" + "php": "^8.0", + "sweetrdf/rdf-helpers": "^1.0" }, "replace": { - "easyrdf/easyrdf": "1.0.*|1.1.*" + "easyrdf/easyrdf": "1.1.*" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.0", + "laminas/laminas-http": "^2", "ml/json-ld": "^1.0", "phpstan/phpstan": "^1.0", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5|^8.5|^9.5", + "phpunit/phpunit": "^9.5.0|^10.0.0", "semsol/arc2": "^2.4", - "zendframework/zend-http": "^2.3" + "zendframework/zend-http": "^2" }, "type": "library", "autoload": { @@ -1381,43 +1451,139 @@ ], "support": { "issues": "https://github.com/sweetrdf/easyrdf/issues", - "source": "https://github.com/sweetrdf/easyrdf/tree/1.7.1" + "source": "https://github.com/sweetrdf/easyrdf/tree/1.9.0" }, - "time": "2022-11-08T08:13:50+00:00" + "time": "2023-06-20T15:05:17+00:00" + }, + { + "name": "sweetrdf/rdf-helpers", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/sweetrdf/rdfHelpers.git", + "reference": "e0ae1d528766aae4c3bfa9e4312f02efbb6830b5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sweetrdf/rdfHelpers/zipball/e0ae1d528766aae4c3bfa9e4312f02efbb6830b5", + "reference": "e0ae1d528766aae4c3bfa9e4312f02efbb6830b5", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "sweetrdf/rdf-interface": "^1.0.0", + "zozlak/rdf-constants": "^1.1" + }, + "require-dev": { + "phpstan/phpstan": "*", + "phpunit/php-code-coverage": "^9.2", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "rdfHelpers\\": "src/rdfHelpers" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mateusz Żółtak", + "email": "zozlak@zozlak.org", + "role": "Developer" + } + ], + "description": "Set of low level helpers for implementing rdfInterface", + "homepage": "https://github.com/sweetrdf/rdfHelpers", + "support": { + "issues": "https://github.com/sweetrdf/rdfHelpers/issues", + "source": "https://github.com/sweetrdf/rdfHelpers/tree/1.0.1" + }, + "time": "2023-04-02T08:59:30+00:00" + }, + { + "name": "sweetrdf/rdf-interface", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sweetrdf/rdfInterface.git", + "reference": "1d7645cc2f138017fe7d1421e3b0b479d6bee4a5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/1d7645cc2f138017fe7d1421e3b0b479d6bee4a5", + "reference": "1d7645cc2f138017fe7d1421e3b0b479d6bee4a5", + "shasum": "" + }, + "require": { + "php": ">=8.0", + "psr/http-message": "^1.0", + "zozlak/rdf-constants": "*" + }, + "require-dev": { + "phpstan/phpstan": "*", + "squizlabs/php_codesniffer": "*" + }, + "type": "library", + "autoload": { + "psr-4": { + "rdfInterface\\": "src/rdfInterface" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mateusz Żółtak", + "email": "zozlak@zozlak.org", + "role": "Developer" + } + ], + "description": "A common RDF interface for PHP RDF libraries.", + "homepage": "https://github.com/sweetrdf/rdfInterface", + "support": { + "issues": "https://github.com/sweetrdf/rdfInterface/issues", + "source": "https://github.com/sweetrdf/rdfInterface/tree/1.0.0" + }, + "time": "2022-11-01T09:27:45+00:00" }, { "name": "symfony/config", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "ebf27792246165a2a0b6b69ec9c620cac8c5a2f0" + "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/ebf27792246165a2a0b6b69ec9c620cac8c5a2f0", - "reference": "ebf27792246165a2a0b6b69ec9c620cac8c5a2f0", + "url": "https://api.github.com/repos/symfony/config/zipball/a5e00dec161b08c946a2c16eed02adbeedf827ae", + "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/filesystem": "^5.4|^6.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<5.4" + "symfony/finder": "<5.4", + "symfony/service-contracts": "<2.5" }, "require-dev": { "symfony/event-dispatcher": "^5.4|^6.0", "symfony/finder": "^5.4|^6.0", "symfony/messenger": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/yaml": "^5.4|^6.0" }, - "suggest": { - "symfony/yaml": "To use the yaml reference dumper" - }, "type": "library", "autoload": { "psr-4": { @@ -1444,7 +1610,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v6.2.0" + "source": "https://github.com/symfony/config/tree/v6.3.0" }, "funding": [ { @@ -1460,27 +1626,27 @@ "type": "tidelift" } ], - "time": "2022-11-02T09:08:04+00:00" + "time": "2023-04-25T10:46:17+00:00" }, { "name": "symfony/console", - "version": "v6.2.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "0f579613e771dba2dbb8211c382342a641f5da06" + "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/0f579613e771dba2dbb8211c382342a641f5da06", - "reference": "0f579613e771dba2dbb8211c382342a641f5da06", + "url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", + "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/string": "^5.4|^6.0" }, "conflict": { @@ -1502,12 +1668,6 @@ "symfony/process": "^5.4|^6.0", "symfony/var-dumper": "^5.4|^6.0" }, - "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" - }, "type": "library", "autoload": { "psr-4": { @@ -1535,12 +1695,12 @@ "homepage": "https://symfony.com/", "keywords": [ "cli", - "command line", + "command-line", "console", "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.2.3" + "source": "https://github.com/symfony/console/tree/v6.3.0" }, "funding": [ { @@ -1556,20 +1716,20 @@ "type": "tidelift" } ], - "time": "2022-12-28T14:26:22+00:00" + "time": "2023-05-29T12:49:39+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3" + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/1ee04c65529dea5d8744774d474e7cbd2f1206d3", - "reference": "1ee04c65529dea5d8744774d474e7cbd2f1206d3", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", + "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", "shasum": "" }, "require": { @@ -1578,7 +1738,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -1607,7 +1767,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" }, "funding": [ { @@ -1623,28 +1783,29 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v6.2.2", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1" + "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3ffeb31139b49bf6ef0bc09d1db95eac053388d1", - "reference": "3ffeb31139b49bf6ef0bc09d1db95eac053388d1", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", + "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/event-dispatcher-contracts": "^2|^3" + "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<5.4", + "symfony/service-contracts": "<2.5" }, "provide": { "psr/event-dispatcher-implementation": "1.0", @@ -1657,13 +1818,9 @@ "symfony/error-handler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/http-foundation": "^5.4|^6.0", - "symfony/service-contracts": "^1.1|^2|^3", + "symfony/service-contracts": "^2.5|^3", "symfony/stopwatch": "^5.4|^6.0" }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, "type": "library", "autoload": { "psr-4": { @@ -1690,7 +1847,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.2.2" + "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0" }, "funding": [ { @@ -1706,33 +1863,30 @@ "type": "tidelift" } ], - "time": "2022-12-14T16:11:27+00:00" + "time": "2023-04-21T14:41:17+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "0782b0b52a737a05b4383d0df35a474303cabdae" + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0782b0b52a737a05b4383d0df35a474303cabdae", - "reference": "0782b0b52a737a05b4383d0df35a474303cabdae", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", + "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", "shasum": "" }, "require": { "php": ">=8.1", "psr/event-dispatcher": "^1" }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -1769,7 +1923,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" }, "funding": [ { @@ -1785,20 +1939,20 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/filesystem", - "version": "v6.2.0", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "50b2523c874605cf3d4acf7a9e2b30b6a440a016" + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/50b2523c874605cf3d4acf7a9e2b30b6a440a016", - "reference": "50b2523c874605cf3d4acf7a9e2b30b6a440a016", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", "shasum": "" }, "require": { @@ -1832,7 +1986,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.2.0" + "source": "https://github.com/symfony/filesystem/tree/v6.3.1" }, "funding": [ { @@ -1848,20 +2002,20 @@ "type": "tidelift" } ], - "time": "2022-11-20T13:01:27+00:00" + "time": "2023-06-01T08:30:39+00:00" }, { "name": "symfony/finder", - "version": "v6.2.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "81eefbddfde282ee33b437ba5e13d7753211ae8e" + "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/81eefbddfde282ee33b437ba5e13d7753211ae8e", - "reference": "81eefbddfde282ee33b437ba5e13d7753211ae8e", + "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2", "shasum": "" }, "require": { @@ -1896,7 +2050,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.2.3" + "source": "https://github.com/symfony/finder/tree/v6.3.0" }, "funding": [ { @@ -1912,25 +2066,25 @@ "type": "tidelift" } ], - "time": "2022-12-22T17:55:15+00:00" + "time": "2023-04-02T01:25:41+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "d28f02acde71ff75e957082cd36e973df395f626" + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/d28f02acde71ff75e957082cd36e973df395f626", - "reference": "d28f02acde71ff75e957082cd36e973df395f626", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", + "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3" + "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -1963,7 +2117,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.2.0" + "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" }, "funding": [ { @@ -1979,7 +2133,7 @@ "type": "tidelift" } ], - "time": "2022-11-02T09:08:04+00:00" + "time": "2023-05-12T14:21:09+00:00" }, { "name": "symfony/polyfill-ctype", @@ -2475,16 +2629,16 @@ }, { "name": "symfony/process", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "ba6e55359f8f755fe996c58a81e00eaa67a35877" + "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/ba6e55359f8f755fe996c58a81e00eaa67a35877", - "reference": "ba6e55359f8f755fe996c58a81e00eaa67a35877", + "url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628", + "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628", "shasum": "" }, "require": { @@ -2516,7 +2670,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v6.2.0" + "source": "https://github.com/symfony/process/tree/v6.3.0" }, "funding": [ { @@ -2532,20 +2686,20 @@ "type": "tidelift" } ], - "time": "2022-11-02T09:08:04+00:00" + "time": "2023-05-19T08:06:44+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75" + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/aac98028c69df04ee77eb69b96b86ee51fbf4b75", - "reference": "aac98028c69df04ee77eb69b96b86ee51fbf4b75", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", "shasum": "" }, "require": { @@ -2555,13 +2709,10 @@ "conflict": { "ext-psr": "<1.1|>=2" }, - "suggest": { - "symfony/service-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -2601,7 +2752,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" }, "funding": [ { @@ -2617,25 +2768,25 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-23T14:45:45+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7" + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/266636bb8f3fbdccc302491df7b3a1b9a8c238a7", - "reference": "266636bb8f3fbdccc302491df7b3a1b9a8c238a7", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/service-contracts": "^1|^2|^3" + "symfony/service-contracts": "^2.5|^3" }, "type": "library", "autoload": { @@ -2663,7 +2814,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.2.0" + "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" }, "funding": [ { @@ -2679,20 +2830,20 @@ "type": "tidelift" } ], - "time": "2022-09-28T16:00:52+00:00" + "time": "2023-02-16T10:14:28+00:00" }, { "name": "symfony/string", - "version": "v6.2.2", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "863219fd713fa41cbcd285a79723f94672faff4d" + "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/863219fd713fa41cbcd285a79723f94672faff4d", - "reference": "863219fd713fa41cbcd285a79723f94672faff4d", + "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f", + "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f", "shasum": "" }, "require": { @@ -2703,13 +2854,13 @@ "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/translation-contracts": "<2.0" + "symfony/translation-contracts": "<2.5" }, "require-dev": { "symfony/error-handler": "^5.4|^6.0", "symfony/http-client": "^5.4|^6.0", "symfony/intl": "^6.2", - "symfony/translation-contracts": "^2.0|^3.0", + "symfony/translation-contracts": "^2.5|^3.0", "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", @@ -2749,7 +2900,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.2.2" + "source": "https://github.com/symfony/string/tree/v6.3.0" }, "funding": [ { @@ -2765,20 +2916,20 @@ "type": "tidelift" } ], - "time": "2022-12-14T16:11:27+00:00" + "time": "2023-03-21T21:06:29+00:00" }, { "name": "symfony/yaml", - "version": "v6.2.2", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3" + "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3", - "reference": "6ed8243aa5f2cb5a57009f826b5e7fb3c4200cf3", + "url": "https://api.github.com/repos/symfony/yaml/zipball/a9a8337aa641ef2aa39c3e028f9107ec391e5927", + "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927", "shasum": "" }, "require": { @@ -2791,9 +2942,6 @@ "require-dev": { "symfony/console": "^5.4|^6.0" }, - "suggest": { - "symfony/console": "For validating YAML files using the lint command" - }, "bin": [ "Resources/bin/yaml-lint" ], @@ -2823,7 +2971,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.2.2" + "source": "https://github.com/symfony/yaml/tree/v6.3.0" }, "funding": [ { @@ -2839,20 +2987,20 @@ "type": "tidelift" } ], - "time": "2022-12-14T16:11:27+00:00" + "time": "2023-04-28T13:28:14+00:00" }, { "name": "twig/twig", - "version": "v3.5.0", + "version": "v3.6.1", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72" + "reference": "7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/3ffcf4b7d890770466da3b2666f82ac054e7ec72", - "reference": "3ffcf4b7d890770466da3b2666f82ac054e7ec72", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd", + "reference": "7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd", "shasum": "" }, "require": { @@ -2861,15 +3009,10 @@ "symfony/polyfill-mbstring": "^1.3" }, "require-dev": { - "psr/container": "^1.0", + "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.5-dev" - } - }, "autoload": { "psr-4": { "Twig\\": "src/" @@ -2903,7 +3046,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.5.0" + "source": "https://github.com/twigphp/Twig/tree/v3.6.1" }, "funding": [ { @@ -2915,57 +3058,99 @@ "type": "tidelift" } ], - "time": "2022-12-27T12:28:18+00:00" + "time": "2023-06-08T12:52:13+00:00" + }, + { + "name": "zozlak/rdf-constants", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/zozlak/RdfConstants.git", + "reference": "a8de0b50d23b213a68784ec2cec22b4ad838012b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/zozlak/RdfConstants/zipball/a8de0b50d23b213a68784ec2cec22b4ad838012b", + "reference": "a8de0b50d23b213a68784ec2cec22b4ad838012b", + "shasum": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "zozlak\\": "src/zozlak" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mateusz Żółtak", + "email": "zozlak@zozlak.org" + } + ], + "description": "A set of commonly used RDF and XSD constants", + "homepage": "https://github.com/zozlak/RdfConstants", + "support": { + "issues": "https://github.com/zozlak/RdfConstants/issues", + "source": "https://github.com/zozlak/RdfConstants/tree/1.2.1" + }, + "time": "2022-08-05T12:50:50+00:00" } ], "packages-dev": [ { "name": "api-platform/core", - "version": "v2.7.5", + "version": "v3.1.12", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "b670958db633d66b05bc46ff34c3bb7c1b306c70" + "reference": "1fe505a9d8fd235a8d7e4aa0f245f382f65578f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/b670958db633d66b05bc46ff34c3bb7c1b306c70", - "reference": "b670958db633d66b05bc46ff34c3bb7c1b306c70", + "url": "https://api.github.com/repos/api-platform/core/zipball/1fe505a9d8fd235a8d7e4aa0f245f382f65578f8", + "reference": "1fe505a9d8fd235a8d7e4aa0f245f382f65578f8", "shasum": "" }, "require": { "doctrine/inflector": "^1.0 || ^2.0", - "php": ">=7.1", + "php": ">=8.1", "psr/cache": "^1.0 || ^2.0 || ^3.0", "psr/container": "^1.0 || ^2.0", - "symfony/deprecation-contracts": "^2.1 || ^3.0", - "symfony/http-foundation": "^4.4 || ^5.1 || ^6.0", - "symfony/http-kernel": "^4.4 || ^5.1 || ^6.0", - "symfony/property-access": "^3.4.19 || ^4.4 || ^5.1 || ^6.0", - "symfony/property-info": "^3.4 || ^4.4 || ^5.2.1 || ^6.0", - "symfony/serializer": "^4.4 || ^5.1 || ^6.0", - "symfony/web-link": "^4.4 || ^5.1 || ^6.0", - "willdurand/negotiation": "^2.0.3 || ^3.0" + "symfony/deprecation-contracts": "^3.1", + "symfony/http-foundation": "^6.1", + "symfony/http-kernel": "^6.1", + "symfony/property-access": "^6.1", + "symfony/property-info": "^6.1", + "symfony/serializer": "^6.1", + "symfony/web-link": "^6.1", + "willdurand/negotiation": "^3.0" }, "conflict": { - "doctrine/common": "<2.7", + "doctrine/common": "<3.2.2", "doctrine/dbal": "<2.10", - "doctrine/mongodb-odm": "<2.2", + "doctrine/mongodb-odm": "<2.4", + "doctrine/orm": "<2.14.0", "doctrine/persistence": "<1.3", - "elasticsearch/elasticsearch": ">=8.0" + "elasticsearch/elasticsearch": ">=8.0", + "phpspec/prophecy": "<1.15", + "phpunit/phpunit": "<9.5", + "symfony/service-contracts": "<3", + "symfony/var-exporter": "<6.1.1" }, "require-dev": { "behat/behat": "^3.1", "behat/mink": "^1.9@dev", - "doctrine/annotations": "^1.7", "doctrine/cache": "^1.11 || ^2.1", - "doctrine/common": "^2.11 || ^3.0", + "doctrine/common": "^3.2.2", "doctrine/data-fixtures": "^1.2.2", - "doctrine/dbal": "^2.6 || ^3.0", + "doctrine/dbal": "^3.4.0", "doctrine/doctrine-bundle": "^1.12 || ^2.0", "doctrine/mongodb-odm": "^2.2", "doctrine/mongodb-odm-bundle": "^4.0", - "doctrine/orm": "^2.6.4", + "doctrine/orm": "^2.14", "elasticsearch/elasticsearch": "^7.11.0", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", @@ -2973,10 +3158,9 @@ "guzzlehttp/guzzle": "^6.0 || ^7.0", "jangregor/phpstan-prophecy": "^1.0", "justinrainbow/json-schema": "^5.2.1", - "phpdocumentor/reflection-docblock": "^3.0 || ^4.0 || ^5.1", - "phpdocumentor/type-resolver": "^0.3 || ^0.4 || ^1.4", - "phpspec/prophecy": "^1.10", + "phpspec/prophecy-phpunit": "^2.0", "phpstan/extension-installer": "^1.1", + "phpstan/phpdoc-parser": "^1.13", "phpstan/phpstan": "^1.1", "phpstan/phpstan-doctrine": "^1.0", "phpstan/phpstan-phpunit": "^1.0", @@ -2984,44 +3168,45 @@ "psr/log": "^1.0 || ^2.0 || ^3.0", "ramsey/uuid": "^3.7 || ^4.0", "ramsey/uuid-doctrine": "^1.4", - "soyuka/contexts": "dev-main", + "soyuka/contexts": "^3.3.6", "soyuka/stubs-mongodb": "^1.0", - "symfony/asset": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/browser-kit": "^4.4 || ^5.1 || ^6.0", - "symfony/cache": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/config": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/console": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/css-selector": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/debug": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/dependency-injection": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/doctrine-bridge": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/dom-crawler": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/event-dispatcher": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/expression-language": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/finder": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/form": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/framework-bundle": "^4.4 || ^5.1 || ^6.0", - "symfony/http-client": "^4.4 || ^5.1 || ^6.0", - "symfony/intl": "^4.4 || ^5.3 || ^6.0", + "symfony/asset": "^6.1", + "symfony/browser-kit": "^6.1", + "symfony/cache": "^6.1", + "symfony/config": "^6.1", + "symfony/console": "^6.1", + "symfony/css-selector": "^6.1", + "symfony/dependency-injection": "^6.1", + "symfony/doctrine-bridge": "^6.1", + "symfony/dom-crawler": "^6.1", + "symfony/error-handler": "^6.1", + "symfony/event-dispatcher": "^6.1", + "symfony/expression-language": "^6.1", + "symfony/finder": "^6.1", + "symfony/form": "^6.1", + "symfony/framework-bundle": "^6.1", + "symfony/http-client": "^6.1", + "symfony/intl": "^6.1", "symfony/maker-bundle": "^1.24", "symfony/mercure-bundle": "*", - "symfony/messenger": "^4.4 || ^5.1 || ^6.0", - "symfony/phpunit-bridge": "^5.4 || ^6.0", - "symfony/routing": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/security-bundle": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/security-core": "^4.4 || ^5.1 || ^6.0", - "symfony/twig-bundle": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/validator": "^3.4 || ^4.4 || ^5.1 || ^6.0", - "symfony/web-profiler-bundle": "^4.4 || ^5.1 || ^6.0", - "symfony/yaml": "^3.4 || ^4.4 || ^5.1 || ^6.0", + "symfony/messenger": "^6.1", + "symfony/phpunit-bridge": "^6.1", + "symfony/routing": "^6.1", + "symfony/security-bundle": "^6.1", + "symfony/security-core": "^6.1", + "symfony/twig-bundle": "^6.1", + "symfony/uid": "^6.1", + "symfony/validator": "^6.1", + "symfony/web-profiler-bundle": "^6.1", + "symfony/yaml": "^6.1", "twig/twig": "^1.42.3 || ^2.12 || ^3.0", - "webonyx/graphql-php": "^14.0" + "webonyx/graphql-php": "^14.0 || ^15.0" }, "suggest": { "doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.", "elasticsearch/elasticsearch": "To support Elasticsearch.", "ocramius/package-versions": "To display the API Platform's version in the debug bar.", - "phpdocumentor/reflection-docblock": "To support extracting metadata from PHPDoc.", + "phpstan/phpdoc-parser": "To support extracting metadata from PHPDoc.", "psr/cache-implementation": "To use metadata caching.", "ramsey/uuid": "To support Ramsey's UUID identifiers.", "symfony/cache": "To have metadata caching when using Symfony integration.", @@ -3038,16 +3223,13 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.7.x-dev" + "dev-main": "3.2.x-dev" }, "symfony": { - "require": "^3.4 || ^4.4 || ^5.1 || ^6.0" + "require": "^6.1" } }, "autoload": { - "files": [ - "src/deprecation.php" - ], "psr-4": { "ApiPlatform\\": "src/" } @@ -3078,7 +3260,7 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v2.7.5" + "source": "https://github.com/api-platform/core/tree/v3.1.12" }, "funding": [ { @@ -3086,7 +3268,7 @@ "type": "tidelift" } ], - "time": "2022-11-25T08:03:09+00:00" + "time": "2023-05-24T19:23:57+00:00" }, { "name": "doctrine/cache", @@ -3360,16 +3542,16 @@ }, { "name": "doctrine/dbal", - "version": "3.5.2", + "version": "3.6.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "63e513cebbbaf96a6795e5c5ee34d205831bfc85" + "reference": "19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/63e513cebbbaf96a6795e5c5ee34d205831bfc85", - "reference": "63e513cebbbaf96a6795e5c5ee34d205831bfc85", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f", + "reference": "19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f", "shasum": "" }, "require": { @@ -3382,13 +3564,14 @@ "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "11.0.0", + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2022.3", - "phpstan/phpstan": "1.9.2", - "phpstan/phpstan-strict-rules": "^1.4", - "phpunit/phpunit": "9.5.27", + "phpstan/phpstan": "1.10.14", + "phpstan/phpstan-strict-rules": "^1.5", + "phpunit/phpunit": "9.6.7", "psalm/plugin-phpunit": "0.18.4", - "squizlabs/php_codesniffer": "3.7.1", + "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", "vimeo/psalm": "4.30.0" @@ -3451,7 +3634,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.5.2" + "source": "https://github.com/doctrine/dbal/tree/3.6.4" }, "funding": [ { @@ -3467,7 +3650,7 @@ "type": "tidelift" } ], - "time": "2022-12-19T08:17:34+00:00" + "time": "2023-06-15T07:40:12+00:00" }, { "name": "doctrine/event-manager", @@ -3562,30 +3745,30 @@ }, { "name": "doctrine/instantiator", - "version": "1.5.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", - "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^11", + "doctrine/coding-standard": "^11", "ext-pdo": "*", "ext-phar": "*", - "phpbench/phpbench": "^0.16 || ^1", - "phpstan/phpstan": "^1.4", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "vimeo/psalm": "^4.30 || ^5.4" + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" }, "type": "library", "autoload": { @@ -3612,7 +3795,7 @@ ], "support": { "issues": "https://github.com/doctrine/instantiator/issues", - "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, "funding": [ { @@ -3628,33 +3811,33 @@ "type": "tidelift" } ], - "time": "2022-12-30T00:15:36+00:00" + "time": "2022-12-30T00:23:10+00:00" }, { "name": "doctrine/orm", - "version": "2.14.0", + "version": "2.15.3", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "f82485e651763fbd1b34879726f4d3b91c358bd9" + "reference": "4c3bd208018c26498e5f682aaad45fa00ea307d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/f82485e651763fbd1b34879726f4d3b91c358bd9", - "reference": "f82485e651763fbd1b34879726f4d3b91c358bd9", + "url": "https://api.github.com/repos/doctrine/orm/zipball/4c3bd208018c26498e5f682aaad45fa00ea307d5", + "reference": "4c3bd208018c26498e5f682aaad45fa00ea307d5", "shasum": "" }, "require": { "composer-runtime-api": "^2", "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5 || ^2.0", + "doctrine/collections": "^1.5 || ^2.1", "doctrine/common": "^3.0.3", "doctrine/dbal": "^2.13.1 || ^3.2", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", - "doctrine/instantiator": "^1.3", - "doctrine/lexer": "^1.2.3 || ^2", + "doctrine/instantiator": "^1.3 || ^2", + "doctrine/lexer": "^2", "doctrine/persistence": "^2.4 || ^3", "ext-ctype": "*", "php": "^7.1 || ^8.0", @@ -3668,16 +3851,16 @@ }, "require-dev": { "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^11.0", + "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.9.4", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "phpstan/phpstan": "~1.4.10 || 1.10.18", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", - "squizlabs/php_codesniffer": "3.7.1", + "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.3.0" + "vimeo/psalm": "4.30.0 || 5.12.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -3727,22 +3910,22 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.14.0" + "source": "https://github.com/doctrine/orm/tree/2.15.3" }, - "time": "2022-12-19T21:51:58+00:00" + "time": "2023-06-22T12:36:06+00:00" }, { "name": "doctrine/persistence", - "version": "3.1.2", + "version": "3.2.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "b44d128311af55275dbed6a4558ca59a2b9f9387" + "reference": "63fee8c33bef740db6730eb2a750cd3da6495603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/b44d128311af55275dbed6a4558ca59a2b9f9387", - "reference": "b44d128311af55275dbed6a4558ca59a2b9f9387", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/63fee8c33bef740db6730eb2a750cd3da6495603", + "reference": "63fee8c33bef740db6730eb2a750cd3da6495603", "shasum": "" }, "require": { @@ -3811,7 +3994,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.1.2" + "source": "https://github.com/doctrine/persistence/tree/3.2.0" }, "funding": [ { @@ -3827,20 +4010,20 @@ "type": "tidelift" } ], - "time": "2022-12-19T13:58:18+00:00" + "time": "2023-05-17T18:32:04+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.0", + "version": "1.11.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614" + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/14daed4296fae74d9e3201d2c4925d1acb7aa614", - "reference": "14daed4296fae74d9e3201d2c4925d1acb7aa614", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { @@ -3878,7 +4061,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.0" + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { @@ -3886,7 +4069,7 @@ "type": "tidelift" } ], - "time": "2022-03-03T13:19:32+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { "name": "myclabs/php-enum", @@ -4174,24 +4357,27 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.6.2", + "version": "1.7.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d" + "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/48f445a408c131e38cab1c235aa6d2bb7a0bb20d", - "reference": "48f445a408c131e38cab1c235aa6d2bb7a0bb20d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b2fe4d22a5426f38e014855322200b97b5362c0d", + "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.0", "php": "^7.4 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" + "phpdocumentor/reflection-common": "^2.0", + "phpstan/phpdoc-parser": "^1.13" }, "require-dev": { "ext-tokenizer": "*", + "phpbench/phpbench": "^1.2", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.1", @@ -4223,26 +4409,26 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.2" }, - "time": "2022-10-14T12:47:21+00:00" + "time": "2023-05-30T18:13:47+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.16.0", + "version": "v1.17.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359" + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/be8cac52a0827776ff9ccda8c381ac5b71aeb359", - "reference": "be8cac52a0827776ff9ccda8c381ac5b71aeb359", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.2", + "doctrine/instantiator": "^1.2 || ^2.0", "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", @@ -4250,6 +4436,7 @@ }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", + "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", @@ -4290,22 +4477,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.16.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.17.0" }, - "time": "2022-11-29T15:06:56+00:00" + "time": "2023-02-02T15:41:36+00:00" }, { "name": "phpspec/prophecy-phpunit", - "version": "v2.0.1", + "version": "v2.0.2", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "2d7a9df55f257d2cba9b1d0c0963a54960657177" + "reference": "9f26c224a2fa335f33e6666cc078fbf388255e87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/2d7a9df55f257d2cba9b1d0c0963a54960657177", - "reference": "2d7a9df55f257d2cba9b1d0c0963a54960657177", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/9f26c224a2fa335f33e6666cc078fbf388255e87", + "reference": "9f26c224a2fa335f33e6666cc078fbf388255e87", "shasum": "" }, "require": { @@ -4342,22 +4529,69 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy-phpunit/issues", - "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.0.1" + "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.0.2" + }, + "time": "2023-04-18T11:58:05+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.22.1", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "65c39594fbd8c67abfc68bb323f86447bab79cc0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/65c39594fbd8c67abfc68bb323f86447bab79cc0", + "reference": "65c39594fbd8c67abfc68bb323f86447bab79cc0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "doctrine/annotations": "^2.0", + "nikic/php-parser": "^4.15", + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.5", + "phpstan/phpstan-phpunit": "^1.1", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" }, - "time": "2020-07-09T08:33:42+00:00" + "type": "library", + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.22.1" + }, + "time": "2023-06-29T20:46:06+00:00" }, { "name": "phpstan/phpstan", - "version": "1.9.5", + "version": "1.10.26", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "4d18c5d98965029c2aa1ccbd91dc22e7ba8c5034" + "reference": "5d660cbb7e1b89253a47147ae44044f49832351f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/4d18c5d98965029c2aa1ccbd91dc22e7ba8c5034", - "reference": "4d18c5d98965029c2aa1ccbd91dc22e7ba8c5034", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5d660cbb7e1b89253a47147ae44044f49832351f", + "reference": "5d660cbb7e1b89253a47147ae44044f49832351f", "shasum": "" }, "require": { @@ -4386,8 +4620,11 @@ "static analysis" ], "support": { + "docs": "https://phpstan.org/user-guide/getting-started", + "forum": "https://github.com/phpstan/phpstan/discussions", "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.9.5" + "security": "https://github.com/phpstan/phpstan/security/policy", + "source": "https://github.com/phpstan/phpstan-src" }, "funding": [ { @@ -4403,27 +4640,27 @@ "type": "tidelift" } ], - "time": "2023-01-02T21:35:42+00:00" + "time": "2023-07-19T12:44:37+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.23", + "version": "9.2.26", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c" + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", - "reference": "9f1f0f9a2fbb680b26d1cf9b61b6eac43a6e4e9c", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.14", + "nikic/php-parser": "^4.15", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4438,8 +4675,8 @@ "phpunit/phpunit": "^9.3" }, "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "type": "library", "extra": { @@ -4472,7 +4709,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.23" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" }, "funding": [ { @@ -4480,7 +4717,7 @@ "type": "github" } ], - "time": "2022-12-28T12:41:10+00:00" + "time": "2023-03-06T12:58:08+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4725,20 +4962,20 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.27", + "version": "9.6.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38" + "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a2bc7ffdca99f92d959b3f2270529334030bba38", - "reference": "a2bc7ffdca99f92d959b3f2270529334030bba38", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a6d351645c3fe5a30f5e86be6577d946af65a328", + "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1", + "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", @@ -4767,8 +5004,8 @@ "sebastian/version": "^3.0.2" }, "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, "bin": [ "phpunit" @@ -4776,7 +5013,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.5-dev" + "dev-master": "9.6-dev" } }, "autoload": { @@ -4807,7 +5044,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.27" + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.10" }, "funding": [ { @@ -4823,7 +5061,7 @@ "type": "tidelift" } ], - "time": "2022-12-09T07:31:23+00:00" + "time": "2023-07-10T04:04:23+00:00" }, { "name": "psr/link", @@ -5181,16 +5419,16 @@ }, { "name": "sebastian/environment", - "version": "5.1.4", + "version": "5.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7" + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/1b5dff7bb151a4db11d49d90e5408e4e938270f7", - "reference": "1b5dff7bb151a4db11d49d90e5408e4e938270f7", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", "shasum": "" }, "require": { @@ -5232,7 +5470,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.4" + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" }, "funding": [ { @@ -5240,7 +5478,7 @@ "type": "github" } ], - "time": "2022-04-03T09:37:03+00:00" + "time": "2023-02-03T06:03:51+00:00" }, { "name": "sebastian/exporter", @@ -5554,16 +5792,16 @@ }, { "name": "sebastian/recursion-context", - "version": "4.0.4", + "version": "4.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172" + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/cd9d8cf3c5804de4341c283ed787f099f5506172", - "reference": "cd9d8cf3c5804de4341c283ed787f099f5506172", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", "shasum": "" }, "require": { @@ -5602,10 +5840,10 @@ } ], "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" }, "funding": [ { @@ -5613,7 +5851,7 @@ "type": "github" } ], - "time": "2020-10-26T13:17:30+00:00" + "time": "2023-02-03T06:07:39+00:00" }, { "name": "sebastian/resource-operations", @@ -5672,16 +5910,16 @@ }, { "name": "sebastian/type", - "version": "3.2.0", + "version": "3.2.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e" + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", - "reference": "fb3fe09c5f0bae6bc27ef3ce933a1e0ed9464b6e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", "shasum": "" }, "require": { @@ -5716,7 +5954,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" }, "funding": [ { @@ -5724,7 +5962,7 @@ "type": "github" } ], - "time": "2022-09-12T14:47:03+00:00" + "time": "2023-02-03T06:13:03+00:00" }, { "name": "sebastian/version", @@ -5781,56 +6019,59 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.2.3", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "f0f0d9d81a172a334c29f536500475c741a5d4c0" + "reference": "594263c7d2677022a16e4f39d20070463ba03888" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/f0f0d9d81a172a334c29f536500475c741a5d4c0", - "reference": "f0f0d9d81a172a334c29f536500475c741a5d4c0", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/594263c7d2677022a16e4f39d20070463ba03888", + "reference": "594263c7d2677022a16e4f39d20070463ba03888", "shasum": "" }, "require": { "doctrine/event-manager": "^1.2|^2", "doctrine/persistence": "^2|^3", "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/service-contracts": "^1.1|^2|^3" + "symfony/service-contracts": "^2.5|^3" }, "conflict": { + "doctrine/annotations": "<1.13.1", "doctrine/dbal": "<2.13.1", "doctrine/lexer": "<1.1", - "doctrine/orm": "<2.7.4", - "phpunit/phpunit": "<5.4.3", + "doctrine/orm": "<2.12", "symfony/cache": "<5.4", - "symfony/dependency-injection": "<5.4", - "symfony/form": "<5.4", + "symfony/dependency-injection": "<6.2", + "symfony/form": "<5.4.21|>=6,<6.2.7", + "symfony/http-foundation": "<6.3", "symfony/http-kernel": "<6.2", + "symfony/lock": "<6.3", "symfony/messenger": "<5.4", "symfony/property-info": "<5.4", "symfony/security-bundle": "<5.4", "symfony/security-core": "<6.0", - "symfony/validator": "<5.4" + "symfony/validator": "<5.4.25|>=6,<6.2.12|>=6.3,<6.3.1" }, "require-dev": { - "doctrine/annotations": "^1.10.4|^2", + "doctrine/annotations": "^1.13.1|^2", "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", "doctrine/dbal": "^2.13.1|^3.0", - "doctrine/orm": "^2.7.4", + "doctrine/orm": "^2.12", "psr/log": "^1|^2|^3", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", + "symfony/dependency-injection": "^6.2", "symfony/doctrine-messenger": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", - "symfony/form": "^5.4.9|^6.0.9", - "symfony/http-kernel": "^6.2", + "symfony/form": "^5.4.21|^6.2.7", + "symfony/http-kernel": "^6.3", + "symfony/lock": "^6.3", "symfony/messenger": "^5.4|^6.0", "symfony/property-access": "^5.4|^6.0", "symfony/property-info": "^5.4|^6.0", @@ -5839,17 +6080,9 @@ "symfony/stopwatch": "^5.4|^6.0", "symfony/translation": "^5.4|^6.0", "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", + "symfony/validator": "^5.4.25|~6.2.12|^6.3.1", "symfony/var-dumper": "^5.4|^6.0" }, - "suggest": { - "doctrine/data-fixtures": "", - "doctrine/dbal": "", - "doctrine/orm": "", - "symfony/form": "", - "symfony/property-info": "", - "symfony/validator": "" - }, "type": "symfony-bridge", "autoload": { "psr-4": { @@ -5876,7 +6109,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.2.3" + "source": "https://github.com/symfony/doctrine-bridge/tree/v6.3.1" }, "funding": [ { @@ -5892,20 +6125,20 @@ "type": "tidelift" } ], - "time": "2022-12-20T16:41:15+00:00" + "time": "2023-06-18T20:33:34+00:00" }, { "name": "symfony/error-handler", - "version": "v6.2.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "0926124c95d220499e2baf0fb465772af3a4eddb" + "reference": "99d2d814a6351461af350ead4d963bd67451236f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/0926124c95d220499e2baf0fb465772af3a4eddb", - "reference": "0926124c95d220499e2baf0fb465772af3a4eddb", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/99d2d814a6351461af350ead4d963bd67451236f", + "reference": "99d2d814a6351461af350ead4d963bd67451236f", "shasum": "" }, "require": { @@ -5913,8 +6146,11 @@ "psr/log": "^1|^2|^3", "symfony/var-dumper": "^5.4|^6.0" }, + "conflict": { + "symfony/deprecation-contracts": "<2.5" + }, "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/http-kernel": "^5.4|^6.0", "symfony/serializer": "^5.4|^6.0" }, @@ -5947,7 +6183,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.2.3" + "source": "https://github.com/symfony/error-handler/tree/v6.3.0" }, "funding": [ { @@ -5963,32 +6199,34 @@ "type": "tidelift" } ], - "time": "2022-12-19T14:33:49+00:00" + "time": "2023-05-10T12:03:13+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.2.2", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "ddf4dd35de1623e7c02013523e6c2137b67b636f" + "reference": "e0ad0d153e1c20069250986cd9e9dd1ccebb0d66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ddf4dd35de1623e7c02013523e6c2137b67b636f", - "reference": "ddf4dd35de1623e7c02013523e6c2137b67b636f", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e0ad0d153e1c20069250986cd9e9dd1ccebb0d66", + "reference": "e0ad0d153e1c20069250986cd9e9dd1ccebb0d66", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/polyfill-mbstring": "~1.1" + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/polyfill-mbstring": "~1.1", + "symfony/polyfill-php83": "^1.27" }, "conflict": { "symfony/cache": "<6.2" }, "require-dev": { - "predis/predis": "~1.0", + "doctrine/dbal": "^2.13.1|^3.0", + "predis/predis": "^1.1|^2.0", "symfony/cache": "^5.4|^6.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", @@ -5996,9 +6234,6 @@ "symfony/mime": "^5.4|^6.0", "symfony/rate-limiter": "^5.2|^6.0" }, - "suggest": { - "symfony/mime": "To use the file extension guesser" - }, "type": "library", "autoload": { "psr-4": { @@ -6025,7 +6260,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.2.2" + "source": "https://github.com/symfony/http-foundation/tree/v6.3.1" }, "funding": [ { @@ -6041,29 +6276,29 @@ "type": "tidelift" } ], - "time": "2022-12-14T16:11:27+00:00" + "time": "2023-06-24T11:51:27+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.2.4", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "74f2e638ec3fa0315443bd85fab7fc8066b77f83" + "reference": "161e16fd2e35fb4881a43bc8b383dfd5be4ac374" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/74f2e638ec3fa0315443bd85fab7fc8066b77f83", - "reference": "74f2e638ec3fa0315443bd85fab7fc8066b77f83", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/161e16fd2e35fb4881a43bc8b383dfd5be4ac374", + "reference": "161e16fd2e35fb4881a43bc8b383dfd5be4ac374", "shasum": "" }, "require": { "php": ">=8.1", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.1|^3", - "symfony/error-handler": "^6.1", + "symfony/deprecation-contracts": "^2.5|^3", + "symfony/error-handler": "^6.3", "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", + "symfony/http-foundation": "^6.2.7", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -6071,15 +6306,18 @@ "symfony/cache": "<5.4", "symfony/config": "<6.1", "symfony/console": "<5.4", - "symfony/dependency-injection": "<6.2", + "symfony/dependency-injection": "<6.3", "symfony/doctrine-bridge": "<5.4", "symfony/form": "<5.4", "symfony/http-client": "<5.4", + "symfony/http-client-contracts": "<2.5", "symfony/mailer": "<5.4", "symfony/messenger": "<5.4", "symfony/translation": "<5.4", + "symfony/translation-contracts": "<2.5", "symfony/twig-bridge": "<5.4", "symfony/validator": "<5.4", + "symfony/var-dumper": "<6.3", "twig/twig": "<2.13" }, "provide": { @@ -6088,28 +6326,27 @@ "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", "symfony/browser-kit": "^5.4|^6.0", + "symfony/clock": "^6.2", "symfony/config": "^6.1", "symfony/console": "^5.4|^6.0", "symfony/css-selector": "^5.4|^6.0", - "symfony/dependency-injection": "^6.2", + "symfony/dependency-injection": "^6.3", "symfony/dom-crawler": "^5.4|^6.0", "symfony/expression-language": "^5.4|^6.0", "symfony/finder": "^5.4|^6.0", - "symfony/http-client-contracts": "^1.1|^2|^3", + "symfony/http-client-contracts": "^2.5|^3", "symfony/process": "^5.4|^6.0", + "symfony/property-access": "^5.4.5|^6.0.5", "symfony/routing": "^5.4|^6.0", + "symfony/serializer": "^6.3", "symfony/stopwatch": "^5.4|^6.0", "symfony/translation": "^5.4|^6.0", - "symfony/translation-contracts": "^1.1|^2|^3", + "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^5.4|^6.0", + "symfony/validator": "^6.3", + "symfony/var-exporter": "^6.2", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "symfony/browser-kit": "", - "symfony/config": "", - "symfony/console": "", - "symfony/dependency-injection": "" - }, "type": "library", "autoload": { "psr-4": { @@ -6136,7 +6373,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.2.4" + "source": "https://github.com/symfony/http-kernel/tree/v6.3.1" }, "funding": [ { @@ -6152,20 +6389,20 @@ "type": "tidelift" } ], - "time": "2022-12-29T19:05:08+00:00" + "time": "2023-06-26T06:07:32+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.2.3", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "3766b8269d3bac5c214a04ebd6870e71e52bcb60" + "reference": "0b0bf59b0d9bd1422145a123a67fb12af546ef0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/3766b8269d3bac5c214a04ebd6870e71e52bcb60", - "reference": "3766b8269d3bac5c214a04ebd6870e71e52bcb60", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/0b0bf59b0d9bd1422145a123a67fb12af546ef0d", + "reference": "0b0bf59b0d9bd1422145a123a67fb12af546ef0d", "shasum": "" }, "require": { @@ -6175,11 +6412,9 @@ "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { - "symfony/deprecation-contracts": "^2.1|^3.0", - "symfony/error-handler": "^5.4|^6.0" - }, - "suggest": { - "symfony/error-handler": "For tracking deprecated interfaces usages at runtime with DebugClassLoader" + "symfony/deprecation-contracts": "^2.5|^3.0", + "symfony/error-handler": "^5.4|^6.0", + "symfony/polyfill-php81": "^1.27" }, "bin": [ "bin/simple-phpunit" @@ -6219,7 +6454,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.2.3" + "source": "https://github.com/symfony/phpunit-bridge/tree/v6.3.1" }, "funding": [ { @@ -6235,7 +6470,7 @@ "type": "tidelift" } ], - "time": "2022-12-28T14:26:22+00:00" + "time": "2023-06-23T13:25:16+00:00" }, { "name": "symfony/polyfill-php72", @@ -6313,31 +6548,105 @@ ], "time": "2022-11-03T14:55:06+00:00" }, + { + "name": "symfony/polyfill-php83", + "version": "v1.27.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php83.git", + "reference": "508c652ba3ccf69f8c97f251534f229791b52a57" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/508c652ba3ccf69f8c97f251534f229791b52a57", + "reference": "508c652ba3ccf69f8c97f251534f229791b52a57", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "symfony/polyfill-php80": "^1.14" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.27-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php83\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill backporting some PHP 8.3+ features to lower PHP versions", + "homepage": "https://symfony.com/", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-php83/tree/v1.27.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2022-11-03T14:55:06+00:00" + }, { "name": "symfony/property-access", - "version": "v6.2.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "9c267d87dd665d5d33e897290bbb9f64ae905b94" + "reference": "db9358571ce63f09c439c2fee6c12e5b090b69ac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/9c267d87dd665d5d33e897290bbb9f64ae905b94", - "reference": "9c267d87dd665d5d33e897290bbb9f64ae905b94", + "url": "https://api.github.com/repos/symfony/property-access/zipball/db9358571ce63f09c439c2fee6c12e5b090b69ac", + "reference": "db9358571ce63f09c439c2fee6c12e5b090b69ac", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/property-info": "^5.4|^6.0" }, "require-dev": { "symfony/cache": "^5.4|^6.0" }, - "suggest": { - "psr/cache-implementation": "To cache access methods." - }, "type": "library", "autoload": { "psr-4": { @@ -6371,11 +6680,11 @@ "injection", "object", "property", - "property path", + "property-path", "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.2.3" + "source": "https://github.com/symfony/property-access/tree/v6.3.0" }, "funding": [ { @@ -6391,20 +6700,20 @@ "type": "tidelift" } ], - "time": "2022-12-23T08:18:26+00:00" + "time": "2023-05-19T08:06:44+00:00" }, { "name": "symfony/property-info", - "version": "v6.2.3", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "b4cbbbcc8679460cfeb1d5bdcb8127a2e85c376c" + "reference": "7f3a03716112269741fe2a809f8f791a371d1fcd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/b4cbbbcc8679460cfeb1d5bdcb8127a2e85c376c", - "reference": "b4cbbbcc8679460cfeb1d5bdcb8127a2e85c376c", + "url": "https://api.github.com/repos/symfony/property-info/zipball/7f3a03716112269741fe2a809f8f791a371d1fcd", + "reference": "7f3a03716112269741fe2a809f8f791a371d1fcd", "shasum": "" }, "require": { @@ -6424,12 +6733,6 @@ "symfony/dependency-injection": "^5.4|^6.0", "symfony/serializer": "^5.4|^6.0" }, - "suggest": { - "phpdocumentor/reflection-docblock": "To use the PHPDoc", - "psr/cache-implementation": "To cache results", - "symfony/doctrine-bridge": "To use Doctrine metadata", - "symfony/serializer": "To use Serializer metadata" - }, "type": "library", "autoload": { "psr-4": { @@ -6464,7 +6767,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.2.3" + "source": "https://github.com/symfony/property-info/tree/v6.3.0" }, "funding": [ { @@ -6480,20 +6783,20 @@ "type": "tidelift" } ], - "time": "2022-12-20T16:41:15+00:00" + "time": "2023-05-19T08:06:44+00:00" }, { "name": "symfony/serializer", - "version": "v6.2.3", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "9cb1e8fd22f9ff40b9580ae822f44c13317ddb20" + "reference": "1d238ee3180bc047f8ab713bfb73848d553f4407" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/9cb1e8fd22f9ff40b9580ae822f44c13317ddb20", - "reference": "9cb1e8fd22f9ff40b9580ae822f44c13317ddb20", + "url": "https://api.github.com/repos/symfony/serializer/zipball/1d238ee3180bc047f8ab713bfb73848d553f4407", + "reference": "1d238ee3180bc047f8ab713bfb73848d553f4407", "shasum": "" }, "require": { @@ -6503,7 +6806,7 @@ "conflict": { "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", - "phpdocumentor/type-resolver": "<1.4.0|>=1.7.0", + "phpdocumentor/type-resolver": "<1.4.0", "symfony/dependency-injection": "<5.4", "symfony/property-access": "<5.4", "symfony/property-info": "<5.4", @@ -6515,6 +6818,7 @@ "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", + "symfony/console": "^5.4|^6.0", "symfony/dependency-injection": "^5.4|^6.0", "symfony/error-handler": "^5.4|^6.0", "symfony/filesystem": "^5.4|^6.0", @@ -6530,15 +6834,6 @@ "symfony/var-exporter": "^5.4|^6.0", "symfony/yaml": "^5.4|^6.0" }, - "suggest": { - "psr/cache-implementation": "For using the metadata cache.", - "symfony/config": "For using the XML mapping loader.", - "symfony/mime": "For using a MIME type guesser within the DataUriNormalizer.", - "symfony/property-access": "For using the ObjectNormalizer.", - "symfony/property-info": "To deserialize relations.", - "symfony/var-exporter": "For using the metadata compiler.", - "symfony/yaml": "For using the default YAML mapping loader." - }, "type": "library", "autoload": { "psr-4": { @@ -6565,7 +6860,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.2.3" + "source": "https://github.com/symfony/serializer/tree/v6.3.1" }, "funding": [ { @@ -6581,32 +6876,29 @@ "type": "tidelift" } ], - "time": "2022-12-20T16:41:15+00:00" + "time": "2023-06-21T19:54:33+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.2.0", + "version": "v3.3.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "68cce71402305a015f8c1589bfada1280dc64fe7" + "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/68cce71402305a015f8c1589bfada1280dc64fe7", - "reference": "68cce71402305a015f8c1589bfada1280dc64fe7", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/02c24deb352fb0d79db5486c0c79905a85e37e86", + "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86", "shasum": "" }, "require": { "php": ">=8.1" }, - "suggest": { - "symfony/translation-implementation": "" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.3-dev" + "dev-main": "3.4-dev" }, "thanks": { "name": "symfony/contracts", @@ -6646,7 +6938,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.2.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.3.0" }, "funding": [ { @@ -6662,33 +6954,33 @@ "type": "tidelift" } ], - "time": "2022-11-25T10:21:52+00:00" + "time": "2023-05-30T17:17:10+00:00" }, { "name": "symfony/validator", - "version": "v6.2.3", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "bd44a9ae3b19ae81c723b5a5fff6a1a36844ee01" + "reference": "1b71f43c62ee867ab08195ba6039a1bc3e6654dc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/bd44a9ae3b19ae81c723b5a5fff6a1a36844ee01", - "reference": "bd44a9ae3b19ae81c723b5a5fff6a1a36844ee01", + "url": "https://api.github.com/repos/symfony/validator/zipball/1b71f43c62ee867ab08195ba6039a1bc3e6654dc", + "reference": "1b71f43c62ee867ab08195ba6039a1bc3e6654dc", "shasum": "" }, "require": { "php": ">=8.1", - "symfony/deprecation-contracts": "^2.1|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", - "symfony/translation-contracts": "^1.1|^2|^3" + "symfony/polyfill-php83": "^1.27", + "symfony/translation-contracts": "^2.5|^3" }, "conflict": { "doctrine/annotations": "<1.13", "doctrine/lexer": "<1.1", - "phpunit/phpunit": "<5.4.3", "symfony/dependency-injection": "<5.4", "symfony/expression-language": "<5.4", "symfony/http-kernel": "<5.4", @@ -6699,7 +6991,7 @@ }, "require-dev": { "doctrine/annotations": "^1.13|^2", - "egulias/email-validator": "^2.1.10|^3", + "egulias/email-validator": "^2.1.10|^3|^4", "symfony/cache": "^5.4|^6.0", "symfony/config": "^5.4|^6.0", "symfony/console": "^5.4|^6.0", @@ -6716,18 +7008,6 @@ "symfony/translation": "^5.4|^6.0", "symfony/yaml": "^5.4|^6.0" }, - "suggest": { - "egulias/email-validator": "Strict (RFC compliant) email validation", - "psr/cache-implementation": "For using the mapping cache.", - "symfony/config": "", - "symfony/expression-language": "For using the Expression validator and the ExpressionLanguageSyntax constraints", - "symfony/http-foundation": "", - "symfony/intl": "", - "symfony/property-access": "For accessing properties within comparison constraints", - "symfony/property-info": "To automatically add NotNull and Type constraints", - "symfony/translation": "For translating validation errors.", - "symfony/yaml": "" - }, "type": "library", "autoload": { "psr-4": { @@ -6754,7 +7034,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.2.3" + "source": "https://github.com/symfony/validator/tree/v6.3.1" }, "funding": [ { @@ -6770,20 +7050,20 @@ "type": "tidelift" } ], - "time": "2022-12-22T17:55:15+00:00" + "time": "2023-06-21T12:08:28+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.2.3", + "version": "v6.3.1", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0" + "reference": "c81268d6960ddb47af17391a27d222bd58cf0515" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0", - "reference": "fdbadd4803bc3c96ef89238c9c9e2ebe424ec2e0", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c81268d6960ddb47af17391a27d222bd58cf0515", + "reference": "c81268d6960ddb47af17391a27d222bd58cf0515", "shasum": "" }, "require": { @@ -6791,7 +7071,6 @@ "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "phpunit/phpunit": "<5.4.3", "symfony/console": "<5.4" }, "require-dev": { @@ -6801,11 +7080,6 @@ "symfony/uid": "^5.4|^6.0", "twig/twig": "^2.13|^3.0.4" }, - "suggest": { - "ext-iconv": "To convert non-UTF-8 strings to UTF-8 (or symfony/polyfill-iconv in case ext-iconv cannot be used).", - "ext-intl": "To show region name in time zone dump", - "symfony/console": "To use the ServerDumpCommand and/or the bin/var-dump-server script" - }, "bin": [ "Resources/bin/var-dump-server" ], @@ -6842,7 +7116,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.2.3" + "source": "https://github.com/symfony/var-dumper/tree/v6.3.1" }, "funding": [ { @@ -6858,20 +7132,20 @@ "type": "tidelift" } ], - "time": "2022-12-22T17:55:15+00:00" + "time": "2023-06-21T12:08:28+00:00" }, { "name": "symfony/web-link", - "version": "v6.2.0", + "version": "v6.3.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "068136a48bd945b0b4a4a13ceaa1327ac6606aa3" + "reference": "0989ca617d0703cdca501a245f10e194ff22315b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/068136a48bd945b0b4a4a13ceaa1327ac6606aa3", - "reference": "068136a48bd945b0b4a4a13ceaa1327ac6606aa3", + "url": "https://api.github.com/repos/symfony/web-link/zipball/0989ca617d0703cdca501a245f10e194ff22315b", + "reference": "0989ca617d0703cdca501a245f10e194ff22315b", "shasum": "" }, "require": { @@ -6887,9 +7161,6 @@ "require-dev": { "symfony/http-kernel": "^5.4|^6.0" }, - "suggest": { - "symfony/http-kernel": "" - }, "type": "library", "autoload": { "psr-4": { @@ -6928,7 +7199,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v6.2.0" + "source": "https://github.com/symfony/web-link/tree/v6.3.0" }, "funding": [ { @@ -6944,7 +7215,7 @@ "type": "tidelift" } ], - "time": "2022-08-25T15:27:04+00:00" + "time": "2023-04-21T14:41:17+00:00" }, { "name": "theseer/tokenizer", diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 0688e2b5..35e4d7e8 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -132,6 +132,7 @@ public function generatePropertyAttributes(Property $property, string $className public function generateUses(Class_ $class): array { if ($this->config['apiPlatformOldAttributes']) { + // @phpstan-ignore-next-line return [new Use_(OldApiResource::class), new Use_(OldApiProperty::class)]; } diff --git a/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php b/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php index 9384ed84..1e591ce7 100644 --- a/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php +++ b/tests/e2e/original/App/OpenApi/Entity/AcademicSession.php @@ -224,14 +224,14 @@ public function getYear(): string return $this->year; } - public function addOtherCod(string $otherCod): void + public function addOtherCode(string $otherCode): void { - $this->otherCodes[] = $otherCod; + $this->otherCodes[] = $otherCode; } - public function removeOtherCod(string $otherCod): void + public function removeOtherCode(string $otherCode): void { - if (false !== $key = array_search($otherCod, $this->otherCodes, true)) { + if (false !== $key = array_search($otherCode, $this->otherCodes, true)) { unset($this->otherCodes[$key]); } } diff --git a/tests/e2e/original/App/Schema/Enum/GenderType.php b/tests/e2e/original/App/Schema/Enum/GenderType.php index cbe6dbe4..f2a24993 100644 --- a/tests/e2e/original/App/Schema/Enum/GenderType.php +++ b/tests/e2e/original/App/Schema/Enum/GenderType.php @@ -13,9 +13,9 @@ */ class GenderType extends Enum { - /** @var string The male gender. */ - public const MALE = 'https://schema.org/Male'; - /** @var string The female gender. */ public const FEMALE = 'https://schema.org/Female'; + + /** @var string The male gender. */ + public const MALE = 'https://schema.org/Male'; } From 1d247279ef8a77ae03e7b3d09571e73cd25ddba5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 19 Jul 2023 23:06:19 +0200 Subject: [PATCH 247/258] ci: test with PHP 8.2 and simplify workflow (#411) --- .github/workflows/ci.yml | 53 +++++++++++++++++----------------------- 1 file changed, 22 insertions(+), 31 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 093606b2..aa7caf19 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -8,9 +8,6 @@ concurrency: group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }} cancel-in-progress: true -env: - COVERAGE: '0' - jobs: build: name: Build and Test @@ -21,13 +18,21 @@ jobs: - '7.4' - '8.0' - '8.1' + - '8.2' include: - - php: '8.1' - coverage: true - phpstan: true + - php: '8.2' + latest: true steps: - uses: actions/checkout@v3 + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + ini-values: memory_limit=-1 + coverage: pcov + tools: composer, cs2pr, php-cs-fixer + - name: Get Composer Cache Directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT @@ -38,15 +43,6 @@ jobs: key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: ${{ runner.os }}-composer- - - name: Setup PHP with extensions - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php }} - extensions: json - ini-values: memory_limit=-1 - coverage: pcov - tools: composer, cs2pr, php-cs-fixer - - name: Install prerequisites run: | wget -O box.phar https://github.com/humbug/box/releases/download/4.3.8/box.phar @@ -54,39 +50,34 @@ jobs: sudo chown -R $(whoami):$(whoami) . - name: Install dependencies - if: startsWith(matrix.php, '8.1') + if: matrix.latest run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Update dependencies - if: "!startsWith(matrix.php, '8.1')" + if: "!matrix.latest" run: composer update --no-interaction --no-progress --ansi - name: Enable code coverage - if: matrix.coverage + if: matrix.latest run: echo "COVERAGE=1" >> $GITHUB_ENV - - name: Run phpunit - run: | - mkdir -p build/logs/phpunit - if [ "$COVERAGE" = '1' ]; then - vendor/bin/simple-phpunit --coverage-clover build/logs/phpunit/clover.xml - else - vendor/bin/simple-phpunit - fi + - name: Run PHPUnit + run: vendor/bin/simple-phpunit ${{ matrix.latest && '--coverage-clover build/logs/phpunit/clover.xml' || '' }} - - name: Run php-cs-fixer + - name: Run PHP CS Fixer + if: matrix.latest run: php-cs-fixer fix --dry-run --format=checkstyle --ansi | cs2pr - - name: Run phpstan - if: matrix.phpstan + - name: Run PHPStan + if: matrix.latest run: vendor/bin/phpstan analyse --ansi - name: Run e2e tests - if: startsWith(matrix.php, '8.1') + if: matrix.latest run: bin/compile - name: Upload coverage results to Coveralls - if: matrix.coverage + if: matrix.latest env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | From 79648fddcce493f49624506ac7f9a01002a65de2 Mon Sep 17 00:00:00 2001 From: stiivo Date: Wed, 19 Jul 2023 23:14:06 +0200 Subject: [PATCH 248/258] fix(schemaorg): Enumeration type detection improved (#401) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Enumeration type detection improved by traversing the graph and checking if one of the parent elements is of type schema.org/Enumeration * Update src/Schema/Model/Class_.php Co-authored-by: Alan Poulain * Update src/Schema/Model/Class_.php Co-authored-by: Alan Poulain * Update src/Schema/Model/Class_.php Co-authored-by: Alan Poulain * removed PHPDoc * fix CS --------- Co-authored-by: steven Co-authored-by: Alan Poulain Co-authored-by: Kévin Dunglas --- src/Schema/Model/Class_.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Schema/Model/Class_.php b/src/Schema/Model/Class_.php index 24118617..6d6a49b7 100644 --- a/src/Schema/Model/Class_.php +++ b/src/Schema/Model/Class_.php @@ -66,10 +66,10 @@ public function getSubClassOf(): array return array_filter($this->resource->all('rdfs:subClassOf', 'resource'), static fn (RdfResource $resource) => !$resource->isBNode()); } - public function isEnum(): bool + public function isEnum(RdfResource $resource = null): bool { - $subClassOf = $this->resource->get('rdfs:subClassOf'); + $parentClass = ($resource ?? $this->resource)->get('rdfs:subClassOf'); - return $subClassOf && self::SCHEMA_ORG_ENUMERATION === $subClassOf->getUri(); + return $parentClass && (self::SCHEMA_ORG_ENUMERATION === $parentClass->getUri() || $this->isEnum($parentClass)); } } From 1709653e7349c354588f9cb311060c6d059be340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Wed, 19 Jul 2023 23:17:17 +0200 Subject: [PATCH 249/258] docs: update changelog --- CHANGELOG.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4faebb78..78e73396 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog +## 5.2.2 + +* fix: detect enum detection when an ancestor is an enum + +## 5.2.1 + +* fix: allow declaring multiple operations using the same class + ## 5.2.0 * feat: improve type detection From 8d683f2504450a39ac787d8b4f7e5710d15dd129 Mon Sep 17 00:00:00 2001 From: Kai Dederichs Date: Tue, 5 Dec 2023 18:10:05 +0100 Subject: [PATCH 250/258] feat: allow symfony 7 --- composer.json | 20 +- composer.lock | 1704 +++++++++++++++++++++++-------------------------- 2 files changed, 821 insertions(+), 903 deletions(-) diff --git a/composer.json b/composer.json index 390e8357..51f3a002 100644 --- a/composer.json +++ b/composer.json @@ -39,27 +39,27 @@ "friendsofphp/php-cs-fixer": "^2.15 || ^3.0", "league/html-to-markdown": "^5.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/config": "^5.2 || ^6.0" , - "symfony/console": "^5.2 || ^6.0", - "symfony/yaml": "^5.2 || ^6.0", - "symfony/filesystem": "^5.2 || ^6.0", + "symfony/config": "^5.2 || ^6.0 || ^7.0" , + "symfony/console": "^5.2 || ^6.0 || ^7.0", + "symfony/yaml": "^5.2 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.2 || ^6.0 || ^7.0", "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0", "nikic/php-parser": "^4.13", "cebe/php-openapi": "^1.6", - "symfony/string": "^5.2 || ^6.0" + "symfony/string": "^5.2 || ^6.0 || ^7.0" }, "require-dev": { "api-platform/core": "^2.7 || ^3.0", "doctrine/orm": "^2.7", "myclabs/php-enum": "^1.7", - "symfony/doctrine-bridge": "^5.2 || ^6.0", - "symfony/phpunit-bridge": "^5.2 || ^6.0", - "symfony/serializer": "^5.2 || ^6.0", - "symfony/validator": "^5.2 || ^6.0", + "symfony/doctrine-bridge": "^5.2 || ^6.0 || ^7.0", + "symfony/phpunit-bridge": "^5.2 || ^6.0 || ^7.0", + "symfony/serializer": "^5.2 || ^6.0 || ^7.0", + "symfony/validator": "^5.2 || ^6.0 || ^7.0", "phpspec/prophecy-phpunit": "^2.0", "phpstan/phpstan": "^1.2.0", - "symfony/finder": "^5.2 || ^6.0" + "symfony/finder": "^5.2 || ^6.0 || ^7.0" }, "bin": [ "bin/schema" diff --git a/composer.lock b/composer.lock index f2be83b3..28aec93e 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "8d7ec2ad8dc62f26690b53d1dbf22ae8", + "content-hash": "1d40f845abecee348779195d39a04ea8", "packages": [ { "name": "cebe/php-openapi", @@ -77,16 +77,16 @@ }, { "name": "composer/pcre", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2" + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", - "reference": "4bff79ddd77851fe3cdd11616ed3f92841ba5bd2", + "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", "shasum": "" }, "require": { @@ -128,7 +128,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.0" + "source": "https://github.com/composer/pcre/tree/3.1.1" }, "funding": [ { @@ -144,20 +144,20 @@ "type": "tidelift" } ], - "time": "2022-11-17T09:50:14+00:00" + "time": "2023-10-11T07:11:09+00:00" }, { "name": "composer/semver", - "version": "3.3.2", + "version": "3.4.0", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9" + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/3953f23262f2bff1919fc82183ad9acb13ff62c9", - "reference": "3953f23262f2bff1919fc82183ad9acb13ff62c9", + "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", + "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", "shasum": "" }, "require": { @@ -207,9 +207,9 @@ "versioning" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.3.2" + "source": "https://github.com/composer/semver/tree/3.4.0" }, "funding": [ { @@ -225,7 +225,7 @@ "type": "tidelift" } ], - "time": "2022-04-01T19:23:25+00:00" + "time": "2023-08-31T09:50:34+00:00" }, { "name": "composer/xdebug-handler", @@ -293,129 +293,6 @@ ], "time": "2022-02-25T21:32:43+00:00" }, - { - "name": "doctrine/annotations", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "reference": "e157ef3f3124bbf6fe7ce0ffd109e8a8ef284e7f", - "shasum": "" - }, - "require": { - "doctrine/lexer": "^2 || ^3", - "ext-tokenizer": "*", - "php": "^7.2 || ^8.0", - "psr/cache": "^1 || ^2 || ^3" - }, - "require-dev": { - "doctrine/cache": "^2.0", - "doctrine/coding-standard": "^10", - "phpstan/phpstan": "^1.8.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "symfony/cache": "^5.4 || ^6", - "vimeo/psalm": "^4.10" - }, - "suggest": { - "php": "PHP 8.0 or higher comes with attributes, a native replacement for annotations" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", - "keywords": [ - "annotations", - "docblock", - "parser" - ], - "support": { - "issues": "https://github.com/doctrine/annotations/issues", - "source": "https://github.com/doctrine/annotations/tree/2.0.1" - }, - "time": "2023-02-02T22:02:53+00:00" - }, - { - "name": "doctrine/deprecations", - "version": "v1.1.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/deprecations.git", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", - "reference": "612a3ee5ab0d5dd97b7cf3874a6efe24325efac3", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" - }, - "suggest": { - "psr/log": "Allows logging deprecations via PSR-3 logger implementation" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", - "homepage": "https://www.doctrine-project.org/", - "support": { - "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/v1.1.1" - }, - "time": "2023-06-03T09:27:29+00:00" - }, { "name": "doctrine/inflector", "version": "2.0.8", @@ -507,134 +384,52 @@ ], "time": "2023-06-16T13:40:37+00:00" }, - { - "name": "doctrine/lexer", - "version": "2.1.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "shasum": "" - }, - "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^4.11 || ^5.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/2.1.0" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2022-12-14T08:49:07+00:00" - }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.22.0", + "version": "v3.40.2", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "92b019f6c8d79aa26349d0db7671d37440dc0ff3" + "reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/92b019f6c8d79aa26349d0db7671d37440dc0ff3", - "reference": "92b019f6c8d79aa26349d0db7671d37440dc0ff3", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4344562a516b76afe8f2d64b2e52214c30d64ed8", + "reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8", "shasum": "" }, "require": { - "composer/semver": "^3.3", + "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", - "doctrine/annotations": "^2", - "doctrine/lexer": "^2 || ^3", "ext-json": "*", "ext-tokenizer": "*", "php": "^7.4 || ^8.0", "sebastian/diff": "^4.0 || ^5.0", - "symfony/console": "^5.4 || ^6.0", - "symfony/event-dispatcher": "^5.4 || ^6.0", - "symfony/filesystem": "^5.4 || ^6.0", - "symfony/finder": "^5.4 || ^6.0", - "symfony/options-resolver": "^5.4 || ^6.0", - "symfony/polyfill-mbstring": "^1.27", - "symfony/polyfill-php80": "^1.27", - "symfony/polyfill-php81": "^1.27", - "symfony/process": "^5.4 || ^6.0", - "symfony/stopwatch": "^5.4 || ^6.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", + "symfony/finder": "^5.4 || ^6.0 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", + "symfony/polyfill-mbstring": "^1.28", + "symfony/polyfill-php80": "^1.28", + "symfony/polyfill-php81": "^1.28", + "symfony/process": "^5.4 || ^6.0 || ^7.0", + "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" }, "require-dev": { "facile-it/paraunit": "^1.3 || ^2.0", "justinrainbow/json-schema": "^5.2", - "keradus/cli-executor": "^2.0", + "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", - "php-coveralls/php-coveralls": "^2.5.3", + "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy": "^1.16", + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", + "phpspec/prophecy": "^1.17", "phpspec/prophecy-phpunit": "^2.0", - "phpunit/phpunit": "^9.5", - "phpunitgoodpractices/polyfill": "^1.6", - "phpunitgoodpractices/traits": "^1.9.2", - "symfony/phpunit-bridge": "^6.2.3", - "symfony/yaml": "^5.4 || ^6.0" + "phpunit/phpunit": "^9.6", + "symfony/phpunit-bridge": "^6.3.8 || ^7.0", + "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -672,7 +467,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.22.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.40.2" }, "funding": [ { @@ -680,20 +475,20 @@ "type": "github" } ], - "time": "2023-07-16T23:08:06+00:00" + "time": "2023-12-03T09:21:33+00:00" }, { "name": "justinrainbow/json-schema", - "version": "5.2.12", + "version": "v5.2.13", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60" + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", - "reference": "ad87d5a5ca981228e0e205c2bc7dfb8e24559b60", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, "require": { @@ -748,9 +543,9 @@ ], "support": { "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/5.2.12" + "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" }, - "time": "2022-04-13T08:02:27+00:00" + "time": "2023-09-26T02:20:38+00:00" }, { "name": "league/html-to-markdown", @@ -843,21 +638,21 @@ }, { "name": "nette/php-generator", - "version": "v4.0.7", + "version": "v4.1.2", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "de1843fbb692125e307937c85d43937d0dc0c1d4" + "reference": "abc0e79b2d02d4b8aba5933765b90df3f610c143" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/de1843fbb692125e307937c85d43937d0dc0c1d4", - "reference": "de1843fbb692125e307937c85d43937d0dc0c1d4", + "url": "https://api.github.com/repos/nette/php-generator/zipball/abc0e79b2d02d4b8aba5933765b90df3f610c143", + "reference": "abc0e79b2d02d4b8aba5933765b90df3f610c143", "shasum": "" }, "require": { "nette/utils": "^3.2.9 || ^4.0", - "php": ">=8.0 <8.3" + "php": "8.0 - 8.3" }, "require-dev": { "jetbrains/phpstorm-attributes": "dev-master", @@ -872,7 +667,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -896,7 +691,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.2 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.3 features.", "homepage": "https://nette.org/", "keywords": [ "code", @@ -906,26 +701,26 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.0.7" + "source": "https://github.com/nette/php-generator/tree/v4.1.2" }, - "time": "2023-04-26T15:09:53+00:00" + "time": "2023-10-29T22:57:32+00:00" }, { "name": "nette/utils", - "version": "v4.0.0", + "version": "v4.0.3", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e" + "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/cacdbf5a91a657ede665c541eda28941d4b09c1e", - "reference": "cacdbf5a91a657ede665c541eda28941d4b09c1e", + "url": "https://api.github.com/repos/nette/utils/zipball/a9d127dd6a203ce6d255b2e2db49759f7506e015", + "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015", "shasum": "" }, "require": { - "php": ">=8.0 <8.3" + "php": ">=8.0 <8.4" }, "conflict": { "nette/finder": "<3", @@ -933,7 +728,7 @@ }, "require-dev": { "jetbrains/phpstorm-attributes": "dev-master", - "nette/tester": "^2.4", + "nette/tester": "^2.5", "phpstan/phpstan": "^1.0", "tracy/tracy": "^2.9" }, @@ -943,8 +738,7 @@ "ext-intl": "to use Strings::webalize(), toAscii(), normalize() and compare()", "ext-json": "to use Nette\\Utils\\Json", "ext-mbstring": "to use Strings::lower() etc...", - "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()", - "ext-xml": "to use Strings::length() etc. when mbstring is not available" + "ext-tokenizer": "to use Nette\\Utils\\Reflection::getUseStatements()" }, "type": "library", "extra": { @@ -993,22 +787,22 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.0" + "source": "https://github.com/nette/utils/tree/v4.0.3" }, - "time": "2023-02-02T10:41:53+00:00" + "time": "2023-10-29T21:02:13+00:00" }, { "name": "nikic/php-parser", - "version": "v4.16.0", + "version": "v4.17.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "19526a33fb561ef417e822e85f08a00db4059c17" + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/19526a33fb561ef417e822e85f08a00db4059c17", - "reference": "19526a33fb561ef417e822e85f08a00db4059c17", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", "shasum": "" }, "require": { @@ -1049,58 +843,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.16.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" }, - "time": "2023-06-25T14:52:30+00:00" - }, - { - "name": "psr/cache", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/php-fig/cache.git", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", - "shasum": "" - }, - "require": { - "php": ">=8.0.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\Cache\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" - } - ], - "description": "Common interface for caching libraries", - "keywords": [ - "cache", - "psr", - "psr-6" - ], - "support": { - "source": "https://github.com/php-fig/cache/tree/3.0.0" - }, - "time": "2021-02-03T23:26:27+00:00" + "time": "2023-08-13T19:53:39+00:00" }, { "name": "psr/container", @@ -1207,16 +952,16 @@ }, { "name": "psr/http-message", - "version": "1.1", + "version": "2.0", "source": { "type": "git", "url": "https://github.com/php-fig/http-message.git", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", - "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", "shasum": "" }, "require": { @@ -1225,7 +970,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1240,7 +985,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for HTTP messages", @@ -1254,9 +999,9 @@ "response" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/1.1" + "source": "https://github.com/php-fig/http-message/tree/2.0" }, - "time": "2023-04-04T09:50:52+00:00" + "time": "2023-04-04T09:54:51+00:00" }, { "name": "psr/log", @@ -1376,16 +1121,16 @@ }, { "name": "sweetrdf/easyrdf", - "version": "1.9.0", + "version": "1.11.0", "source": { "type": "git", "url": "https://github.com/sweetrdf/easyrdf.git", - "reference": "feaeb6f602d989c6bc6e482d27426a212e76289a" + "reference": "92554d04aaec5635cbd82caf428434f824298a1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/feaeb6f602d989c6bc6e482d27426a212e76289a", - "reference": "feaeb6f602d989c6bc6e482d27426a212e76289a", + "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/92554d04aaec5635cbd82caf428434f824298a1b", + "reference": "92554d04aaec5635cbd82caf428434f824298a1b", "shasum": "" }, "require": { @@ -1407,7 +1152,7 @@ "phpstan/phpstan": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^9.5.0|^10.0.0", - "semsol/arc2": "^2.4", + "semsol/arc2": "^3", "zendframework/zend-http": "^2" }, "type": "library", @@ -1451,27 +1196,27 @@ ], "support": { "issues": "https://github.com/sweetrdf/easyrdf/issues", - "source": "https://github.com/sweetrdf/easyrdf/tree/1.9.0" + "source": "https://github.com/sweetrdf/easyrdf/tree/1.11.0" }, - "time": "2023-06-20T15:05:17+00:00" + "time": "2023-09-14T07:31:36+00:00" }, { "name": "sweetrdf/rdf-helpers", - "version": "1.0.1", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/sweetrdf/rdfHelpers.git", - "reference": "e0ae1d528766aae4c3bfa9e4312f02efbb6830b5" + "reference": "29db501d91ffe0056b8c3db1fe42d7cd13f9193f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/rdfHelpers/zipball/e0ae1d528766aae4c3bfa9e4312f02efbb6830b5", - "reference": "e0ae1d528766aae4c3bfa9e4312f02efbb6830b5", + "url": "https://api.github.com/repos/sweetrdf/rdfHelpers/zipball/29db501d91ffe0056b8c3db1fe42d7cd13f9193f", + "reference": "29db501d91ffe0056b8c3db1fe42d7cd13f9193f", "shasum": "" }, "require": { "php": ">=8.0", - "sweetrdf/rdf-interface": "^1.0.0", + "sweetrdf/rdf-interface": "^1 | ^2.0.0-RC3", "zozlak/rdf-constants": "^1.1" }, "require-dev": { @@ -1501,27 +1246,27 @@ "homepage": "https://github.com/sweetrdf/rdfHelpers", "support": { "issues": "https://github.com/sweetrdf/rdfHelpers/issues", - "source": "https://github.com/sweetrdf/rdfHelpers/tree/1.0.1" + "source": "https://github.com/sweetrdf/rdfHelpers/tree/1.2.0" }, - "time": "2023-04-02T08:59:30+00:00" + "time": "2023-08-31T12:13:56+00:00" }, { "name": "sweetrdf/rdf-interface", - "version": "1.0.0", + "version": "1.0.1", "source": { "type": "git", "url": "https://github.com/sweetrdf/rdfInterface.git", - "reference": "1d7645cc2f138017fe7d1421e3b0b479d6bee4a5" + "reference": "b0c930b7bd7a80e63f77510d0dcb261aead4f0a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/1d7645cc2f138017fe7d1421e3b0b479d6bee4a5", - "reference": "1d7645cc2f138017fe7d1421e3b0b479d6bee4a5", + "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/b0c930b7bd7a80e63f77510d0dcb261aead4f0a3", + "reference": "b0c930b7bd7a80e63f77510d0dcb261aead4f0a3", "shasum": "" }, "require": { "php": ">=8.0", - "psr/http-message": "^1.0", + "psr/http-message": "^1.0 || ^2.0", "zozlak/rdf-constants": "*" }, "require-dev": { @@ -1549,40 +1294,40 @@ "homepage": "https://github.com/sweetrdf/rdfInterface", "support": { "issues": "https://github.com/sweetrdf/rdfInterface/issues", - "source": "https://github.com/sweetrdf/rdfInterface/tree/1.0.0" + "source": "https://github.com/sweetrdf/rdfInterface/tree/1.0.1" }, - "time": "2022-11-01T09:27:45+00:00" + "time": "2023-07-21T08:26:06+00:00" }, { "name": "symfony/config", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae" + "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/a5e00dec161b08c946a2c16eed02adbeedf827ae", - "reference": "a5e00dec161b08c946a2c16eed02adbeedf827ae", + "url": "https://api.github.com/repos/symfony/config/zipball/8789646600f4e7e451dde9e1dc81cfa429f3857a", + "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^5.4|^6.0", + "symfony/filesystem": "^6.4|^7.0", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "symfony/finder": "<5.4", + "symfony/finder": "<6.4", "symfony/service-contracts": "<2.5" }, "require-dev": { - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/messenger": "^5.4|^6.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/yaml": "^5.4|^6.0" + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1610,7 +1355,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v6.3.0" + "source": "https://github.com/symfony/config/tree/v7.0.0" }, "funding": [ { @@ -1626,47 +1371,50 @@ "type": "tidelift" } ], - "time": "2023-04-25T10:46:17+00:00" + "time": "2023-11-09T08:30:23+00:00" }, { "name": "symfony/console", - "version": "v6.3.0", + "version": "v7.0.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7" + "reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", - "reference": "8788808b07cf0bdd6e4b7fdd23d8ddb1470c83b7", + "url": "https://api.github.com/repos/symfony/console/zipball/cdce5c684b2f920bb1343deecdfba356ffad83d5", + "reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3", - "symfony/string": "^5.4|^6.0" + "symfony/string": "^6.4|^7.0" }, "conflict": { - "symfony/dependency-injection": "<5.4", - "symfony/dotenv": "<5.4", - "symfony/event-dispatcher": "<5.4", - "symfony/lock": "<5.4", - "symfony/process": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/dotenv": "<6.4", + "symfony/event-dispatcher": "<6.4", + "symfony/lock": "<6.4", + "symfony/process": "<6.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/lock": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1700,7 +1448,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v6.3.0" + "source": "https://github.com/symfony/console/tree/v7.0.1" }, "funding": [ { @@ -1716,11 +1464,11 @@ "type": "tidelift" } ], - "time": "2023-05-29T12:49:39+00:00" + "time": "2023-12-01T15:10:06+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", @@ -1767,7 +1515,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" }, "funding": [ { @@ -1787,24 +1535,24 @@ }, { "name": "symfony/event-dispatcher", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa" + "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", - "reference": "3af8ac1a3f98f6dbc55e10ae59c9e44bfc38dfaa", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c459b40ffe67c49af6fd392aac374c9edf8a027e", + "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/event-dispatcher-contracts": "^2.5|^3" }, "conflict": { - "symfony/dependency-injection": "<5.4", + "symfony/dependency-injection": "<6.4", "symfony/service-contracts": "<2.5" }, "provide": { @@ -1813,13 +1561,13 @@ }, "require-dev": { "psr/log": "^1|^2|^3", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/service-contracts": "^2.5|^3", - "symfony/stopwatch": "^5.4|^6.0" + "symfony/stopwatch": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -1847,7 +1595,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v6.3.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.0" }, "funding": [ { @@ -1863,11 +1611,11 @@ "type": "tidelift" } ], - "time": "2023-04-21T14:41:17+00:00" + "time": "2023-07-27T16:29:09+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", @@ -1923,7 +1671,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" }, "funding": [ { @@ -1943,20 +1691,20 @@ }, { "name": "symfony/filesystem", - "version": "v6.3.1", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae" + "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", - "reference": "edd36776956f2a6fcf577edb5b05eb0e3bdc52ae", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/7da8ea2362a283771478c5f7729cfcb43a76b8b7", + "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, @@ -1986,7 +1734,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v6.3.1" + "source": "https://github.com/symfony/filesystem/tree/v7.0.0" }, "funding": [ { @@ -2002,27 +1750,27 @@ "type": "tidelift" } ], - "time": "2023-06-01T08:30:39+00:00" + "time": "2023-07-27T06:33:22+00:00" }, { "name": "symfony/finder", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2" + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/d9b01ba073c44cef617c7907ce2419f8d00d75e2", - "reference": "d9b01ba073c44cef617c7907ce2419f8d00d75e2", + "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "require-dev": { - "symfony/filesystem": "^6.0" + "symfony/filesystem": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -2050,7 +1798,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v6.3.0" + "source": "https://github.com/symfony/finder/tree/v7.0.0" }, "funding": [ { @@ -2066,24 +1814,24 @@ "type": "tidelift" } ], - "time": "2023-04-02T01:25:41+00:00" + "time": "2023-10-31T17:59:56+00:00" }, { "name": "symfony/options-resolver", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd" + "reference": "700ff4096e346f54cb628ea650767c8130f1001f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/a10f19f5198d589d5c33333cffe98dc9820332dd", - "reference": "a10f19f5198d589d5c33333cffe98dc9820332dd", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f", + "reference": "700ff4096e346f54cb628ea650767c8130f1001f", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3" }, "type": "library", @@ -2117,7 +1865,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v6.3.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.0.0" }, "funding": [ { @@ -2133,20 +1881,20 @@ "type": "tidelift" } ], - "time": "2023-05-12T14:21:09+00:00" + "time": "2023-08-08T10:20:21+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a" + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/5bbc823adecdae860bb64756d639ecfec17b050a", - "reference": "5bbc823adecdae860bb64756d639ecfec17b050a", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", "shasum": "" }, "require": { @@ -2161,7 +1909,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2199,7 +1947,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" }, "funding": [ { @@ -2215,20 +1963,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354" + "reference": "875e90aeea2777b6f135677f618529449334a612" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/511a08c03c1960e08a883f4cffcacd219b758354", - "reference": "511a08c03c1960e08a883f4cffcacd219b758354", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", + "reference": "875e90aeea2777b6f135677f618529449334a612", "shasum": "" }, "require": { @@ -2240,7 +1988,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2280,7 +2028,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" }, "funding": [ { @@ -2296,20 +2044,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6" + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/19bd1e4fcd5b91116f14d8533c57831ed00571b6", - "reference": "19bd1e4fcd5b91116f14d8533c57831ed00571b6", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", "shasum": "" }, "require": { @@ -2321,7 +2069,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2364,7 +2112,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" }, "funding": [ { @@ -2380,20 +2128,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534" + "reference": "42292d99c55abe617799667f454222c54c60e229" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/8ad114f6b39e2c98a8b0e3bd907732c207c2b534", - "reference": "8ad114f6b39e2c98a8b0e3bd907732c207c2b534", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", + "reference": "42292d99c55abe617799667f454222c54c60e229", "shasum": "" }, "require": { @@ -2408,7 +2156,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2447,7 +2195,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" }, "funding": [ { @@ -2463,20 +2211,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-07-28T09:04:16+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936" + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", - "reference": "7a6ff3f1959bb01aefccb463a0f2cd3d3d2fd936", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", "shasum": "" }, "require": { @@ -2485,7 +2233,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2530,7 +2278,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" }, "funding": [ { @@ -2546,20 +2294,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a" + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/707403074c8ea6e2edaf8794b0157a0bfa52157a", - "reference": "707403074c8ea6e2edaf8794b0157a0bfa52157a", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", + "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", "shasum": "" }, "require": { @@ -2568,7 +2316,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -2609,7 +2357,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" }, "funding": [ { @@ -2625,24 +2373,24 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/process", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628" + "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/8741e3ed7fe2e91ec099e02446fb86667a0f1628", - "reference": "8741e3ed7fe2e91ec099e02446fb86667a0f1628", + "url": "https://api.github.com/repos/symfony/process/zipball/13bdb1670c7f510494e04fcb2bfa29af63db9c0d", + "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d", "shasum": "" }, "require": { - "php": ">=8.1" + "php": ">=8.2" }, "type": "library", "autoload": { @@ -2670,7 +2418,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v6.3.0" + "source": "https://github.com/symfony/process/tree/v7.0.0" }, "funding": [ { @@ -2686,20 +2434,20 @@ "type": "tidelift" } ], - "time": "2023-05-19T08:06:44+00:00" + "time": "2023-11-20T16:43:42+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4" + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", - "reference": "40da9cc13ec349d9e4966ce18b5fbcd724ab10a4", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", "shasum": "" }, "require": { @@ -2752,7 +2500,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" }, "funding": [ { @@ -2768,24 +2516,24 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2023-07-30T20:28:31+00:00" }, { "name": "symfony/stopwatch", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2" + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", - "reference": "fc47f1015ec80927ff64ba9094dfe8b9d48fe9f2", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", + "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/service-contracts": "^2.5|^3" }, "type": "library", @@ -2814,7 +2562,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v6.3.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.0.0" }, "funding": [ { @@ -2830,24 +2578,24 @@ "type": "tidelift" } ], - "time": "2023-02-16T10:14:28+00:00" + "time": "2023-07-05T13:06:06+00:00" }, { "name": "symfony/string", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f" + "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/f2e190ee75ff0f5eced645ec0be5c66fac81f51f", - "reference": "f2e190ee75ff0f5eced645ec0be5c66fac81f51f", + "url": "https://api.github.com/repos/symfony/string/zipball/92bd2bfbba476d4a1838e5e12168bef2fd1e6620", + "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", @@ -2857,11 +2605,11 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { - "symfony/error-handler": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/intl": "^6.2", + "symfony/error-handler": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3.0", - "symfony/var-exporter": "^5.4|^6.0" + "symfony/var-exporter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -2900,7 +2648,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v6.3.0" + "source": "https://github.com/symfony/string/tree/v7.0.0" }, "funding": [ { @@ -2916,31 +2664,32 @@ "type": "tidelift" } ], - "time": "2023-03-21T21:06:29+00:00" + "time": "2023-11-29T08:40:23+00:00" }, { "name": "symfony/yaml", - "version": "v6.3.0", + "version": "v6.4.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927" + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/a9a8337aa641ef2aa39c3e028f9107ec391e5927", - "reference": "a9a8337aa641ef2aa39c3e028f9107ec391e5927", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", + "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", "shasum": "" }, "require": { "php": ">=8.1", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "symfony/console": "<5.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0" + "symfony/console": "^5.4|^6.0|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -2971,7 +2720,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.3.0" + "source": "https://github.com/symfony/yaml/tree/v6.4.0" }, "funding": [ { @@ -2987,30 +2736,31 @@ "type": "tidelift" } ], - "time": "2023-04-28T13:28:14+00:00" + "time": "2023-11-06T11:00:25+00:00" }, { "name": "twig/twig", - "version": "v3.6.1", + "version": "v3.8.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd" + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd", - "reference": "7e7d5839d4bec168dfeef0ac66d5c5a2edbabffd", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", "shasum": "" }, "require": { "php": ">=7.2.5", "symfony/polyfill-ctype": "^1.8", - "symfony/polyfill-mbstring": "^1.3" + "symfony/polyfill-mbstring": "^1.3", + "symfony/polyfill-php80": "^1.22" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^4.4.9|^5.0.9|^6.0" + "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" }, "type": "library", "autoload": { @@ -3046,7 +2796,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.6.1" + "source": "https://github.com/twigphp/Twig/tree/v3.8.0" }, "funding": [ { @@ -3058,7 +2808,7 @@ "type": "tidelift" } ], - "time": "2023-06-08T12:52:13+00:00" + "time": "2023-11-21T18:54:41+00:00" }, { "name": "zozlak/rdf-constants", @@ -3102,16 +2852,16 @@ "packages-dev": [ { "name": "api-platform/core", - "version": "v3.1.12", + "version": "v3.2.7", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "1fe505a9d8fd235a8d7e4aa0f245f382f65578f8" + "reference": "f297d2192652a3acd2a644707740de8cb5069221" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/1fe505a9d8fd235a8d7e4aa0f245f382f65578f8", - "reference": "1fe505a9d8fd235a8d7e4aa0f245f382f65578f8", + "url": "https://api.github.com/repos/api-platform/core/zipball/f297d2192652a3acd2a644707740de8cb5069221", + "reference": "f297d2192652a3acd2a644707740de8cb5069221", "shasum": "" }, "require": { @@ -3120,12 +2870,13 @@ "psr/cache": "^1.0 || ^2.0 || ^3.0", "psr/container": "^1.0 || ^2.0", "symfony/deprecation-contracts": "^3.1", - "symfony/http-foundation": "^6.1", - "symfony/http-kernel": "^6.1", - "symfony/property-access": "^6.1", - "symfony/property-info": "^6.1", - "symfony/serializer": "^6.1", - "symfony/web-link": "^6.1", + "symfony/http-foundation": "^6.1 || ^7.0", + "symfony/http-kernel": "^6.1 || ^7.0", + "symfony/property-access": "^6.1 || ^7.0", + "symfony/property-info": "^6.1 || ^7.0", + "symfony/serializer": "^6.1 || ^7.0", + "symfony/translation-contracts": "^3.3", + "symfony/web-link": "^6.1 || ^7.0", "willdurand/negotiation": "^3.0" }, "conflict": { @@ -3134,24 +2885,21 @@ "doctrine/mongodb-odm": "<2.4", "doctrine/orm": "<2.14.0", "doctrine/persistence": "<1.3", - "elasticsearch/elasticsearch": ">=8.0", + "elasticsearch/elasticsearch": ">=8.0,<8.4", "phpspec/prophecy": "<1.15", "phpunit/phpunit": "<9.5", - "symfony/service-contracts": "<3", "symfony/var-exporter": "<6.1.1" }, "require-dev": { - "behat/behat": "^3.1", - "behat/mink": "^1.9@dev", + "behat/behat": "^3.11", + "behat/mink": "^1.9", "doctrine/cache": "^1.11 || ^2.1", "doctrine/common": "^3.2.2", - "doctrine/data-fixtures": "^1.2.2", "doctrine/dbal": "^3.4.0", "doctrine/doctrine-bundle": "^1.12 || ^2.0", "doctrine/mongodb-odm": "^2.2", - "doctrine/mongodb-odm-bundle": "^4.0", "doctrine/orm": "^2.14", - "elasticsearch/elasticsearch": "^7.11.0", + "elasticsearch/elasticsearch": "^7.11 || ^8.4", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", "friends-of-behat/symfony-extension": "^2.1", @@ -3166,39 +2914,40 @@ "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-symfony": "^1.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "ramsey/uuid": "^3.7 || ^4.0", - "ramsey/uuid-doctrine": "^1.4", - "soyuka/contexts": "^3.3.6", + "ramsey/uuid": "^3.9.7 || ^4.0", + "ramsey/uuid-doctrine": "^1.4 || ^2.0", + "soyuka/contexts": "v3.3.9", "soyuka/stubs-mongodb": "^1.0", - "symfony/asset": "^6.1", - "symfony/browser-kit": "^6.1", - "symfony/cache": "^6.1", - "symfony/config": "^6.1", - "symfony/console": "^6.1", - "symfony/css-selector": "^6.1", - "symfony/dependency-injection": "^6.1", - "symfony/doctrine-bridge": "^6.1", - "symfony/dom-crawler": "^6.1", - "symfony/error-handler": "^6.1", - "symfony/event-dispatcher": "^6.1", - "symfony/expression-language": "^6.1", - "symfony/finder": "^6.1", - "symfony/form": "^6.1", - "symfony/framework-bundle": "^6.1", - "symfony/http-client": "^6.1", - "symfony/intl": "^6.1", + "symfony/asset": "^6.1 || ^7.0", + "symfony/browser-kit": "^6.1 || ^7.0", + "symfony/cache": "^6.1 || ^7.0", + "symfony/config": "^6.1 || ^7.0", + "symfony/console": "^6.1 || ^7.0", + "symfony/css-selector": "^6.1 || ^7.0", + "symfony/dependency-injection": "^6.1 || ^7.0.12", + "symfony/doctrine-bridge": "^6.1 || ^7.0", + "symfony/dom-crawler": "^6.1 || ^7.0", + "symfony/error-handler": "^6.1 || ^7.0", + "symfony/event-dispatcher": "^6.1 || ^7.0", + "symfony/expression-language": "^6.1 || ^7.0", + "symfony/finder": "^6.1 || ^7.0", + "symfony/form": "^6.1 || ^7.0", + "symfony/framework-bundle": "^6.1 || ^7.0", + "symfony/http-client": "^6.1 || ^7.0", + "symfony/intl": "^6.1 || ^7.0", "symfony/maker-bundle": "^1.24", "symfony/mercure-bundle": "*", - "symfony/messenger": "^6.1", - "symfony/phpunit-bridge": "^6.1", - "symfony/routing": "^6.1", - "symfony/security-bundle": "^6.1", - "symfony/security-core": "^6.1", - "symfony/twig-bundle": "^6.1", - "symfony/uid": "^6.1", - "symfony/validator": "^6.1", - "symfony/web-profiler-bundle": "^6.1", - "symfony/yaml": "^6.1", + "symfony/messenger": "^6.1 || ^7.0", + "symfony/phpunit-bridge": "^6.1 || ^7.0", + "symfony/routing": "^6.1 || ^7.0", + "symfony/security-bundle": "^6.1 || ^7.0", + "symfony/security-core": "^6.1 || ^7.0", + "symfony/stopwatch": "^6.1 || ^7.0", + "symfony/twig-bundle": "^6.1 || ^7.0", + "symfony/uid": "^6.1 || ^7.0", + "symfony/validator": "^6.1 || ^7.0", + "symfony/web-profiler-bundle": "^6.1 || ^7.0", + "symfony/yaml": "^6.1 || ^7.0", "twig/twig": "^1.42.3 || ^2.12 || ^3.0", "webonyx/graphql-php": "^14.0 || ^15.0" }, @@ -3223,10 +2972,10 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.2.x-dev" + "dev-main": "3.3.x-dev" }, "symfony": { - "require": "^6.1" + "require": "^6.1 || ^7.0" } }, "autoload": { @@ -3260,15 +3009,9 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v3.1.12" + "source": "https://github.com/api-platform/core/tree/v3.2.7" }, - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/api-platform/core", - "type": "tidelift" - } - ], - "time": "2023-05-24T19:23:57+00:00" + "time": "2023-11-30T13:51:25+00:00" }, { "name": "doctrine/cache", @@ -3365,16 +3108,16 @@ }, { "name": "doctrine/collections", - "version": "2.1.2", + "version": "2.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "db8cda536a034337f7dd63febecc713d4957f9ee" + "reference": "72328a11443a0de79967104ad36ba7b30bded134" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/db8cda536a034337f7dd63febecc713d4957f9ee", - "reference": "db8cda536a034337f7dd63febecc713d4957f9ee", + "url": "https://api.github.com/repos/doctrine/collections/zipball/72328a11443a0de79967104ad36ba7b30bded134", + "reference": "72328a11443a0de79967104ad36ba7b30bded134", "shasum": "" }, "require": { @@ -3382,12 +3125,12 @@ "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^10.0", + "doctrine/coding-standard": "^12", "ext-json": "*", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.0", "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.22" + "vimeo/psalm": "^5.11" }, "type": "library", "autoload": { @@ -3431,7 +3174,7 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/2.1.2" + "source": "https://github.com/doctrine/collections/tree/2.1.4" }, "funding": [ { @@ -3447,7 +3190,7 @@ "type": "tidelift" } ], - "time": "2022-12-27T23:41:38+00:00" + "time": "2023-10-03T09:22:33+00:00" }, { "name": "doctrine/common", @@ -3542,16 +3285,16 @@ }, { "name": "doctrine/dbal", - "version": "3.6.4", + "version": "3.7.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f" + "reference": "0ac3c270590e54910715e9a1a044cc368df282b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f", - "reference": "19f0dec95edd6a3c3c5ff1d188ea94c6b7fc903f", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/0ac3c270590e54910715e9a1a044cc368df282b2", + "reference": "0ac3c270590e54910715e9a1a044cc368df282b2", "shasum": "" }, "require": { @@ -3566,11 +3309,12 @@ "require-dev": { "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2022.3", - "phpstan/phpstan": "1.10.14", + "jetbrains/phpstorm-stubs": "2023.1", + "phpstan/phpstan": "1.10.42", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.7", + "phpunit/phpunit": "9.6.13", "psalm/plugin-phpunit": "0.18.4", + "slevomat/coding-standard": "8.13.1", "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^5.4|^6.0", "symfony/console": "^4.4|^5.4|^6.0", @@ -3634,7 +3378,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.6.4" + "source": "https://github.com/doctrine/dbal/tree/3.7.2" }, "funding": [ { @@ -3650,7 +3394,54 @@ "type": "tidelift" } ], - "time": "2023-06-15T07:40:12+00:00" + "time": "2023-11-19T08:06:58+00:00" + }, + { + "name": "doctrine/deprecations", + "version": "1.1.2", + "source": { + "type": "git", + "url": "https://github.com/doctrine/deprecations.git", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "1.4.10 || 1.10.15", + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "0.18.4", + "psr/log": "^1 || ^2 || ^3", + "vimeo/psalm": "4.30.0 || 5.12.0" + }, + "suggest": { + "psr/log": "Allows logging deprecations via PSR-3 logger implementation" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 logging with options to disable all deprecations or selectively for packages.", + "homepage": "https://www.doctrine-project.org/", + "support": { + "issues": "https://github.com/doctrine/deprecations/issues", + "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + }, + "time": "2023-09-27T20:04:15+00:00" }, { "name": "doctrine/event-manager", @@ -3813,18 +3604,96 @@ ], "time": "2022-12-30T00:23:10+00:00" }, + { + "name": "doctrine/lexer", + "version": "2.1.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/lexer.git", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "shasum": "" + }, + "require": { + "doctrine/deprecations": "^1.0", + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^10", + "phpstan/phpstan": "^1.3", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "psalm/plugin-phpunit": "^0.18.3", + "vimeo/psalm": "^4.11 || ^5.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Common\\Lexer\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Guilherme Blanco", + "email": "guilhermeblanco@gmail.com" + }, + { + "name": "Roman Borschel", + "email": "roman@code-factory.org" + }, + { + "name": "Johannes Schmitt", + "email": "schmittjoh@gmail.com" + } + ], + "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", + "homepage": "https://www.doctrine-project.org/projects/lexer.html", + "keywords": [ + "annotations", + "docblock", + "lexer", + "parser", + "php" + ], + "support": { + "issues": "https://github.com/doctrine/lexer/issues", + "source": "https://github.com/doctrine/lexer/tree/2.1.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", + "type": "tidelift" + } + ], + "time": "2022-12-14T08:49:07+00:00" + }, { "name": "doctrine/orm", - "version": "2.15.3", + "version": "2.17.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "4c3bd208018c26498e5f682aaad45fa00ea307d5" + "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/4c3bd208018c26498e5f682aaad45fa00ea307d5", - "reference": "4c3bd208018c26498e5f682aaad45fa00ea307d5", + "url": "https://api.github.com/repos/doctrine/orm/zipball/1a4fe6e0bb67762370937a7e6cee3da40a9122d1", + "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1", "shasum": "" }, "require": { @@ -3842,7 +3711,7 @@ "ext-ctype": "*", "php": "^7.1 || ^8.0", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0", + "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", "symfony/polyfill-php72": "^1.23", "symfony/polyfill-php80": "^1.16" }, @@ -3853,14 +3722,14 @@ "doctrine/annotations": "^1.13 || ^2", "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.18", + "phpstan/phpstan": "~1.4.10 || 1.10.35", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", "symfony/cache": "^4.4 || ^5.4 || ^6.0", "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.12.0" + "vimeo/psalm": "4.30.0 || 5.15.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -3910,9 +3779,9 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.15.3" + "source": "https://github.com/doctrine/orm/tree/2.17.1" }, - "time": "2023-06-22T12:36:06+00:00" + "time": "2023-11-17T06:25:40+00:00" }, { "name": "doctrine/persistence", @@ -4357,16 +4226,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.7.2", + "version": "1.7.3", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d" + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/b2fe4d22a5426f38e014855322200b97b5362c0d", - "reference": "b2fe4d22a5426f38e014855322200b97b5362c0d", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", "shasum": "" }, "require": { @@ -4409,9 +4278,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" }, - "time": "2023-05-30T18:13:47+00:00" + "time": "2023-08-12T11:01:26+00:00" }, { "name": "phpspec/prophecy", @@ -4535,16 +4404,16 @@ }, { "name": "phpstan/phpdoc-parser", - "version": "1.22.1", + "version": "1.24.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "65c39594fbd8c67abfc68bb323f86447bab79cc0" + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/65c39594fbd8c67abfc68bb323f86447bab79cc0", - "reference": "65c39594fbd8c67abfc68bb323f86447bab79cc0", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", "shasum": "" }, "require": { @@ -4576,22 +4445,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.22.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.4" }, - "time": "2023-06-29T20:46:06+00:00" + "time": "2023-11-26T18:29:22+00:00" }, { "name": "phpstan/phpstan", - "version": "1.10.26", + "version": "1.10.47", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "5d660cbb7e1b89253a47147ae44044f49832351f" + "reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5d660cbb7e1b89253a47147ae44044f49832351f", - "reference": "5d660cbb7e1b89253a47147ae44044f49832351f", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/84dbb33b520ea28b6cf5676a3941f4bae1c1ff39", + "reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39", "shasum": "" }, "require": { @@ -4640,20 +4509,20 @@ "type": "tidelift" } ], - "time": "2023-07-19T12:44:37+00:00" + "time": "2023-12-01T15:19:17+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.26", + "version": "9.2.29", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1" + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", - "reference": "443bc6912c9bd5b409254a40f4b0f4ced7c80ea1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", "shasum": "" }, "require": { @@ -4709,7 +4578,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.26" + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" }, "funding": [ { @@ -4717,7 +4587,7 @@ "type": "github" } ], - "time": "2023-03-06T12:58:08+00:00" + "time": "2023-09-19T04:57:46+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4962,16 +4832,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.10", + "version": "9.6.15", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328" + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a6d351645c3fe5a30f5e86be6577d946af65a328", - "reference": "a6d351645c3fe5a30f5e86be6577d946af65a328", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", + "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", "shasum": "" }, "require": { @@ -4986,7 +4856,7 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.13", + "phpunit/php-code-coverage": "^9.2.28", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -5045,7 +4915,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" }, "funding": [ { @@ -5061,7 +4931,56 @@ "type": "tidelift" } ], - "time": "2023-07-10T04:04:23+00:00" + "time": "2023-12-01T16:55:19+00:00" + }, + { + "name": "psr/cache", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/cache.git", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/cache/zipball/aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "reference": "aa5030cfa5405eccfdcb1083ce040c2cb8d253bf", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for caching libraries", + "keywords": [ + "cache", + "psr", + "psr-6" + ], + "support": { + "source": "https://github.com/php-fig/cache/tree/3.0.0" + }, + "time": "2021-02-03T23:26:27+00:00" }, { "name": "psr/link", @@ -5559,16 +5478,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.5", + "version": "5.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" + "reference": "bde739e7565280bda77be70044ac1047bc007e34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", - "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", + "reference": "bde739e7565280bda77be70044ac1047bc007e34", "shasum": "" }, "require": { @@ -5611,7 +5530,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" }, "funding": [ { @@ -5619,7 +5538,7 @@ "type": "github" } ], - "time": "2022-02-14T08:28:10+00:00" + "time": "2023-08-02T09:26:13+00:00" }, { "name": "sebastian/lines-of-code", @@ -6019,69 +5938,65 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v6.3.1", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "594263c7d2677022a16e4f39d20070463ba03888" + "reference": "5e8e95e8389d03f2f3ae16a6c7c804849ed483b5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/594263c7d2677022a16e4f39d20070463ba03888", - "reference": "594263c7d2677022a16e4f39d20070463ba03888", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/5e8e95e8389d03f2f3ae16a6c7c804849ed483b5", + "reference": "5e8e95e8389d03f2f3ae16a6c7c804849ed483b5", "shasum": "" }, "require": { - "doctrine/event-manager": "^1.2|^2", - "doctrine/persistence": "^2|^3", - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "doctrine/event-manager": "^2", + "doctrine/persistence": "^3.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.13.1", - "doctrine/dbal": "<2.13.1", + "doctrine/dbal": "<3.6", "doctrine/lexer": "<1.1", - "doctrine/orm": "<2.12", - "symfony/cache": "<5.4", - "symfony/dependency-injection": "<6.2", - "symfony/form": "<5.4.21|>=6,<6.2.7", - "symfony/http-foundation": "<6.3", - "symfony/http-kernel": "<6.2", - "symfony/lock": "<6.3", - "symfony/messenger": "<5.4", - "symfony/property-info": "<5.4", - "symfony/security-bundle": "<5.4", - "symfony/security-core": "<6.0", - "symfony/validator": "<5.4.25|>=6,<6.2.12|>=6.3,<6.3.1" + "doctrine/orm": "<2.15", + "symfony/cache": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/form": "<6.4", + "symfony/http-foundation": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/lock": "<6.4", + "symfony/messenger": "<6.4", + "symfony/property-info": "<6.4", + "symfony/security-bundle": "<6.4", + "symfony/security-core": "<6.4", + "symfony/validator": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.13.1|^2", "doctrine/collections": "^1.0|^2.0", "doctrine/data-fixtures": "^1.1", - "doctrine/dbal": "^2.13.1|^3.0", - "doctrine/orm": "^2.12", + "doctrine/dbal": "^3.6|^4", + "doctrine/orm": "^2.15|^3", "psr/log": "^1|^2|^3", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/dependency-injection": "^6.2", - "symfony/doctrine-messenger": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/form": "^5.4.21|^6.2.7", - "symfony/http-kernel": "^6.3", - "symfony/lock": "^6.3", - "symfony/messenger": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/proxy-manager-bridge": "^5.4|^6.0", - "symfony/security-core": "^6.0", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4.25|~6.2.12|^6.3.1", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/doctrine-messenger": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/lock": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/security-core": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" }, "type": "symfony-bridge", "autoload": { @@ -6109,7 +6024,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v6.3.1" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.0" }, "funding": [ { @@ -6125,34 +6040,35 @@ "type": "tidelift" } ], - "time": "2023-06-18T20:33:34+00:00" + "time": "2023-11-17T16:04:05+00:00" }, { "name": "symfony/error-handler", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "99d2d814a6351461af350ead4d963bd67451236f" + "reference": "80b1258be1b84c12a345d0ec3881bbf2e5270cc2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/99d2d814a6351461af350ead4d963bd67451236f", - "reference": "99d2d814a6351461af350ead4d963bd67451236f", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/80b1258be1b84c12a345d0ec3881bbf2e5270cc2", + "reference": "80b1258be1b84c12a345d0ec3881bbf2e5270cc2", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/var-dumper": "^5.4|^6.0" + "symfony/var-dumper": "^6.4|^7.0" }, "conflict": { - "symfony/deprecation-contracts": "<2.5" + "symfony/deprecation-contracts": "<2.5", + "symfony/http-kernel": "<6.4" }, "require-dev": { "symfony/deprecation-contracts": "^2.5|^3", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/http-kernel": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "bin": [ "Resources/bin/patch-type-declarations" @@ -6183,7 +6099,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v6.3.0" + "source": "https://github.com/symfony/error-handler/tree/v7.0.0" }, "funding": [ { @@ -6199,40 +6115,40 @@ "type": "tidelift" } ], - "time": "2023-05-10T12:03:13+00:00" + "time": "2023-10-20T16:35:23+00:00" }, { "name": "symfony/http-foundation", - "version": "v6.3.1", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e0ad0d153e1c20069250986cd9e9dd1ccebb0d66" + "reference": "47d72323200934694def5d57083899d774a2b110" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e0ad0d153e1c20069250986cd9e9dd1ccebb0d66", - "reference": "e0ad0d153e1c20069250986cd9e9dd1ccebb0d66", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/47d72323200934694def5d57083899d774a2b110", + "reference": "47d72323200934694def5d57083899d774a2b110", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, "conflict": { - "symfony/cache": "<6.2" + "doctrine/dbal": "<3.6", + "symfony/cache": "<6.4" }, "require-dev": { - "doctrine/dbal": "^2.13.1|^3.0", + "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", - "symfony/mime": "^5.4|^6.0", - "symfony/rate-limiter": "^5.2|^6.0" + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/rate-limiter": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6260,7 +6176,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v6.3.1" + "source": "https://github.com/symfony/http-foundation/tree/v7.0.0" }, "funding": [ { @@ -6276,76 +6192,75 @@ "type": "tidelift" } ], - "time": "2023-06-24T11:51:27+00:00" + "time": "2023-11-07T15:10:37+00:00" }, { "name": "symfony/http-kernel", - "version": "v6.3.1", + "version": "v7.0.1", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "161e16fd2e35fb4881a43bc8b383dfd5be4ac374" + "reference": "4787639523dcdda32f69063f7fca2ad709f3c6d2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/161e16fd2e35fb4881a43bc8b383dfd5be4ac374", - "reference": "161e16fd2e35fb4881a43bc8b383dfd5be4ac374", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4787639523dcdda32f69063f7fca2ad709f3c6d2", + "reference": "4787639523dcdda32f69063f7fca2ad709f3c6d2", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/log": "^1|^2|^3", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/error-handler": "^6.3", - "symfony/event-dispatcher": "^5.4|^6.0", - "symfony/http-foundation": "^6.2.7", + "symfony/error-handler": "^6.4|^7.0", + "symfony/event-dispatcher": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/browser-kit": "<5.4", - "symfony/cache": "<5.4", - "symfony/config": "<6.1", - "symfony/console": "<5.4", - "symfony/dependency-injection": "<6.3", - "symfony/doctrine-bridge": "<5.4", - "symfony/form": "<5.4", - "symfony/http-client": "<5.4", + "symfony/browser-kit": "<6.4", + "symfony/cache": "<6.4", + "symfony/config": "<6.4", + "symfony/console": "<6.4", + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<6.4", + "symfony/form": "<6.4", + "symfony/http-client": "<6.4", "symfony/http-client-contracts": "<2.5", - "symfony/mailer": "<5.4", - "symfony/messenger": "<5.4", - "symfony/translation": "<5.4", + "symfony/mailer": "<6.4", + "symfony/messenger": "<6.4", + "symfony/translation": "<6.4", "symfony/translation-contracts": "<2.5", - "symfony/twig-bridge": "<5.4", - "symfony/validator": "<5.4", - "symfony/var-dumper": "<6.3", - "twig/twig": "<2.13" + "symfony/twig-bridge": "<6.4", + "symfony/validator": "<6.4", + "symfony/var-dumper": "<6.4", + "twig/twig": "<3.0.4" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" }, "require-dev": { "psr/cache": "^1.0|^2.0|^3.0", - "symfony/browser-kit": "^5.4|^6.0", - "symfony/clock": "^6.2", - "symfony/config": "^6.1", - "symfony/console": "^5.4|^6.0", - "symfony/css-selector": "^5.4|^6.0", - "symfony/dependency-injection": "^6.3", - "symfony/dom-crawler": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", + "symfony/browser-kit": "^6.4|^7.0", + "symfony/clock": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/css-selector": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dom-crawler": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3", - "symfony/process": "^5.4|^6.0", - "symfony/property-access": "^5.4.5|^6.0.5", - "symfony/routing": "^5.4|^6.0", - "symfony/serializer": "^6.3", - "symfony/stopwatch": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", + "symfony/process": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/routing": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/stopwatch": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^6.3", - "symfony/var-exporter": "^6.2", - "twig/twig": "^2.13|^3.0.4" + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "twig/twig": "^3.0.4" }, "type": "library", "autoload": { @@ -6373,7 +6288,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v6.3.1" + "source": "https://github.com/symfony/http-kernel/tree/v7.0.1" }, "funding": [ { @@ -6389,31 +6304,31 @@ "type": "tidelift" } ], - "time": "2023-06-26T06:07:32+00:00" + "time": "2023-12-01T17:08:48+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v6.3.1", + "version": "v7.0.1", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "0b0bf59b0d9bd1422145a123a67fb12af546ef0d" + "reference": "c2d059b25e31274157dd7727131cd1cf33650207" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/0b0bf59b0d9bd1422145a123a67fb12af546ef0d", - "reference": "0b0bf59b0d9bd1422145a123a67fb12af546ef0d", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/c2d059b25e31274157dd7727131cd1cf33650207", + "reference": "c2d059b25e31274157dd7727131cd1cf33650207", "shasum": "" }, "require": { - "php": ">=7.1.3" + "php": ">=7.2.5" }, "conflict": { "phpunit/phpunit": "<7.5|9.1.2" }, "require-dev": { "symfony/deprecation-contracts": "^2.5|^3.0", - "symfony/error-handler": "^5.4|^6.0", + "symfony/error-handler": "^5.4|^6.4|^7.0", "symfony/polyfill-php81": "^1.27" }, "bin": [ @@ -6454,7 +6369,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v6.3.1" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.1" }, "funding": [ { @@ -6470,20 +6385,20 @@ "type": "tidelift" } ], - "time": "2023-06-23T13:25:16+00:00" + "time": "2023-12-01T09:26:31+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97" + "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/869329b1e9894268a8a61dabb69153029b7a8c97", - "reference": "869329b1e9894268a8a61dabb69153029b7a8c97", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", + "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", "shasum": "" }, "require": { @@ -6492,7 +6407,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -6530,7 +6445,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" }, "funding": [ { @@ -6546,20 +6461,20 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-01-26T09:26:14+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.27.0", + "version": "v1.28.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "508c652ba3ccf69f8c97f251534f229791b52a57" + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/508c652ba3ccf69f8c97f251534f229791b52a57", - "reference": "508c652ba3ccf69f8c97f251534f229791b52a57", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", "shasum": "" }, "require": { @@ -6569,7 +6484,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.27-dev" + "dev-main": "1.28-dev" }, "thanks": { "name": "symfony/polyfill", @@ -6582,7 +6497,10 @@ ], "psr-4": { "Symfony\\Polyfill\\Php83\\": "" - } + }, + "classmap": [ + "Resources/stubs" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -6607,7 +6525,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.27.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.0" }, "funding": [ { @@ -6623,29 +6541,28 @@ "type": "tidelift" } ], - "time": "2022-11-03T14:55:06+00:00" + "time": "2023-08-16T06:22:46+00:00" }, { "name": "symfony/property-access", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "db9358571ce63f09c439c2fee6c12e5b090b69ac" + "reference": "740e8cb8c54a4f16c82179e8558c29d9fc49901d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/db9358571ce63f09c439c2fee6c12e5b090b69ac", - "reference": "db9358571ce63f09c439c2fee6c12e5b090b69ac", + "url": "https://api.github.com/repos/symfony/property-access/zipball/740e8cb8c54a4f16c82179e8558c29d9fc49901d", + "reference": "740e8cb8c54a4f16c82179e8558c29d9fc49901d", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", - "symfony/property-info": "^5.4|^6.0" + "php": ">=8.2", + "symfony/property-info": "^6.4|^7.0" }, "require-dev": { - "symfony/cache": "^5.4|^6.0" + "symfony/cache": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6684,7 +6601,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v6.3.0" + "source": "https://github.com/symfony/property-access/tree/v7.0.0" }, "funding": [ { @@ -6700,38 +6617,38 @@ "type": "tidelift" } ], - "time": "2023-05-19T08:06:44+00:00" + "time": "2023-09-27T14:05:33+00:00" }, { "name": "symfony/property-info", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "7f3a03716112269741fe2a809f8f791a371d1fcd" + "reference": "ce627df05f5629ce4feec536ee827ad0a12689b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/7f3a03716112269741fe2a809f8f791a371d1fcd", - "reference": "7f3a03716112269741fe2a809f8f791a371d1fcd", + "url": "https://api.github.com/repos/symfony/property-info/zipball/ce627df05f5629ce4feec536ee827ad0a12689b6", + "reference": "ce627df05f5629ce4feec536ee827ad0a12689b6", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/string": "^5.4|^6.0" + "php": ">=8.2", + "symfony/string": "^6.4|^7.0" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", - "symfony/dependency-injection": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/serializer": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.10.4|^2", "phpdocumentor/reflection-docblock": "^5.2", "phpstan/phpdoc-parser": "^1.0", - "symfony/cache": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/serializer": "^5.4|^6.0" + "symfony/cache": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6767,7 +6684,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v6.3.0" + "source": "https://github.com/symfony/property-info/tree/v7.0.0" }, "funding": [ { @@ -6783,56 +6700,58 @@ "type": "tidelift" } ], - "time": "2023-05-19T08:06:44+00:00" + "time": "2023-11-25T08:38:27+00:00" }, { "name": "symfony/serializer", - "version": "v6.3.1", + "version": "v7.0.1", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "1d238ee3180bc047f8ab713bfb73848d553f4407" + "reference": "9c8f67c1444adf6dbcf90fb76da5b2f5c43af0ff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/1d238ee3180bc047f8ab713bfb73848d553f4407", - "reference": "1d238ee3180bc047f8ab713bfb73848d553f4407", + "url": "https://api.github.com/repos/symfony/serializer/zipball/9c8f67c1444adf6dbcf90fb76da5b2f5c43af0ff", + "reference": "9c8f67c1444adf6dbcf90fb76da5b2f5c43af0ff", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8" }, "conflict": { - "doctrine/annotations": "<1.12", "phpdocumentor/reflection-docblock": "<3.2.2", "phpdocumentor/type-resolver": "<1.4.0", - "symfony/dependency-injection": "<5.4", - "symfony/property-access": "<5.4", - "symfony/property-info": "<5.4", - "symfony/uid": "<5.4", - "symfony/yaml": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/property-access": "<6.4", + "symfony/property-info": "<6.4", + "symfony/uid": "<6.4", + "symfony/validator": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.12|^2", "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/error-handler": "^5.4|^6.0", - "symfony/filesystem": "^5.4|^6.0", - "symfony/form": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "symfony/validator": "^5.4|^6.0", - "symfony/var-dumper": "^5.4|^6.0", - "symfony/var-exporter": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" + "seld/jsonlint": "^1.10", + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/error-handler": "^6.4|^7.0", + "symfony/filesystem": "^6.4|^7.0", + "symfony/form": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/messenger": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation-contracts": "^2.5|^3", + "symfony/uid": "^6.4|^7.0", + "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", + "symfony/var-exporter": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -6860,7 +6779,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v6.3.1" + "source": "https://github.com/symfony/serializer/tree/v7.0.1" }, "funding": [ { @@ -6876,20 +6795,20 @@ "type": "tidelift" } ], - "time": "2023-06-21T19:54:33+00:00" + "time": "2023-12-01T15:10:06+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.3.0", + "version": "v3.4.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86" + "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/02c24deb352fb0d79db5486c0c79905a85e37e86", - "reference": "02c24deb352fb0d79db5486c0c79905a85e37e86", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", "shasum": "" }, "require": { @@ -6938,7 +6857,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.3.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" }, "funding": [ { @@ -6954,59 +6873,57 @@ "type": "tidelift" } ], - "time": "2023-05-30T17:17:10+00:00" + "time": "2023-07-25T15:08:44+00:00" }, { "name": "symfony/validator", - "version": "v6.3.1", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "1b71f43c62ee867ab08195ba6039a1bc3e6654dc" + "reference": "616b39ffb22c1519f7fd2582b8052cde4c2d0b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/1b71f43c62ee867ab08195ba6039a1bc3e6654dc", - "reference": "1b71f43c62ee867ab08195ba6039a1bc3e6654dc", + "url": "https://api.github.com/repos/symfony/validator/zipball/616b39ffb22c1519f7fd2582b8052cde4c2d0b9f", + "reference": "616b39ffb22c1519f7fd2582b8052cde4c2d0b9f", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php83": "^1.27", "symfony/translation-contracts": "^2.5|^3" }, "conflict": { - "doctrine/annotations": "<1.13", "doctrine/lexer": "<1.1", - "symfony/dependency-injection": "<5.4", - "symfony/expression-language": "<5.4", - "symfony/http-kernel": "<5.4", - "symfony/intl": "<5.4", - "symfony/property-info": "<5.4", - "symfony/translation": "<5.4", - "symfony/yaml": "<5.4" + "symfony/dependency-injection": "<6.4", + "symfony/doctrine-bridge": "<7.0", + "symfony/expression-language": "<6.4", + "symfony/http-kernel": "<6.4", + "symfony/intl": "<6.4", + "symfony/property-info": "<6.4", + "symfony/translation": "<6.4", + "symfony/yaml": "<6.4" }, "require-dev": { - "doctrine/annotations": "^1.13|^2", "egulias/email-validator": "^2.1.10|^3|^4", - "symfony/cache": "^5.4|^6.0", - "symfony/config": "^5.4|^6.0", - "symfony/console": "^5.4|^6.0", - "symfony/dependency-injection": "^5.4|^6.0", - "symfony/expression-language": "^5.4|^6.0", - "symfony/finder": "^5.4|^6.0", - "symfony/http-client": "^5.4|^6.0", - "symfony/http-foundation": "^5.4|^6.0", - "symfony/http-kernel": "^5.4|^6.0", - "symfony/intl": "^5.4|^6.0", - "symfony/mime": "^5.4|^6.0", - "symfony/property-access": "^5.4|^6.0", - "symfony/property-info": "^5.4|^6.0", - "symfony/translation": "^5.4|^6.0", - "symfony/yaml": "^5.4|^6.0" + "symfony/cache": "^6.4|^7.0", + "symfony/config": "^6.4|^7.0", + "symfony/console": "^6.4|^7.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/expression-language": "^6.4|^7.0", + "symfony/finder": "^6.4|^7.0", + "symfony/http-client": "^6.4|^7.0", + "symfony/http-foundation": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/intl": "^6.4|^7.0", + "symfony/mime": "^6.4|^7.0", + "symfony/property-access": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0", + "symfony/translation": "^6.4|^7.0", + "symfony/yaml": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7034,7 +6951,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v6.3.1" + "source": "https://github.com/symfony/validator/tree/v7.0.0" }, "funding": [ { @@ -7050,35 +6967,36 @@ "type": "tidelift" } ], - "time": "2023-06-21T12:08:28+00:00" + "time": "2023-11-29T08:40:23+00:00" }, { "name": "symfony/var-dumper", - "version": "v6.3.1", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "c81268d6960ddb47af17391a27d222bd58cf0515" + "reference": "cf0220fc7607476fd0d001ab3ed9e830d1fdda56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/c81268d6960ddb47af17391a27d222bd58cf0515", - "reference": "c81268d6960ddb47af17391a27d222bd58cf0515", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cf0220fc7607476fd0d001ab3ed9e830d1fdda56", + "reference": "cf0220fc7607476fd0d001ab3ed9e830d1fdda56", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { "ext-iconv": "*", - "symfony/console": "^5.4|^6.0", - "symfony/process": "^5.4|^6.0", - "symfony/uid": "^5.4|^6.0", - "twig/twig": "^2.13|^3.0.4" + "symfony/console": "^6.4|^7.0", + "symfony/http-kernel": "^6.4|^7.0", + "symfony/process": "^6.4|^7.0", + "symfony/uid": "^6.4|^7.0", + "twig/twig": "^3.0.4" }, "bin": [ "Resources/bin/var-dump-server" @@ -7116,7 +7034,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v6.3.1" + "source": "https://github.com/symfony/var-dumper/tree/v7.0.0" }, "funding": [ { @@ -7132,34 +7050,34 @@ "type": "tidelift" } ], - "time": "2023-06-21T12:08:28+00:00" + "time": "2023-11-27T12:39:18+00:00" }, { "name": "symfony/web-link", - "version": "v6.3.0", + "version": "v7.0.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "0989ca617d0703cdca501a245f10e194ff22315b" + "reference": "378bcc80b48c51e32bf121bee684183ff879a62f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/0989ca617d0703cdca501a245f10e194ff22315b", - "reference": "0989ca617d0703cdca501a245f10e194ff22315b", + "url": "https://api.github.com/repos/symfony/web-link/zipball/378bcc80b48c51e32bf121bee684183ff879a62f", + "reference": "378bcc80b48c51e32bf121bee684183ff879a62f", "shasum": "" }, "require": { - "php": ">=8.1", + "php": ">=8.2", "psr/link": "^1.1|^2.0" }, "conflict": { - "symfony/http-kernel": "<5.4" + "symfony/http-kernel": "<6.4" }, "provide": { "psr/link-implementation": "1.0|2.0" }, "require-dev": { - "symfony/http-kernel": "^5.4|^6.0" + "symfony/http-kernel": "^6.4|^7.0" }, "type": "library", "autoload": { @@ -7199,7 +7117,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v6.3.0" + "source": "https://github.com/symfony/web-link/tree/v7.0.0" }, "funding": [ { @@ -7215,20 +7133,20 @@ "type": "tidelift" } ], - "time": "2023-04-21T14:41:17+00:00" + "time": "2023-07-25T09:50:29+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.1", + "version": "1.2.2", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", - "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", "shasum": "" }, "require": { @@ -7257,7 +7175,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + "source": "https://github.com/theseer/tokenizer/tree/1.2.2" }, "funding": [ { @@ -7265,7 +7183,7 @@ "type": "github" } ], - "time": "2021-07-28T10:34:58+00:00" + "time": "2023-11-20T00:12:19+00:00" }, { "name": "webmozart/assert", @@ -7392,5 +7310,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.3.0" + "plugin-api-version": "2.2.0" } From 997f6f811faa75006aeff72cec26fe291bb8eaab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Sat, 9 Dec 2023 11:23:07 +0100 Subject: [PATCH 251/258] ci: upgrade deps and use PHP 8.3 (#420) * ci: upgrade deps and use PHP 8.3 * chore: updage deps * force PHPUnit version * fix ci --- .github/dependabot.yaml | 9 +++++ .github/workflows/ci.yml | 12 ++++--- .github/workflows/release.yml | 8 ++--- composer.json | 3 ++ composer.lock | 65 +++++++++++++++++------------------ 5 files changed, 54 insertions(+), 43 deletions(-) create mode 100644 .github/dependabot.yaml diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 00000000..e993f44f --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,9 @@ +version: 2 +updates: + - + package-ecosystem: github-actions + directory: / + schedule: + interval: weekly + commit-message: + prefix: ci diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index aa7caf19..14f0720e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,11 +19,13 @@ jobs: - '8.0' - '8.1' - '8.2' + - '8.3' include: - - php: '8.2' + - php: '8.3' latest: true + fail-fast: false steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup PHP uses: shivammathur/setup-php@v2 @@ -45,7 +47,7 @@ jobs: - name: Install prerequisites run: | - wget -O box.phar https://github.com/humbug/box/releases/download/4.3.8/box.phar + wget -O box.phar https://github.com/humbug/box/releases/download/4.5.1/box.phar echo "BOX_BIN=$(pwd)/box.phar" >> $GITHUB_ENV sudo chown -R $(whoami):$(whoami) . @@ -54,7 +56,7 @@ jobs: run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Update dependencies - if: "!matrix.latest" + if: '!matrix.latest' run: composer update --no-interaction --no-progress --ansi - name: Enable code coverage @@ -63,7 +65,7 @@ jobs: - name: Run PHPUnit run: vendor/bin/simple-phpunit ${{ matrix.latest && '--coverage-clover build/logs/phpunit/clover.xml' || '' }} - + - name: Run PHP CS Fixer if: matrix.latest run: php-cs-fixer fix --dry-run --format=checkstyle --ansi | cs2pr diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 949ee0b4..fb37875f 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -9,16 +9,14 @@ jobs: build: name: Create Release and Upload Release Asset runs-on: ubuntu-latest - outputs: - upload_url: ${{ steps.step_upload_url.outputs.upload_url }} steps: - name: Checkout code - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Setup PHP with extensions uses: shivammathur/setup-php@v2 with: - php-version: '8.1' + php-version: '8.3' extensions: json ini-values: memory_limit=-1 tools: composer @@ -27,7 +25,7 @@ jobs: run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Download box.phar - run: wget -O box.phar https://github.com/humbug/box/releases/download/4.2.0/box.phar + run: wget -O box.phar https://github.com/humbug/box/releases/download/4.5.1/box.phar - name: Compile project run: php ./box.phar compile diff --git a/composer.json b/composer.json index 51f3a002..6b1d4512 100644 --- a/composer.json +++ b/composer.json @@ -61,6 +61,9 @@ "phpstan/phpstan": "^1.2.0", "symfony/finder": "^5.2 || ^6.0 || ^7.0" }, + "conflict": { + "sebastian/comparator": ">=5.0" + }, "bin": [ "bin/schema" ], diff --git a/composer.lock b/composer.lock index 28aec93e..19d51278 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1d40f845abecee348779195d39a04ea8", + "content-hash": "c118a467698d922b77c84d55de44dea4", "packages": [ { "name": "cebe/php-openapi", @@ -386,16 +386,16 @@ }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.40.2", + "version": "v3.41.0", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8" + "reference": "7d8d18e19095a939b8a3b8046f57108feaad6134" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/4344562a516b76afe8f2d64b2e52214c30d64ed8", - "reference": "4344562a516b76afe8f2d64b2e52214c30d64ed8", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7d8d18e19095a939b8a3b8046f57108feaad6134", + "reference": "7d8d18e19095a939b8a3b8046f57108feaad6134", "shasum": "" }, "require": { @@ -425,8 +425,6 @@ "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpspec/prophecy": "^1.17", - "phpspec/prophecy-phpunit": "^2.0", "phpunit/phpunit": "^9.6", "symfony/phpunit-bridge": "^6.3.8 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" @@ -467,7 +465,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.40.2" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.0" }, "funding": [ { @@ -475,7 +473,7 @@ "type": "github" } ], - "time": "2023-12-03T09:21:33+00:00" + "time": "2023-12-08T22:54:33+00:00" }, { "name": "justinrainbow/json-schema", @@ -4284,29 +4282,29 @@ }, { "name": "phpspec/prophecy", - "version": "v1.17.0", + "version": "v1.18.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2" + "reference": "d4f454f7e1193933f04e6500de3e79191648ed0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/15873c65b207b07765dbc3c95d20fdf4a320cbe2", - "reference": "15873c65b207b07765dbc3c95d20fdf4a320cbe2", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d4f454f7e1193933f04e6500de3e79191648ed0c", + "reference": "d4f454f7e1193933f04e6500de3e79191648ed0c", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2 || ^2.0", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.*", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*", "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" + "sebastian/comparator": "^3.0 || ^4.0 || ^5.0", + "sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0" }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", "phpstan/phpstan": "^1.9", - "phpunit/phpunit": "^8.0 || ^9.0" + "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0" }, "type": "library", "extra": { @@ -4339,6 +4337,7 @@ "keywords": [ "Double", "Dummy", + "dev", "fake", "mock", "spy", @@ -4346,28 +4345,28 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.17.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.18.0" }, - "time": "2023-02-02T15:41:36+00:00" + "time": "2023-12-07T16:22:33+00:00" }, { "name": "phpspec/prophecy-phpunit", - "version": "v2.0.2", + "version": "v2.1.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "9f26c224a2fa335f33e6666cc078fbf388255e87" + "reference": "29f8114c2c319a4308e6b070902211e062efa392" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/9f26c224a2fa335f33e6666cc078fbf388255e87", - "reference": "9f26c224a2fa335f33e6666cc078fbf388255e87", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/29f8114c2c319a4308e6b070902211e062efa392", + "reference": "29f8114c2c319a4308e6b070902211e062efa392", "shasum": "" }, "require": { "php": "^7.3 || ^8", - "phpspec/prophecy": "^1.3", - "phpunit/phpunit": "^9.1" + "phpspec/prophecy": "^1.18", + "phpunit/phpunit": "^9.1 || ^10.1" }, "type": "library", "extra": { @@ -4398,9 +4397,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy-phpunit/issues", - "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.0.2" + "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.1.0" }, - "time": "2023-04-18T11:58:05+00:00" + "time": "2023-12-08T12:48:02+00:00" }, { "name": "phpstan/phpdoc-parser", @@ -4451,16 +4450,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.47", + "version": "1.10.48", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39" + "reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/84dbb33b520ea28b6cf5676a3941f4bae1c1ff39", - "reference": "84dbb33b520ea28b6cf5676a3941f4bae1c1ff39", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6", + "reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6", "shasum": "" }, "require": { @@ -4509,7 +4508,7 @@ "type": "tidelift" } ], - "time": "2023-12-01T15:19:17+00:00" + "time": "2023-12-08T14:34:28+00:00" }, { "name": "phpunit/php-code-coverage", @@ -7310,5 +7309,5 @@ "ext-json": "*" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.6.0" } From 1bb5502b9b7b0cb767f7fbb16f80934bb57fbbdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marin=20B=C3=AEnzari?= Date: Sat, 19 Oct 2024 12:21:19 +0300 Subject: [PATCH 252/258] chore: update deps (#426) Co-authored-by: soyuka --- box.json.dist | 2 +- composer.json | 4 +- composer.lock | 2165 ++++++++++++----- scoper.inc.php | 4 +- src/FilesGenerator.php | 2 +- src/Model/Attribute.php | 4 +- src/Model/Class_.php | 4 +- src/Model/Interface_.php | 2 +- src/Model/Property.php | 2 +- src/Model/Type/ArrayType.php | 2 +- src/Model/Use_.php | 2 +- .../PropertyGenerator/IdPropertyGenerator.php | 4 +- .../PropertyGenerator/PropertyGenerator.php | 9 +- src/PropertyGenerator/IdPropertyGenerator.php | 2 +- .../IdPropertyGeneratorInterface.php | 2 +- src/PropertyGenerator/PropertyGenerator.php | 2 +- .../PropertyGeneratorInterface.php | 2 +- src/Schema/Model/Class_.php | 2 +- .../PropertyGenerator/IdPropertyGenerator.php | 4 +- .../PropertyGenerator/PropertyGenerator.php | 4 +- src/SchemaGeneratorConfiguration.php | 2 +- src/TypesGenerator.php | 8 +- tests/ClassMutator/ClassParentMutatorTest.php | 2 +- .../ClassPropertiesAppenderTest.php | 2 +- 24 files changed, 1534 insertions(+), 704 deletions(-) diff --git a/box.json.dist b/box.json.dist index def052f6..3a14f713 100644 --- a/box.json.dist +++ b/box.json.dist @@ -15,7 +15,7 @@ "vendor/twig/twig/src/TwigTest.php" ], "directories": [ - "vendor/cebe/php-openapi/src/spec" + "vendor/devizzent/cebe-php-openapi/src/spec" ], "force-autodiscovery": true, diff --git a/composer.json b/composer.json index 6b1d4512..1cd1e87b 100644 --- a/composer.json +++ b/composer.json @@ -45,8 +45,8 @@ "symfony/filesystem": "^5.2 || ^6.0 || ^7.0", "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0", - "nikic/php-parser": "^4.13", - "cebe/php-openapi": "^1.6", + "nikic/php-parser": "^4.13 || ^5.0", + "devizzent/cebe-php-openapi": "^1.0.3", "symfony/string": "^5.2 || ^6.0 || ^7.0" }, "require-dev": { diff --git a/composer.lock b/composer.lock index 19d51278..f11029f4 100644 --- a/composer.lock +++ b/composer.lock @@ -4,52 +4,34 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "c118a467698d922b77c84d55de44dea4", + "content-hash": "361ed8a36c253f2e709b8aa97ef133b7", "packages": [ { - "name": "cebe/php-openapi", - "version": "1.7.0", + "name": "clue/ndjson-react", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/cebe/php-openapi.git", - "reference": "020d72b8e3a9a60bc229953e93eda25c49f46f45" + "url": "https://github.com/clue/reactphp-ndjson.git", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/cebe/php-openapi/zipball/020d72b8e3a9a60bc229953e93eda25c49f46f45", - "reference": "020d72b8e3a9a60bc229953e93eda25c49f46f45", + "url": "https://api.github.com/repos/clue/reactphp-ndjson/zipball/392dc165fce93b5bb5c637b67e59619223c931b0", + "reference": "392dc165fce93b5bb5c637b67e59619223c931b0", "shasum": "" }, "require": { - "ext-json": "*", - "justinrainbow/json-schema": "^5.2", - "php": ">=7.1.0", - "symfony/yaml": "^3.4 || ^4 || ^5 || ^6" - }, - "conflict": { - "symfony/yaml": "3.4.0 - 3.4.4 || 4.0.0 - 4.4.17 || 5.0.0 - 5.1.9 || 5.2.0" + "php": ">=5.3", + "react/stream": "^1.2" }, "require-dev": { - "apis-guru/openapi-directory": "1.0.0", - "cebe/indent": "*", - "mermade/openapi3-examples": "1.0.0", - "nexmo/api-specification": "1.0.0", - "oai/openapi-specification": "3.0.3", - "phpstan/phpstan": "^0.12.0", - "phpunit/phpunit": "^6.5 || ^7.5 || ^8.5 || ^9.4" + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35", + "react/event-loop": "^1.2" }, - "bin": [ - "bin/php-openapi" - ], "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.6.x-dev" - } - }, "autoload": { "psr-4": { - "cebe\\openapi\\": "src/" + "Clue\\React\\NDJson\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -58,35 +40,48 @@ ], "authors": [ { - "name": "Carsten Brandt", - "email": "mail@cebe.cc", - "homepage": "https://cebe.cc/", - "role": "Creator" + "name": "Christian Lück", + "email": "christian@clue.engineering" } ], - "description": "Read and write OpenAPI yaml/json files and make the content accessable in PHP objects.", - "homepage": "https://github.com/cebe/php-openapi#readme", + "description": "Streaming newline-delimited JSON (NDJSON) parser and encoder for ReactPHP.", + "homepage": "https://github.com/clue/reactphp-ndjson", "keywords": [ - "openapi" + "NDJSON", + "json", + "jsonlines", + "newline", + "reactphp", + "streaming" ], "support": { - "issues": "https://github.com/cebe/php-openapi/issues", - "source": "https://github.com/cebe/php-openapi" + "issues": "https://github.com/clue/reactphp-ndjson/issues", + "source": "https://github.com/clue/reactphp-ndjson/tree/v1.3.0" }, - "time": "2022-04-20T14:46:44+00:00" + "funding": [ + { + "url": "https://clue.engineering/support", + "type": "custom" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-12-23T10:58:28+00:00" }, { "name": "composer/pcre", - "version": "3.1.1", + "version": "3.1.4", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9" + "reference": "04229f163664973f68f38f6f73d917799168ef24" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/00104306927c7a0919b4ced2aaa6782c1e61a3c9", - "reference": "00104306927c7a0919b4ced2aaa6782c1e61a3c9", + "url": "https://api.github.com/repos/composer/pcre/zipball/04229f163664973f68f38f6f73d917799168ef24", + "reference": "04229f163664973f68f38f6f73d917799168ef24", "shasum": "" }, "require": { @@ -128,7 +123,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.1" + "source": "https://github.com/composer/pcre/tree/3.1.4" }, "funding": [ { @@ -144,7 +139,7 @@ "type": "tidelift" } ], - "time": "2023-10-11T07:11:09+00:00" + "time": "2024-05-27T13:40:54+00:00" }, { "name": "composer/semver", @@ -229,16 +224,16 @@ }, { "name": "composer/xdebug-handler", - "version": "3.0.3", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/composer/xdebug-handler.git", - "reference": "ced299686f41dce890debac69273b47ffe98a40c" + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/ced299686f41dce890debac69273b47ffe98a40c", - "reference": "ced299686f41dce890debac69273b47ffe98a40c", + "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/6c1925561632e83d60a44492e0b344cf48ab85ef", + "reference": "6c1925561632e83d60a44492e0b344cf48ab85ef", "shasum": "" }, "require": { @@ -249,7 +244,7 @@ "require-dev": { "phpstan/phpstan": "^1.0", "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^6.0" + "phpunit/phpunit": "^8.5 || ^9.6 || ^10.5" }, "type": "library", "autoload": { @@ -273,9 +268,9 @@ "performance" ], "support": { - "irc": "irc://irc.freenode.org/composer", + "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/xdebug-handler/issues", - "source": "https://github.com/composer/xdebug-handler/tree/3.0.3" + "source": "https://github.com/composer/xdebug-handler/tree/3.0.5" }, "funding": [ { @@ -291,20 +286,93 @@ "type": "tidelift" } ], - "time": "2022-02-25T21:32:43+00:00" + "time": "2024-05-06T16:37:16+00:00" + }, + { + "name": "devizzent/cebe-php-openapi", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/DEVizzent/cebe-php-openapi.git", + "reference": "b5a5de835dcb1642094fe76568451bd73b8fc0ab" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DEVizzent/cebe-php-openapi/zipball/b5a5de835dcb1642094fe76568451bd73b8fc0ab", + "reference": "b5a5de835dcb1642094fe76568451bd73b8fc0ab", + "shasum": "" + }, + "require": { + "ext-json": "*", + "justinrainbow/json-schema": "^5.2", + "php": ">=7.1.0", + "symfony/yaml": "^3.4 || ^4 || ^5 || ^6 || ^7" + }, + "conflict": { + "symfony/yaml": "3.4.0 - 3.4.4 || 4.0.0 - 4.4.17 || 5.0.0 - 5.1.9 || 5.2.0" + }, + "require-dev": { + "apis-guru/openapi-directory": "1.0.0", + "cebe/indent": "*", + "mermade/openapi3-examples": "1.0.0", + "oai/openapi-specification-3.0": "3.0.3", + "oai/openapi-specification-3.1": "3.1.0", + "phpstan/phpstan": "^0.12.0", + "phpunit/phpunit": "^6.5 || ^7.5 || ^8.5 || ^9.4" + }, + "bin": [ + "bin/php-openapi" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.6.x-dev" + } + }, + "autoload": { + "psr-4": { + "cebe\\openapi\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Carsten Brandt", + "email": "mail@cebe.cc", + "homepage": "https://cebe.cc/", + "role": "Creator" + }, + { + "name": "Vicent Valls", + "email": "vizzent@gmail.com" + } + ], + "description": "Read and write OpenAPI yaml/json files and make the content accessable in PHP objects.", + "homepage": "https://github.com/DEVizzent/cebe-php-openapi#readme", + "keywords": [ + "openapi" + ], + "support": { + "issues": "https://github.com/DEVizzent/cebe-php-openapi/issues", + "source": "https://github.com/DEVizzent/cebe-php-openapi" + }, + "time": "2024-01-10T11:41:55+00:00" }, { "name": "doctrine/inflector", - "version": "2.0.8", + "version": "2.0.10", "source": { "type": "git", "url": "https://github.com/doctrine/inflector.git", - "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff" + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/inflector/zipball/f9301a5b2fb1216b2b08f02ba04dc45423db6bff", - "reference": "f9301a5b2fb1216b2b08f02ba04dc45423db6bff", + "url": "https://api.github.com/repos/doctrine/inflector/zipball/5817d0659c5b50c9b950feb9af7b9668e2c436bc", + "reference": "5817d0659c5b50c9b950feb9af7b9668e2c436bc", "shasum": "" }, "require": { @@ -366,7 +434,7 @@ ], "support": { "issues": "https://github.com/doctrine/inflector/issues", - "source": "https://github.com/doctrine/inflector/tree/2.0.8" + "source": "https://github.com/doctrine/inflector/tree/2.0.10" }, "funding": [ { @@ -382,29 +450,145 @@ "type": "tidelift" } ], - "time": "2023-06-16T13:40:37+00:00" + "time": "2024-02-18T20:23:39+00:00" + }, + { + "name": "evenement/evenement", + "version": "v3.0.2", + "source": { + "type": "git", + "url": "https://github.com/igorw/evenement.git", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/igorw/evenement/zipball/0a16b0d71ab13284339abb99d9d2bd813640efbc", + "reference": "0a16b0d71ab13284339abb99d9d2bd813640efbc", + "shasum": "" + }, + "require": { + "php": ">=7.0" + }, + "require-dev": { + "phpunit/phpunit": "^9 || ^6" + }, + "type": "library", + "autoload": { + "psr-4": { + "Evenement\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Igor Wiedler", + "email": "igor@wiedler.ch" + } + ], + "description": "Événement is a very simple event dispatching library for PHP", + "keywords": [ + "event-dispatcher", + "event-emitter" + ], + "support": { + "issues": "https://github.com/igorw/evenement/issues", + "source": "https://github.com/igorw/evenement/tree/v3.0.2" + }, + "time": "2023-08-08T05:53:35+00:00" + }, + { + "name": "fidry/cpu-core-counter", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theofidry/cpu-core-counter.git", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "fidry/makefile": "^0.2.0", + "fidry/php-cs-fixer-config": "^1.1.2", + "phpstan/extension-installer": "^1.2.0", + "phpstan/phpstan": "^1.9.2", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.2.2", + "phpstan/phpstan-strict-rules": "^1.4.4", + "phpunit/phpunit": "^8.5.31 || ^9.5.26", + "webmozarts/strict-phpunit": "^7.5" + }, + "type": "library", + "autoload": { + "psr-4": { + "Fidry\\CpuCoreCounter\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Théo FIDRY", + "email": "theo.fidry@gmail.com" + } + ], + "description": "Tiny utility to get the number of CPU cores.", + "keywords": [ + "CPU", + "core" + ], + "support": { + "issues": "https://github.com/theofidry/cpu-core-counter/issues", + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + }, + "funding": [ + { + "url": "https://github.com/theofidry", + "type": "github" + } + ], + "time": "2024-02-07T09:43:46+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.41.0", + "version": "v3.58.1", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "7d8d18e19095a939b8a3b8046f57108feaad6134" + "reference": "04e9424025677a86914b9a4944dbbf4060bb0aff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/7d8d18e19095a939b8a3b8046f57108feaad6134", - "reference": "7d8d18e19095a939b8a3b8046f57108feaad6134", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/04e9424025677a86914b9a4944dbbf4060bb0aff", + "reference": "04e9424025677a86914b9a4944dbbf4060bb0aff", "shasum": "" }, "require": { + "clue/ndjson-react": "^1.0", "composer/semver": "^3.4", "composer/xdebug-handler": "^3.0.3", + "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", + "fidry/cpu-core-counter": "^1.0", "php": "^7.4 || ^8.0", - "sebastian/diff": "^4.0 || ^5.0", + "react/child-process": "^0.6.5", + "react/event-loop": "^1.0", + "react/promise": "^2.0 || ^3.0", + "react/socket": "^1.0", + "react/stream": "^1.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0", "symfony/console": "^5.4 || ^6.0 || ^7.0", "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", @@ -418,6 +602,7 @@ }, "require-dev": { "facile-it/paraunit": "^1.3 || ^2.0", + "infection/infection": "^0.27.11", "justinrainbow/json-schema": "^5.2", "keradus/cli-executor": "^2.1", "mikey179/vfsstream": "^1.6.11", @@ -425,8 +610,8 @@ "php-cs-fixer/accessible-object": "^1.1", "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpunit/phpunit": "^9.6", - "symfony/phpunit-bridge": "^6.3.8 || ^7.0", + "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", + "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", "symfony/yaml": "^5.4 || ^6.0 || ^7.0" }, "suggest": { @@ -465,7 +650,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.41.0" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.58.1" }, "funding": [ { @@ -473,19 +658,19 @@ "type": "github" } ], - "time": "2023-12-08T22:54:33+00:00" + "time": "2024-05-29T16:39:07+00:00" }, { "name": "justinrainbow/json-schema", "version": "v5.2.13", "source": { "type": "git", - "url": "https://github.com/justinrainbow/json-schema.git", + "url": "https://github.com/jsonrainbow/json-schema.git", "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", "shasum": "" }, @@ -540,8 +725,8 @@ "schema" ], "support": { - "issues": "https://github.com/justinrainbow/json-schema/issues", - "source": "https://github.com/justinrainbow/json-schema/tree/v5.2.13" + "issues": "https://github.com/jsonrainbow/json-schema/issues", + "source": "https://github.com/jsonrainbow/json-schema/tree/v5.2.13" }, "time": "2023-09-26T02:20:38+00:00" }, @@ -636,16 +821,16 @@ }, { "name": "nette/php-generator", - "version": "v4.1.2", + "version": "v4.1.5", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "abc0e79b2d02d4b8aba5933765b90df3f610c143" + "reference": "690b00d81d42d5633e4457c43ef9754573b6f9d6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/abc0e79b2d02d4b8aba5933765b90df3f610c143", - "reference": "abc0e79b2d02d4b8aba5933765b90df3f610c143", + "url": "https://api.github.com/repos/nette/php-generator/zipball/690b00d81d42d5633e4457c43ef9754573b6f9d6", + "reference": "690b00d81d42d5633e4457c43ef9754573b6f9d6", "shasum": "" }, "require": { @@ -655,7 +840,7 @@ "require-dev": { "jetbrains/phpstorm-attributes": "dev-master", "nette/tester": "^2.4", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "phpstan/phpstan": "^1.0", "tracy/tracy": "^2.8" }, @@ -699,22 +884,22 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.1.2" + "source": "https://github.com/nette/php-generator/tree/v4.1.5" }, - "time": "2023-10-29T22:57:32+00:00" + "time": "2024-05-12T17:31:02+00:00" }, { "name": "nette/utils", - "version": "v4.0.3", + "version": "v4.0.4", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015" + "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/a9d127dd6a203ce6d255b2e2db49759f7506e015", - "reference": "a9d127dd6a203ce6d255b2e2db49759f7506e015", + "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218", "shasum": "" }, "require": { @@ -785,31 +970,33 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.3" + "source": "https://github.com/nette/utils/tree/v4.0.4" }, - "time": "2023-10-29T21:02:13+00:00" + "time": "2024-01-17T16:50:36+00:00" }, { "name": "nikic/php-parser", - "version": "v4.17.1", + "version": "v5.0.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d" + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", - "reference": "a6303e50c90c355c7eeee2c4a8b27fe8dc8fef1d", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", "shasum": "" }, "require": { + "ext-ctype": "*", + "ext-json": "*", "ext-tokenizer": "*", - "php": ">=7.0" + "php": ">=7.4" }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, "bin": [ "bin/php-parse" @@ -817,7 +1004,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.9-dev" + "dev-master": "5.0-dev" } }, "autoload": { @@ -841,9 +1028,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.17.1" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" }, - "time": "2023-08-13T19:53:39+00:00" + "time": "2024-03-05T20:51:40+00:00" }, { "name": "psr/container", @@ -899,31 +1086,485 @@ "time": "2021-11-05T16:47:00+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "psr/event-dispatcher", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/event-dispatcher.git", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", + "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\EventDispatcher\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Standard interfaces for event handling.", + "keywords": [ + "events", + "psr", + "psr-14" + ], + "support": { + "issues": "https://github.com/php-fig/event-dispatcher/issues", + "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + }, + "time": "2019-01-08T18:20:26+00:00" + }, + { + "name": "psr/http-message", + "version": "2.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/2.0" + }, + "time": "2023-04-04T09:54:51+00:00" + }, + { + "name": "psr/log", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/log.git", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", + "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "shasum": "" + }, + "require": { + "php": ">=8.0.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Log\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for logging libraries", + "homepage": "https://github.com/php-fig/log", + "keywords": [ + "log", + "psr", + "psr-3" + ], + "support": { + "source": "https://github.com/php-fig/log/tree/3.0.0" + }, + "time": "2021-07-14T16:46:02+00:00" + }, + { + "name": "react/cache", + "version": "v1.2.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/cache.git", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/cache/zipball/d47c472b64aa5608225f47965a484b75c7817d5b", + "reference": "d47c472b64aa5608225f47965a484b75c7817d5b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/promise": "^3.0 || ^2.0 || ^1.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Cache\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async, Promise-based cache interface for ReactPHP", + "keywords": [ + "cache", + "caching", + "promise", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/cache/issues", + "source": "https://github.com/reactphp/cache/tree/v1.2.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2022-11-30T15:59:55+00:00" + }, + { + "name": "react/child-process", + "version": "v0.6.5", + "source": { + "type": "git", + "url": "https://github.com/reactphp/child-process.git", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "shasum": "" + }, + "require": { + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/event-loop": "^1.2", + "react/stream": "^1.2" + }, + "require-dev": { + "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", + "react/socket": "^1.8", + "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\ChildProcess\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Event-driven library for executing child processes with ReactPHP.", + "keywords": [ + "event-driven", + "process", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/child-process/issues", + "source": "https://github.com/reactphp/child-process/tree/v0.6.5" + }, + "funding": [ + { + "url": "https://github.com/WyriHaximus", + "type": "github" + }, + { + "url": "https://github.com/clue", + "type": "github" + } + ], + "time": "2022-09-16T13:41:56+00:00" + }, + { + "name": "react/dns", + "version": "v1.12.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/dns.git", + "reference": "c134600642fa615b46b41237ef243daa65bb64ec" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/dns/zipball/c134600642fa615b46b41237ef243daa65bb64ec", + "reference": "c134600642fa615b46b41237ef243daa65bb64ec", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "react/cache": "^1.0 || ^0.6 || ^0.5", + "react/event-loop": "^1.2", + "react/promise": "^3.0 || ^2.7 || ^1.2.1" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4 || ^3 || ^2", + "react/promise-timer": "^1.9" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\Dns\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "Async DNS resolver for ReactPHP", + "keywords": [ + "async", + "dns", + "dns-resolver", + "reactphp" + ], + "support": { + "issues": "https://github.com/reactphp/dns/issues", + "source": "https://github.com/reactphp/dns/tree/v1.12.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-29T12:41:06+00:00" + }, + { + "name": "react/event-loop", + "version": "v1.5.0", + "source": { + "type": "git", + "url": "https://github.com/reactphp/event-loop.git", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/reactphp/event-loop/zipball/bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "reference": "bbe0bd8c51ffc05ee43f1729087ed3bdf7d53354", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" + }, + "suggest": { + "ext-pcntl": "For signal handling support when using the StreamSelectLoop" + }, + "type": "library", + "autoload": { + "psr-4": { + "React\\EventLoop\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" + } + ], + "description": "ReactPHP's core reactor event loop that libraries can use for evented I/O.", + "keywords": [ + "asynchronous", + "event-loop" + ], + "support": { + "issues": "https://github.com/reactphp/event-loop/issues", + "source": "https://github.com/reactphp/event-loop/tree/v1.5.0" + }, + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-11-13T13:48:05+00:00" + }, + { + "name": "react/promise", + "version": "v3.2.0", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/reactphp/promise.git", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/reactphp/promise/zipball/8a164643313c71354582dc850b42b33fa12a4b63", + "reference": "8a164643313c71354582dc850b42b33fa12a4b63", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.1.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "phpstan/phpstan": "1.10.39 || 1.4.10", + "phpunit/phpunit": "^9.6 || ^7.5" }, + "type": "library", "autoload": { + "files": [ + "src/functions_include.php" + ], "psr-4": { - "Psr\\EventDispatcher\\": "src/" + "React\\Promise\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -932,48 +1573,75 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Standard interfaces for event handling.", + "description": "A lightweight implementation of CommonJS Promises/A for PHP", "keywords": [ - "events", - "psr", - "psr-14" + "promise", + "promises" ], "support": { - "issues": "https://github.com/php-fig/event-dispatcher/issues", - "source": "https://github.com/php-fig/event-dispatcher/tree/1.0.0" + "issues": "https://github.com/reactphp/promise/issues", + "source": "https://github.com/reactphp/promise/tree/v3.2.0" }, - "time": "2019-01-08T18:20:26+00:00" + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2024-05-24T10:39:05+00:00" }, { - "name": "psr/http-message", - "version": "2.0", + "name": "react/socket", + "version": "v1.15.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71" + "url": "https://github.com/reactphp/socket.git", + "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/402d35bcb92c70c026d1a6a9883f06b2ead23d71", - "reference": "402d35bcb92c70c026d1a6a9883f06b2ead23d71", + "url": "https://api.github.com/repos/reactphp/socket/zipball/216d3aec0b87f04a40ca04f481e6af01bdd1d038", + "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.0", + "react/dns": "^1.11", + "react/event-loop": "^1.2", + "react/promise": "^3 || ^2.6 || ^1.2.1", + "react/stream": "^1.2" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } + "require-dev": { + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/async": "^4 || ^3 || ^2", + "react/promise-stream": "^1.4", + "react/promise-timer": "^1.10" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Http\\Message\\": "src/" + "React\\Socket\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -982,51 +1650,73 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", + "description": "Async, streaming plaintext TCP/IP and secure TLS socket server and client connections for ReactPHP", "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" + "Connection", + "Socket", + "async", + "reactphp", + "stream" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/2.0" + "issues": "https://github.com/reactphp/socket/issues", + "source": "https://github.com/reactphp/socket/tree/v1.15.0" }, - "time": "2023-04-04T09:54:51+00:00" + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-12-15T11:02:10+00:00" }, { - "name": "psr/log", - "version": "3.0.0", + "name": "react/stream", + "version": "v1.3.0", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "url": "https://github.com/reactphp/stream.git", + "reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/reactphp/stream/zipball/6fbc9672905c7d5a885f2da2fc696f65840f4a66", + "reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66", "shasum": "" }, "require": { - "php": ">=8.0.0" + "evenement/evenement": "^3.0 || ^2.0 || ^1.0", + "php": ">=5.3.8", + "react/event-loop": "^1.2" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } + "require-dev": { + "clue/stream-filter": "~1.2", + "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Log\\": "src" + "React\\Stream\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1035,34 +1725,61 @@ ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Christian Lück", + "email": "christian@clue.engineering", + "homepage": "https://clue.engineering/" + }, + { + "name": "Cees-Jan Kiewiet", + "email": "reactphp@ceesjankiewiet.nl", + "homepage": "https://wyrihaximus.net/" + }, + { + "name": "Jan Sorgalla", + "email": "jsorgalla@gmail.com", + "homepage": "https://sorgalla.com/" + }, + { + "name": "Chris Boden", + "email": "cboden@gmail.com", + "homepage": "https://cboden.dev/" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "Event-driven readable and writable streams for non-blocking I/O in ReactPHP", "keywords": [ - "log", - "psr", - "psr-3" + "event-driven", + "io", + "non-blocking", + "pipe", + "reactphp", + "readable", + "stream", + "writable" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "issues": "https://github.com/reactphp/stream/issues", + "source": "https://github.com/reactphp/stream/tree/v1.3.0" }, - "time": "2021-07-14T16:46:02+00:00" + "funding": [ + { + "url": "https://opencollective.com/reactphp", + "type": "open_collective" + } + ], + "time": "2023-06-16T10:52:11+00:00" }, { "name": "sebastian/diff", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131" + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/74be17022044ebaaecfdf0c5cd504fc9cd5a7131", - "reference": "74be17022044ebaaecfdf0c5cd504fc9cd5a7131", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", "shasum": "" }, "require": { @@ -1107,7 +1824,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" }, "funding": [ { @@ -1115,20 +1832,20 @@ "type": "github" } ], - "time": "2023-05-07T05:35:17+00:00" + "time": "2024-03-02T06:30:58+00:00" }, { "name": "sweetrdf/easyrdf", - "version": "1.11.0", + "version": "1.14.1", "source": { "type": "git", "url": "https://github.com/sweetrdf/easyrdf.git", - "reference": "92554d04aaec5635cbd82caf428434f824298a1b" + "reference": "b5eeeb31795fedd773acd867a461aeba75f8a347" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/92554d04aaec5635cbd82caf428434f824298a1b", - "reference": "92554d04aaec5635cbd82caf428434f824298a1b", + "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/b5eeeb31795fedd773acd867a461aeba75f8a347", + "reference": "b5eeeb31795fedd773acd867a461aeba75f8a347", "shasum": "" }, "require": { @@ -1138,7 +1855,7 @@ "ext-xmlreader": "*", "lib-libxml": "*", "php": "^8.0", - "sweetrdf/rdf-helpers": "^1.0" + "sweetrdf/rdf-helpers": "^2.0" }, "replace": { "easyrdf/easyrdf": "1.1.*" @@ -1194,34 +1911,32 @@ ], "support": { "issues": "https://github.com/sweetrdf/easyrdf/issues", - "source": "https://github.com/sweetrdf/easyrdf/tree/1.11.0" + "source": "https://github.com/sweetrdf/easyrdf/tree/1.14.1" }, - "time": "2023-09-14T07:31:36+00:00" + "time": "2024-05-27T10:24:12+00:00" }, { "name": "sweetrdf/rdf-helpers", - "version": "1.2.0", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sweetrdf/rdfHelpers.git", - "reference": "29db501d91ffe0056b8c3db1fe42d7cd13f9193f" + "reference": "3c2cb15e86053fcf5c52235da75c2b141218e3f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/rdfHelpers/zipball/29db501d91ffe0056b8c3db1fe42d7cd13f9193f", - "reference": "29db501d91ffe0056b8c3db1fe42d7cd13f9193f", + "url": "https://api.github.com/repos/sweetrdf/rdfHelpers/zipball/3c2cb15e86053fcf5c52235da75c2b141218e3f8", + "reference": "3c2cb15e86053fcf5c52235da75c2b141218e3f8", "shasum": "" }, "require": { "php": ">=8.0", - "sweetrdf/rdf-interface": "^1 | ^2.0.0-RC3", + "sweetrdf/rdf-interface": "^2", "zozlak/rdf-constants": "^1.1" }, "require-dev": { - "phpstan/phpstan": "*", - "phpunit/php-code-coverage": "^9.2", - "phpunit/phpunit": "^9.5", - "squizlabs/php_codesniffer": "*" + "phpstan/phpstan": "^1", + "phpunit/phpunit": "^10" }, "type": "library", "autoload": { @@ -1244,22 +1959,22 @@ "homepage": "https://github.com/sweetrdf/rdfHelpers", "support": { "issues": "https://github.com/sweetrdf/rdfHelpers/issues", - "source": "https://github.com/sweetrdf/rdfHelpers/tree/1.2.0" + "source": "https://github.com/sweetrdf/rdfHelpers/tree/2.0.0" }, - "time": "2023-08-31T12:13:56+00:00" + "time": "2024-02-13T12:03:47+00:00" }, { "name": "sweetrdf/rdf-interface", - "version": "1.0.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/sweetrdf/rdfInterface.git", - "reference": "b0c930b7bd7a80e63f77510d0dcb261aead4f0a3" + "reference": "9a8c01779a214fa37f3420aa1d7228d51c170a19" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/b0c930b7bd7a80e63f77510d0dcb261aead4f0a3", - "reference": "b0c930b7bd7a80e63f77510d0dcb261aead4f0a3", + "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/9a8c01779a214fa37f3420aa1d7228d51c170a19", + "reference": "9a8c01779a214fa37f3420aa1d7228d51c170a19", "shasum": "" }, "require": { @@ -1268,8 +1983,7 @@ "zozlak/rdf-constants": "*" }, "require-dev": { - "phpstan/phpstan": "*", - "squizlabs/php_codesniffer": "*" + "phpstan/phpstan": "*" }, "type": "library", "autoload": { @@ -1292,28 +2006,28 @@ "homepage": "https://github.com/sweetrdf/rdfInterface", "support": { "issues": "https://github.com/sweetrdf/rdfInterface/issues", - "source": "https://github.com/sweetrdf/rdfInterface/tree/1.0.1" + "source": "https://github.com/sweetrdf/rdfInterface/tree/2.0.0" }, - "time": "2023-07-21T08:26:06+00:00" + "time": "2024-02-09T12:03:33+00:00" }, { "name": "symfony/config", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a" + "reference": "c4a60be1c7ec93aa8b7f19e07b6427143a502ef4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/8789646600f4e7e451dde9e1dc81cfa429f3857a", - "reference": "8789646600f4e7e451dde9e1dc81cfa429f3857a", + "url": "https://api.github.com/repos/symfony/config/zipball/c4a60be1c7ec93aa8b7f19e07b6427143a502ef4", + "reference": "c4a60be1c7ec93aa8b7f19e07b6427143a502ef4", "shasum": "" }, "require": { "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", - "symfony/filesystem": "^6.4|^7.0", + "symfony/filesystem": "^7.1", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -1353,7 +2067,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v7.0.0" + "source": "https://github.com/symfony/config/tree/v7.1.0" }, "funding": [ { @@ -1369,20 +2083,20 @@ "type": "tidelift" } ], - "time": "2023-11-09T08:30:23+00:00" + "time": "2024-05-28T06:54:05+00:00" }, { "name": "symfony/console", - "version": "v7.0.1", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5" + "reference": "5bcde9e0b2ea9bd9772bca17618365ea921c5707" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/cdce5c684b2f920bb1343deecdfba356ffad83d5", - "reference": "cdce5c684b2f920bb1343deecdfba356ffad83d5", + "url": "https://api.github.com/repos/symfony/console/zipball/5bcde9e0b2ea9bd9772bca17618365ea921c5707", + "reference": "5bcde9e0b2ea9bd9772bca17618365ea921c5707", "shasum": "" }, "require": { @@ -1446,7 +2160,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.0.1" + "source": "https://github.com/symfony/console/tree/v7.1.0" }, "funding": [ { @@ -1462,20 +2176,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T15:10:06+00:00" + "time": "2024-05-17T10:55:18+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf" + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/7c3aff79d10325257a001fcf92d991f24fc967cf", - "reference": "7c3aff79d10325257a001fcf92d991f24fc967cf", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", "shasum": "" }, "require": { @@ -1484,7 +2198,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1513,7 +2227,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" }, "funding": [ { @@ -1529,20 +2243,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e" + "reference": "522d2772d6c7bab843b0c52466dc7844622bacc2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/c459b40ffe67c49af6fd392aac374c9edf8a027e", - "reference": "c459b40ffe67c49af6fd392aac374c9edf8a027e", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/522d2772d6c7bab843b0c52466dc7844622bacc2", + "reference": "522d2772d6c7bab843b0c52466dc7844622bacc2", "shasum": "" }, "require": { @@ -1593,7 +2307,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.0.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.0" }, "funding": [ { @@ -1609,20 +2323,20 @@ "type": "tidelift" } ], - "time": "2023-07-27T16:29:09+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df" + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/a76aed96a42d2b521153fb382d418e30d18b59df", - "reference": "a76aed96a42d2b521153fb382d418e30d18b59df", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", + "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", "shasum": "" }, "require": { @@ -1632,7 +2346,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -1669,7 +2383,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" }, "funding": [ { @@ -1685,20 +2399,20 @@ "type": "tidelift" } ], - "time": "2023-05-23T14:45:45+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/filesystem", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7" + "reference": "8ecdde25881598f86cdd7cfe8b25302b66a402e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/7da8ea2362a283771478c5f7729cfcb43a76b8b7", - "reference": "7da8ea2362a283771478c5f7729cfcb43a76b8b7", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/8ecdde25881598f86cdd7cfe8b25302b66a402e9", + "reference": "8ecdde25881598f86cdd7cfe8b25302b66a402e9", "shasum": "" }, "require": { @@ -1706,6 +2420,9 @@ "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.8" }, + "require-dev": { + "symfony/process": "^6.4|^7.0" + }, "type": "library", "autoload": { "psr-4": { @@ -1732,7 +2449,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.0.0" + "source": "https://github.com/symfony/filesystem/tree/v7.1.0" }, "funding": [ { @@ -1748,20 +2465,20 @@ "type": "tidelift" } ], - "time": "2023-07-27T06:33:22+00:00" + "time": "2024-05-17T10:55:18+00:00" }, { "name": "symfony/finder", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56" + "reference": "fb6c2d65c3dbf7ad83201a4168d4510c8dddaac7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", - "reference": "6e5688d69f7cfc4ed4a511e96007e06c2d34ce56", + "url": "https://api.github.com/repos/symfony/finder/zipball/fb6c2d65c3dbf7ad83201a4168d4510c8dddaac7", + "reference": "fb6c2d65c3dbf7ad83201a4168d4510c8dddaac7", "shasum": "" }, "require": { @@ -1796,7 +2513,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v7.0.0" + "source": "https://github.com/symfony/finder/tree/v7.1.0" }, "funding": [ { @@ -1812,20 +2529,20 @@ "type": "tidelift" } ], - "time": "2023-10-31T17:59:56+00:00" + "time": "2024-04-28T18:29:00+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "700ff4096e346f54cb628ea650767c8130f1001f" + "reference": "9564f64c16f99e29f252eafc642965e8fcb755ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/700ff4096e346f54cb628ea650767c8130f1001f", - "reference": "700ff4096e346f54cb628ea650767c8130f1001f", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/9564f64c16f99e29f252eafc642965e8fcb755ce", + "reference": "9564f64c16f99e29f252eafc642965e8fcb755ce", "shasum": "" }, "require": { @@ -1863,7 +2580,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.0.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.1.0" }, "funding": [ { @@ -1879,20 +2596,20 @@ "type": "tidelift" } ], - "time": "2023-08-08T10:20:21+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb" + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", - "reference": "ea208ce43cbb04af6867b4fdddb1bdbf84cc28cb", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", + "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", "shasum": "" }, "require": { @@ -1906,9 +2623,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -1945,7 +2659,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" }, "funding": [ { @@ -1961,20 +2675,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "875e90aeea2777b6f135677f618529449334a612" + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/875e90aeea2777b6f135677f618529449334a612", - "reference": "875e90aeea2777b6f135677f618529449334a612", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", "shasum": "" }, "require": { @@ -1985,9 +2699,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -2026,7 +2737,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" }, "funding": [ { @@ -2042,20 +2753,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92" + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", - "reference": "8c4ad05dd0120b6a53c1ca374dca2ad0a1c4ed92", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", + "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", "shasum": "" }, "require": { @@ -2066,9 +2777,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -2110,7 +2818,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" }, "funding": [ { @@ -2126,20 +2834,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "42292d99c55abe617799667f454222c54c60e229" + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/42292d99c55abe617799667f454222c54c60e229", - "reference": "42292d99c55abe617799667f454222c54c60e229", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", "shasum": "" }, "require": { @@ -2153,9 +2861,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -2193,7 +2898,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" }, "funding": [ { @@ -2209,20 +2914,20 @@ "type": "tidelift" } ], - "time": "2023-07-28T09:04:16+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5" + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/6caa57379c4aec19c0a12a38b59b26487dcfe4b5", - "reference": "6caa57379c4aec19c0a12a38b59b26487dcfe4b5", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", "shasum": "" }, "require": { @@ -2230,9 +2935,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -2276,7 +2978,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" }, "funding": [ { @@ -2292,20 +2994,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b" + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/7581cd600fa9fd681b797d00b02f068e2f13263b", - "reference": "7581cd600fa9fd681b797d00b02f068e2f13263b", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", + "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", "shasum": "" }, "require": { @@ -2313,9 +3015,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -2355,7 +3054,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" }, "funding": [ { @@ -2371,20 +3070,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/process", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d" + "reference": "56c8a1ea51eb70003fee94a78c7d6d0f44832ce7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/13bdb1670c7f510494e04fcb2bfa29af63db9c0d", - "reference": "13bdb1670c7f510494e04fcb2bfa29af63db9c0d", + "url": "https://api.github.com/repos/symfony/process/zipball/56c8a1ea51eb70003fee94a78c7d6d0f44832ce7", + "reference": "56c8a1ea51eb70003fee94a78c7d6d0f44832ce7", "shasum": "" }, "require": { @@ -2416,7 +3115,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v7.0.0" + "source": "https://github.com/symfony/process/tree/v7.1.0" }, "funding": [ { @@ -2432,25 +3131,26 @@ "type": "tidelift" } ], - "time": "2023-11-20T16:43:42+00:00" + "time": "2024-05-17T10:55:18+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838" + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b3313c2dbffaf71c8de2934e2ea56ed2291a3838", - "reference": "b3313c2dbffaf71c8de2934e2ea56ed2291a3838", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", "shasum": "" }, "require": { "php": ">=8.1", - "psr/container": "^2.0" + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, "conflict": { "ext-psr": "<1.1|>=2" @@ -2458,7 +3158,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -2498,7 +3198,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" }, "funding": [ { @@ -2514,20 +3214,20 @@ "type": "tidelift" } ], - "time": "2023-07-30T20:28:31+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a" + "reference": "13c750a45ac43c45f45d944d22499768aa1b72d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", - "reference": "7bbfa3dd564a0ce12eb4acaaa46823c740f9cb7a", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/13c750a45ac43c45f45d944d22499768aa1b72d8", + "reference": "13c750a45ac43c45f45d944d22499768aa1b72d8", "shasum": "" }, "require": { @@ -2560,7 +3260,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.0.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.1.0" }, "funding": [ { @@ -2576,20 +3276,20 @@ "type": "tidelift" } ], - "time": "2023-07-05T13:06:06+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/string", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620" + "reference": "6f41b185e742737917e6f2e3eca37767fba5f17a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/92bd2bfbba476d4a1838e5e12168bef2fd1e6620", - "reference": "92bd2bfbba476d4a1838e5e12168bef2fd1e6620", + "url": "https://api.github.com/repos/symfony/string/zipball/6f41b185e742737917e6f2e3eca37767fba5f17a", + "reference": "6f41b185e742737917e6f2e3eca37767fba5f17a", "shasum": "" }, "require": { @@ -2603,6 +3303,7 @@ "symfony/translation-contracts": "<2.5" }, "require-dev": { + "symfony/emoji": "^7.1", "symfony/error-handler": "^6.4|^7.0", "symfony/http-client": "^6.4|^7.0", "symfony/intl": "^6.4|^7.0", @@ -2646,7 +3347,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.0.0" + "source": "https://github.com/symfony/string/tree/v7.1.0" }, "funding": [ { @@ -2662,32 +3363,31 @@ "type": "tidelift" } ], - "time": "2023-11-29T08:40:23+00:00" + "time": "2024-05-17T10:55:18+00:00" }, { "name": "symfony/yaml", - "version": "v6.4.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587" + "reference": "c5f718c94e3c37dd77b77484e6cf0b524b2d405e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/4f9237a1bb42455d609e6687d2613dde5b41a587", - "reference": "4f9237a1bb42455d609e6687d2613dde5b41a587", + "url": "https://api.github.com/repos/symfony/yaml/zipball/c5f718c94e3c37dd77b77484e6cf0b524b2d405e", + "reference": "c5f718c94e3c37dd77b77484e6cf0b524b2d405e", "shasum": "" }, "require": { - "php": ">=8.1", - "symfony/deprecation-contracts": "^2.5|^3", + "php": ">=8.2", "symfony/polyfill-ctype": "^1.8" }, "conflict": { - "symfony/console": "<5.4" + "symfony/console": "<6.4" }, "require-dev": { - "symfony/console": "^5.4|^6.0|^7.0" + "symfony/console": "^6.4|^7.0" }, "bin": [ "Resources/bin/yaml-lint" @@ -2718,7 +3418,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v6.4.0" + "source": "https://github.com/symfony/yaml/tree/v7.1.0" }, "funding": [ { @@ -2734,34 +3434,41 @@ "type": "tidelift" } ], - "time": "2023-11-06T11:00:25+00:00" + "time": "2024-04-28T18:29:00+00:00" }, { "name": "twig/twig", - "version": "v3.8.0", + "version": "v3.10.3", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d" + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", - "reference": "9d15f0ac07f44dc4217883ec6ae02fd555c6f71d", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572", + "reference": "67f29781ffafa520b0bbfbd8384674b42db04572", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", "symfony/polyfill-php80": "^1.22" }, "require-dev": { "psr/container": "^1.0|^2.0", - "symfony/phpunit-bridge": "^5.4.9|^6.3|^7.0" + "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, "type": "library", "autoload": { + "files": [ + "src/Resources/core.php", + "src/Resources/debug.php", + "src/Resources/escaper.php", + "src/Resources/string_loader.php" + ], "psr-4": { "Twig\\": "src/" } @@ -2794,7 +3501,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.8.0" + "source": "https://github.com/twigphp/Twig/tree/v3.10.3" }, "funding": [ { @@ -2806,7 +3513,7 @@ "type": "tidelift" } ], - "time": "2023-11-21T18:54:41+00:00" + "time": "2024-05-16T10:04:27+00:00" }, { "name": "zozlak/rdf-constants", @@ -2850,16 +3557,16 @@ "packages-dev": [ { "name": "api-platform/core", - "version": "v3.2.7", + "version": "v3.3.5", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "f297d2192652a3acd2a644707740de8cb5069221" + "reference": "b5a93fb0bb855273aabb0807505ba61b68813246" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/f297d2192652a3acd2a644707740de8cb5069221", - "reference": "f297d2192652a3acd2a644707740de8cb5069221", + "url": "https://api.github.com/repos/api-platform/core/zipball/b5a93fb0bb855273aabb0807505ba61b68813246", + "reference": "b5a93fb0bb855273aabb0807505ba61b68813246", "shasum": "" }, "require": { @@ -2868,13 +3575,13 @@ "psr/cache": "^1.0 || ^2.0 || ^3.0", "psr/container": "^1.0 || ^2.0", "symfony/deprecation-contracts": "^3.1", - "symfony/http-foundation": "^6.1 || ^7.0", - "symfony/http-kernel": "^6.1 || ^7.0", - "symfony/property-access": "^6.1 || ^7.0", - "symfony/property-info": "^6.1 || ^7.0", - "symfony/serializer": "^6.1 || ^7.0", + "symfony/http-foundation": "^6.4 || ^7.0", + "symfony/http-kernel": "^6.4 || ^7.0", + "symfony/property-access": "^6.4 || ^7.0", + "symfony/property-info": "^6.4 || ^7.0", + "symfony/serializer": "^6.4 || ^7.0", "symfony/translation-contracts": "^3.3", - "symfony/web-link": "^6.1 || ^7.0", + "symfony/web-link": "^6.4 || ^7.0", "willdurand/negotiation": "^3.0" }, "conflict": { @@ -2886,6 +3593,7 @@ "elasticsearch/elasticsearch": ">=8.0,<8.4", "phpspec/prophecy": "<1.15", "phpunit/phpunit": "<9.5", + "symfony/framework-bundle": "6.4.6 || 7.0.6", "symfony/var-exporter": "<6.1.1" }, "require-dev": { @@ -2896,7 +3604,8 @@ "doctrine/dbal": "^3.4.0", "doctrine/doctrine-bundle": "^1.12 || ^2.0", "doctrine/mongodb-odm": "^2.2", - "doctrine/orm": "^2.14", + "doctrine/mongodb-odm-bundle": "^4.0 || ^5.0", + "doctrine/orm": "^2.14 || ^3.0", "elasticsearch/elasticsearch": "^7.11 || ^8.4", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", @@ -2907,45 +3616,48 @@ "phpspec/prophecy-phpunit": "^2.0", "phpstan/extension-installer": "^1.1", "phpstan/phpdoc-parser": "^1.13", - "phpstan/phpstan": "^1.1", + "phpstan/phpstan": "^1.10", "phpstan/phpstan-doctrine": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-symfony": "^1.0", + "phpunit/phpunit": "^9.6", "psr/log": "^1.0 || ^2.0 || ^3.0", "ramsey/uuid": "^3.9.7 || ^4.0", "ramsey/uuid-doctrine": "^1.4 || ^2.0", + "sebastian/comparator": "<5.0", "soyuka/contexts": "v3.3.9", + "soyuka/pmu": "^0.0.2", "soyuka/stubs-mongodb": "^1.0", - "symfony/asset": "^6.1 || ^7.0", - "symfony/browser-kit": "^6.1 || ^7.0", - "symfony/cache": "^6.1 || ^7.0", - "symfony/config": "^6.1 || ^7.0", - "symfony/console": "^6.1 || ^7.0", - "symfony/css-selector": "^6.1 || ^7.0", - "symfony/dependency-injection": "^6.1 || ^7.0.12", - "symfony/doctrine-bridge": "^6.1 || ^7.0", - "symfony/dom-crawler": "^6.1 || ^7.0", - "symfony/error-handler": "^6.1 || ^7.0", - "symfony/event-dispatcher": "^6.1 || ^7.0", - "symfony/expression-language": "^6.1 || ^7.0", - "symfony/finder": "^6.1 || ^7.0", - "symfony/form": "^6.1 || ^7.0", - "symfony/framework-bundle": "^6.1 || ^7.0", - "symfony/http-client": "^6.1 || ^7.0", - "symfony/intl": "^6.1 || ^7.0", + "symfony/asset": "^6.4 || ^7.0", + "symfony/browser-kit": "^6.4 || ^7.0", + "symfony/cache": "^6.4 || ^7.0", + "symfony/config": "^6.4 || ^7.0", + "symfony/console": "^6.4 || ^7.0", + "symfony/css-selector": "^6.4 || ^7.0", + "symfony/dependency-injection": "^6.4 || ^7.0.12", + "symfony/doctrine-bridge": "^6.4 || ^7.0", + "symfony/dom-crawler": "^6.4 || ^7.0", + "symfony/error-handler": "^6.4 || ^7.0", + "symfony/event-dispatcher": "^6.4 || ^7.0", + "symfony/expression-language": "^6.4 || ^7.0", + "symfony/finder": "^6.4 || ^7.0", + "symfony/form": "^6.4 || ^7.0", + "symfony/framework-bundle": "^6.4 || ^7.0", + "symfony/http-client": "^6.4 || ^7.0", + "symfony/intl": "^6.4 || ^7.0", "symfony/maker-bundle": "^1.24", "symfony/mercure-bundle": "*", - "symfony/messenger": "^6.1 || ^7.0", - "symfony/phpunit-bridge": "^6.1 || ^7.0", - "symfony/routing": "^6.1 || ^7.0", - "symfony/security-bundle": "^6.1 || ^7.0", - "symfony/security-core": "^6.1 || ^7.0", - "symfony/stopwatch": "^6.1 || ^7.0", - "symfony/twig-bundle": "^6.1 || ^7.0", - "symfony/uid": "^6.1 || ^7.0", - "symfony/validator": "^6.1 || ^7.0", - "symfony/web-profiler-bundle": "^6.1 || ^7.0", - "symfony/yaml": "^6.1 || ^7.0", + "symfony/messenger": "^6.4 || ^7.0", + "symfony/phpunit-bridge": "^6.4.1 || ^7.0", + "symfony/routing": "^6.4 || ^7.0", + "symfony/security-bundle": "^6.4 || ^7.0", + "symfony/security-core": "^6.4 || ^7.0", + "symfony/stopwatch": "^6.4 || ^7.0", + "symfony/twig-bundle": "^6.4 || ^7.0", + "symfony/uid": "^6.4 || ^7.0", + "symfony/validator": "^6.4 || ^7.0", + "symfony/web-profiler-bundle": "^6.4 || ^7.0", + "symfony/yaml": "^6.4 || ^7.0", "twig/twig": "^1.42.3 || ^2.12 || ^3.0", "webonyx/graphql-php": "^14.0 || ^15.0" }, @@ -2973,8 +3685,28 @@ "dev-main": "3.3.x-dev" }, "symfony": { - "require": "^6.1 || ^7.0" - } + "require": "^6.4 || ^7.0" + }, + "projects": [ + "api-platform/doctrine-common", + "api-platform/doctrine-orm", + "api-platform/doctrine-odm", + "api-platform/metadata", + "api-platform/json-schema", + "api-platform/elasticsearch", + "api-platform/jsonld", + "api-platform/hydra", + "api-platform/openapi", + "api-platform/graphql", + "api-platform/http-cache", + "api-platform/documentation", + "api-platform/parameter-validator", + "api-platform/ramsey-uuid", + "api-platform/serializer", + "api-platform/state", + "api-platform/symfony", + "api-platform/validator" + ] }, "autoload": { "psr-4": { @@ -3007,9 +3739,9 @@ ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v3.2.7" + "source": "https://github.com/api-platform/core/tree/v3.3.5" }, - "time": "2023-11-30T13:51:25+00:00" + "time": "2024-05-29T05:48:47+00:00" }, { "name": "doctrine/cache", @@ -3106,16 +3838,16 @@ }, { "name": "doctrine/collections", - "version": "2.1.4", + "version": "2.2.2", "source": { "type": "git", "url": "https://github.com/doctrine/collections.git", - "reference": "72328a11443a0de79967104ad36ba7b30bded134" + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/collections/zipball/72328a11443a0de79967104ad36ba7b30bded134", - "reference": "72328a11443a0de79967104ad36ba7b30bded134", + "url": "https://api.github.com/repos/doctrine/collections/zipball/d8af7f248c74f195f7347424600fd9e17b57af59", + "reference": "d8af7f248c74f195f7347424600fd9e17b57af59", "shasum": "" }, "require": { @@ -3127,7 +3859,7 @@ "ext-json": "*", "phpstan/phpstan": "^1.8", "phpstan/phpstan-phpunit": "^1.0", - "phpunit/phpunit": "^9.5", + "phpunit/phpunit": "^10.5", "vimeo/psalm": "^5.11" }, "type": "library", @@ -3172,7 +3904,7 @@ ], "support": { "issues": "https://github.com/doctrine/collections/issues", - "source": "https://github.com/doctrine/collections/tree/2.1.4" + "source": "https://github.com/doctrine/collections/tree/2.2.2" }, "funding": [ { @@ -3188,20 +3920,20 @@ "type": "tidelift" } ], - "time": "2023-10-03T09:22:33+00:00" + "time": "2024-04-18T06:56:21+00:00" }, { "name": "doctrine/common", - "version": "3.4.3", + "version": "3.4.4", "source": { "type": "git", "url": "https://github.com/doctrine/common.git", - "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced" + "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/8b5e5650391f851ed58910b3e3d48a71062eeced", - "reference": "8b5e5650391f851ed58910b3e3d48a71062eeced", + "url": "https://api.github.com/repos/doctrine/common/zipball/0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", + "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", "shasum": "" }, "require": { @@ -3263,7 +3995,7 @@ ], "support": { "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.3" + "source": "https://github.com/doctrine/common/tree/3.4.4" }, "funding": [ { @@ -3279,20 +4011,20 @@ "type": "tidelift" } ], - "time": "2022-10-09T11:47:59+00:00" + "time": "2024-04-16T13:35:33+00:00" }, { "name": "doctrine/dbal", - "version": "3.7.2", + "version": "3.8.4", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "0ac3c270590e54910715e9a1a044cc368df282b2" + "reference": "b05e48a745f722801f55408d0dbd8003b403dbbd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/0ac3c270590e54910715e9a1a044cc368df282b2", - "reference": "0ac3c270590e54910715e9a1a044cc368df282b2", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/b05e48a745f722801f55408d0dbd8003b403dbbd", + "reference": "b05e48a745f722801f55408d0dbd8003b403dbbd", "shasum": "" }, "require": { @@ -3308,14 +4040,14 @@ "doctrine/coding-standard": "12.0.0", "fig/log-test": "^1", "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.42", + "phpstan/phpstan": "1.10.58", "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.13", + "phpunit/phpunit": "9.6.16", "psalm/plugin-phpunit": "0.18.4", "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^5.4|^6.0", - "symfony/console": "^4.4|^5.4|^6.0", + "squizlabs/php_codesniffer": "3.9.0", + "symfony/cache": "^5.4|^6.0|^7.0", + "symfony/console": "^4.4|^5.4|^6.0|^7.0", "vimeo/psalm": "4.30.0" }, "suggest": { @@ -3376,7 +4108,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.7.2" + "source": "https://github.com/doctrine/dbal/tree/3.8.4" }, "funding": [ { @@ -3392,20 +4124,20 @@ "type": "tidelift" } ], - "time": "2023-11-19T08:06:58+00:00" + "time": "2024-04-25T07:04:44+00:00" }, { "name": "doctrine/deprecations", - "version": "1.1.2", + "version": "1.1.3", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931" + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/4f2d4f2836e7ec4e7a8625e75c6aa916004db931", - "reference": "4f2d4f2836e7ec4e7a8625e75c6aa916004db931", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", "shasum": "" }, "require": { @@ -3437,22 +4169,22 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.2" + "source": "https://github.com/doctrine/deprecations/tree/1.1.3" }, - "time": "2023-09-27T20:04:15+00:00" + "time": "2024-01-30T19:34:25+00:00" }, { "name": "doctrine/event-manager", - "version": "2.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32" + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/750671534e0241a7c50ea5b43f67e23eb5c96f32", - "reference": "750671534e0241a7c50ea5b43f67e23eb5c96f32", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/b680156fa328f1dfd874fd48c7026c41570b9c6e", + "reference": "b680156fa328f1dfd874fd48c7026c41570b9c6e", "shasum": "" }, "require": { @@ -3462,10 +4194,10 @@ "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^10", + "doctrine/coding-standard": "^12", "phpstan/phpstan": "^1.8.8", - "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^4.28" + "phpunit/phpunit": "^10.5", + "vimeo/psalm": "^5.24" }, "type": "library", "autoload": { @@ -3514,7 +4246,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/2.0.0" + "source": "https://github.com/doctrine/event-manager/tree/2.0.1" }, "funding": [ { @@ -3530,7 +4262,7 @@ "type": "tidelift" } ], - "time": "2022-10-12T20:59:15+00:00" + "time": "2024-05-22T20:47:39+00:00" }, { "name": "doctrine/instantiator", @@ -3604,28 +4336,27 @@ }, { "name": "doctrine/lexer", - "version": "2.1.0", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/doctrine/lexer.git", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124" + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", - "reference": "39ab8fcf5a51ce4b85ca97c7a7d033eb12831124", + "url": "https://api.github.com/repos/doctrine/lexer/zipball/31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", + "reference": "31ad66abc0fc9e1a1f2d9bc6a42668d2fbbcd6dd", "shasum": "" }, "require": { - "doctrine/deprecations": "^1.0", - "php": "^7.1 || ^8.0" + "php": "^8.1" }, "require-dev": { - "doctrine/coding-standard": "^9 || ^10", - "phpstan/phpstan": "^1.3", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "^1.10", + "phpunit/phpunit": "^10.5", "psalm/plugin-phpunit": "^0.18.3", - "vimeo/psalm": "^4.11 || ^5.0" + "vimeo/psalm": "^5.21" }, "type": "library", "autoload": { @@ -3662,7 +4393,7 @@ ], "support": { "issues": "https://github.com/doctrine/lexer/issues", - "source": "https://github.com/doctrine/lexer/tree/2.1.0" + "source": "https://github.com/doctrine/lexer/tree/3.0.1" }, "funding": [ { @@ -3678,20 +4409,20 @@ "type": "tidelift" } ], - "time": "2022-12-14T08:49:07+00:00" + "time": "2024-02-05T11:56:58+00:00" }, { "name": "doctrine/orm", - "version": "2.17.1", + "version": "2.19.5", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1" + "reference": "94986af28452da42a46a4489d1c958a2e5d710e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/1a4fe6e0bb67762370937a7e6cee3da40a9122d1", - "reference": "1a4fe6e0bb67762370937a7e6cee3da40a9122d1", + "url": "https://api.github.com/repos/doctrine/orm/zipball/94986af28452da42a46a4489d1c958a2e5d710e5", + "reference": "94986af28452da42a46a4489d1c958a2e5d710e5", "shasum": "" }, "require": { @@ -3704,7 +4435,7 @@ "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", - "doctrine/lexer": "^2", + "doctrine/lexer": "^2 || ^3", "doctrine/persistence": "^2.4 || ^3", "ext-ctype": "*", "php": "^7.1 || ^8.0", @@ -3720,14 +4451,14 @@ "doctrine/annotations": "^1.13 || ^2", "doctrine/coding-standard": "^9.0.2 || ^12.0", "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.35", + "phpstan/phpstan": "~1.4.10 || 1.10.59", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.15.0" + "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", + "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", + "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", + "vimeo/psalm": "4.30.0 || 5.22.2" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", @@ -3740,7 +4471,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\ORM\\": "lib/Doctrine/ORM" + "Doctrine\\ORM\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -3777,22 +4508,22 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.17.1" + "source": "https://github.com/doctrine/orm/tree/2.19.5" }, - "time": "2023-11-17T06:25:40+00:00" + "time": "2024-04-30T06:49:54+00:00" }, { "name": "doctrine/persistence", - "version": "3.2.0", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "63fee8c33bef740db6730eb2a750cd3da6495603" + "reference": "477da35bd0255e032826f440b94b3e37f2d56f42" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/63fee8c33bef740db6730eb2a750cd3da6495603", - "reference": "63fee8c33bef740db6730eb2a750cd3da6495603", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/477da35bd0255e032826f440b94b3e37f2d56f42", + "reference": "477da35bd0255e032826f440b94b3e37f2d56f42", "shasum": "" }, "require": { @@ -3861,7 +4592,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.2.0" + "source": "https://github.com/doctrine/persistence/tree/3.3.2" }, "funding": [ { @@ -3877,7 +4608,7 @@ "type": "tidelift" } ], - "time": "2023-05-17T18:32:04+00:00" + "time": "2024-03-12T14:54:36+00:00" }, { "name": "myclabs/deep-copy", @@ -4003,20 +4734,21 @@ }, { "name": "phar-io/manifest", - "version": "2.0.3", + "version": "2.0.4", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53" + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", - "reference": "97803eca37d319dfa7826cc2437fc020857acb53", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { "ext-dom": "*", + "ext-libxml": "*", "ext-phar": "*", "ext-xmlwriter": "*", "phar-io/version": "^3.0.1", @@ -4057,9 +4789,15 @@ "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { "issues": "https://github.com/phar-io/manifest/issues", - "source": "https://github.com/phar-io/manifest/tree/2.0.3" + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-07-20T11:28:43+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { "name": "phar-io/version", @@ -4167,28 +4905,35 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", + "version": "5.4.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" + "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", + "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", "shasum": "" }, "require": { + "doctrine/deprecations": "^1.1", "ext-filter": "*", - "php": "^7.2 || ^8.0", + "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", + "phpdocumentor/type-resolver": "^1.7", + "phpstan/phpdoc-parser": "^1.7", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" + "mockery/mockery": "~1.3.5", + "phpstan/extension-installer": "^1.1", + "phpstan/phpstan": "^1.8", + "phpstan/phpstan-mockery": "^1.1", + "phpstan/phpstan-webmozart-assert": "^1.2", + "phpunit/phpunit": "^9.5", + "vimeo/psalm": "^5.13" }, "type": "library", "extra": { @@ -4212,33 +4957,33 @@ }, { "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" + "email": "opensource@ijaap.nl" } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" }, - "time": "2021-10-19T17:43:47+00:00" + "time": "2024-05-21T05:55:05+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.7.3", + "version": "1.8.2", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419" + "reference": "153ae662783729388a584b4361f2545e4d841e3c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", - "reference": "3219c6ee25c9ea71e3d9bbaf39c67c9ebd499419", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", + "reference": "153ae662783729388a584b4361f2545e4d841e3c", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", - "php": "^7.4 || ^8.0", + "php": "^7.3 || ^8.0", "phpdocumentor/reflection-common": "^2.0", "phpstan/phpdoc-parser": "^1.13" }, @@ -4276,30 +5021,30 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.7.3" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" }, - "time": "2023-08-12T11:01:26+00:00" + "time": "2024-02-23T11:10:43+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.18.0", + "version": "v1.19.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d4f454f7e1193933f04e6500de3e79191648ed0c" + "reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d4f454f7e1193933f04e6500de3e79191648ed0c", - "reference": "d4f454f7e1193933f04e6500de3e79191648ed0c", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/67a759e7d8746d501c41536ba40cd9c0a07d6a87", + "reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2 || ^2.0", "php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*", "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0 || ^5.0", - "sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0" + "sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0", + "sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { "phpspec/phpspec": "^6.0 || ^7.0", @@ -4345,33 +5090,33 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.18.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.19.0" }, - "time": "2023-12-07T16:22:33+00:00" + "time": "2024-02-29T11:52:51+00:00" }, { "name": "phpspec/prophecy-phpunit", - "version": "v2.1.0", + "version": "v2.2.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "29f8114c2c319a4308e6b070902211e062efa392" + "reference": "16e1247e139434bce0bac09848bc5c8d882940fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/29f8114c2c319a4308e6b070902211e062efa392", - "reference": "29f8114c2c319a4308e6b070902211e062efa392", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/16e1247e139434bce0bac09848bc5c8d882940fc", + "reference": "16e1247e139434bce0bac09848bc5c8d882940fc", "shasum": "" }, "require": { "php": "^7.3 || ^8", "phpspec/prophecy": "^1.18", - "phpunit/phpunit": "^9.1 || ^10.1" + "phpunit/phpunit": "^9.1 || ^10.1 || ^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -4397,22 +5142,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy-phpunit/issues", - "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.1.0" + "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.2.0" }, - "time": "2023-12-08T12:48:02+00:00" + "time": "2024-03-01T08:33:58+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.24.4", + "version": "1.29.1", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496" + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/6bd0c26f3786cd9b7c359675cb789e35a8e07496", - "reference": "6bd0c26f3786cd9b7c359675cb789e35a8e07496", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", "shasum": "" }, "require": { @@ -4444,22 +5189,22 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.24.4" + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" }, - "time": "2023-11-26T18:29:22+00:00" + "time": "2024-05-31T08:52:43+00:00" }, { "name": "phpstan/phpstan", - "version": "1.10.48", + "version": "1.11.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6" + "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6", - "reference": "087ed4b5f4a7a6e8f3bbdfbfe98ce5c181380bc6", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", + "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", "shasum": "" }, "require": { @@ -4502,33 +5247,29 @@ { "url": "https://github.com/phpstan", "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", - "type": "tidelift" } ], - "time": "2023-12-08T14:34:28+00:00" + "time": "2024-05-24T13:23:04+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.29", + "version": "9.2.31", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76" + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/6a3a87ac2bbe33b25042753df8195ba4aa534c76", - "reference": "6a3a87ac2bbe33b25042753df8195ba4aa534c76", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", + "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -4578,7 +5319,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.29" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" }, "funding": [ { @@ -4586,7 +5327,7 @@ "type": "github" } ], - "time": "2023-09-19T04:57:46+00:00" + "time": "2024-03-02T06:37:42+00:00" }, { "name": "phpunit/php-file-iterator", @@ -4831,16 +5572,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.6.15", + "version": "9.6.19", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1" + "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/05017b80304e0eb3f31d90194a563fd53a6021f1", - "reference": "05017b80304e0eb3f31d90194a563fd53a6021f1", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8", + "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8", "shasum": "" }, "require": { @@ -4914,7 +5655,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.15" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19" }, "funding": [ { @@ -4930,7 +5671,7 @@ "type": "tidelift" } ], - "time": "2023-12-01T16:55:19+00:00" + "time": "2024-04-05T04:35:58+00:00" }, { "name": "psr/cache", @@ -5039,16 +5780,16 @@ }, { "name": "sebastian/cli-parser", - "version": "1.0.1", + "version": "1.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", "shasum": "" }, "require": { @@ -5083,7 +5824,7 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" }, "funding": [ { @@ -5091,7 +5832,7 @@ "type": "github" } ], - "time": "2020-09-28T06:08:49+00:00" + "time": "2024-03-02T06:27:43+00:00" }, { "name": "sebastian/code-unit", @@ -5280,20 +6021,20 @@ }, { "name": "sebastian/complexity", - "version": "2.0.2", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88" + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/739b35e53379900cc9ac327b2147867b8b6efd88", - "reference": "739b35e53379900cc9ac327b2147867b8b6efd88", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.7", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -5325,7 +6066,7 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" }, "funding": [ { @@ -5333,7 +6074,7 @@ "type": "github" } ], - "time": "2020-10-26T15:52:27+00:00" + "time": "2023-12-22T06:19:30+00:00" }, { "name": "sebastian/environment", @@ -5400,16 +6141,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.5", + "version": "4.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d" + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", - "reference": "ac230ed27f0f98f597c8a2b6eb7ac563af5e5b9d", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", + "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", "shasum": "" }, "require": { @@ -5465,7 +6206,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.5" + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" }, "funding": [ { @@ -5473,20 +6214,20 @@ "type": "github" } ], - "time": "2022-09-14T06:03:37+00:00" + "time": "2024-03-02T06:33:00+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.6", + "version": "5.0.7", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bde739e7565280bda77be70044ac1047bc007e34" + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bde739e7565280bda77be70044ac1047bc007e34", - "reference": "bde739e7565280bda77be70044ac1047bc007e34", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", "shasum": "" }, "require": { @@ -5529,7 +6270,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.6" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" }, "funding": [ { @@ -5537,24 +6278,24 @@ "type": "github" } ], - "time": "2023-08-02T09:26:13+00:00" + "time": "2024-03-02T06:35:11+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.3", + "version": "1.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc" + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/c1c2e997aa3146983ed888ad08b15470a2e22ecc", - "reference": "c1c2e997aa3146983ed888ad08b15470a2e22ecc", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", "shasum": "" }, "require": { - "nikic/php-parser": "^4.6", + "nikic/php-parser": "^4.18 || ^5.0", "php": ">=7.3" }, "require-dev": { @@ -5586,7 +6327,7 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" }, "funding": [ { @@ -5594,7 +6335,7 @@ "type": "github" } ], - "time": "2020-11-28T06:42:11+00:00" + "time": "2023-12-22T06:20:34+00:00" }, { "name": "sebastian/object-enumerator", @@ -5773,16 +6514,16 @@ }, { "name": "sebastian/resource-operations", - "version": "3.0.3", + "version": "3.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8" + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", - "reference": "0f4443cb3a1d92ce809899753bc0d5d5a8dd19a8", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", "shasum": "" }, "require": { @@ -5794,7 +6535,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -5815,8 +6556,7 @@ "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/resource-operations/issues", - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" }, "funding": [ { @@ -5824,7 +6564,7 @@ "type": "github" } ], - "time": "2020-09-28T06:45:17+00:00" + "time": "2024-03-14T16:00:52+00:00" }, { "name": "sebastian/type", @@ -5937,22 +6677,23 @@ }, { "name": "symfony/doctrine-bridge", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "5e8e95e8389d03f2f3ae16a6c7c804849ed483b5" + "reference": "5ae0d9d1d54663daddd132ca6a5757e7d1f2fcd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/5e8e95e8389d03f2f3ae16a6c7c804849ed483b5", - "reference": "5e8e95e8389d03f2f3ae16a6c7c804849ed483b5", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/5ae0d9d1d54663daddd132ca6a5757e7d1f2fcd2", + "reference": "5ae0d9d1d54663daddd132ca6a5757e7d1f2fcd2", "shasum": "" }, "require": { "doctrine/event-manager": "^2", "doctrine/persistence": "^3.1", "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/service-contracts": "^2.5|^3" @@ -5963,7 +6704,7 @@ "doctrine/orm": "<2.15", "symfony/cache": "<6.4", "symfony/dependency-injection": "<6.4", - "symfony/form": "<6.4", + "symfony/form": "<6.4.6|>=7,<7.0.6", "symfony/http-foundation": "<6.4", "symfony/http-kernel": "<6.4", "symfony/lock": "<6.4", @@ -5984,7 +6725,7 @@ "symfony/dependency-injection": "^6.4|^7.0", "symfony/doctrine-messenger": "^6.4|^7.0", "symfony/expression-language": "^6.4|^7.0", - "symfony/form": "^6.4|^7.0", + "symfony/form": "^6.4.6|^7.0.6", "symfony/http-kernel": "^6.4|^7.0", "symfony/lock": "^6.4|^7.0", "symfony/messenger": "^6.4|^7.0", @@ -5993,6 +6734,7 @@ "symfony/security-core": "^6.4|^7.0", "symfony/stopwatch": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", + "symfony/type-info": "^7.1", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0" @@ -6023,7 +6765,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.0.0" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.1.0" }, "funding": [ { @@ -6039,20 +6781,20 @@ "type": "tidelift" } ], - "time": "2023-11-17T16:04:05+00:00" + "time": "2024-05-30T18:00:20+00:00" }, { "name": "symfony/error-handler", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "80b1258be1b84c12a345d0ec3881bbf2e5270cc2" + "reference": "477d911900bf32fc43a675f78d4cbaedbb78378f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/80b1258be1b84c12a345d0ec3881bbf2e5270cc2", - "reference": "80b1258be1b84c12a345d0ec3881bbf2e5270cc2", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/477d911900bf32fc43a675f78d4cbaedbb78378f", + "reference": "477d911900bf32fc43a675f78d4cbaedbb78378f", "shasum": "" }, "require": { @@ -6098,7 +6840,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.0.0" + "source": "https://github.com/symfony/error-handler/tree/v7.1.0" }, "funding": [ { @@ -6114,20 +6856,20 @@ "type": "tidelift" } ], - "time": "2023-10-20T16:35:23+00:00" + "time": "2024-05-17T10:55:18+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "47d72323200934694def5d57083899d774a2b110" + "reference": "f9c54a6b1697d0b3b3d541e89e7843cdb3c9bfb7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/47d72323200934694def5d57083899d774a2b110", - "reference": "47d72323200934694def5d57083899d774a2b110", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f9c54a6b1697d0b3b3d541e89e7843cdb3c9bfb7", + "reference": "f9c54a6b1697d0b3b3d541e89e7843cdb3c9bfb7", "shasum": "" }, "require": { @@ -6175,7 +6917,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.0.0" + "source": "https://github.com/symfony/http-foundation/tree/v7.1.0" }, "funding": [ { @@ -6191,25 +6933,26 @@ "type": "tidelift" } ], - "time": "2023-11-07T15:10:37+00:00" + "time": "2024-05-20T16:41:11+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.0.1", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "4787639523dcdda32f69063f7fca2ad709f3c6d2" + "reference": "7eb093ee3911354aa13704d757127535dd8d371f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/4787639523dcdda32f69063f7fca2ad709f3c6d2", - "reference": "4787639523dcdda32f69063f7fca2ad709f3c6d2", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/7eb093ee3911354aa13704d757127535dd8d371f", + "reference": "7eb093ee3911354aa13704d757127535dd8d371f", "shasum": "" }, "require": { "php": ">=8.2", "psr/log": "^1|^2|^3", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/error-handler": "^6.4|^7.0", "symfony/event-dispatcher": "^6.4|^7.0", "symfony/http-foundation": "^6.4|^7.0", @@ -6250,14 +6993,15 @@ "symfony/finder": "^6.4|^7.0", "symfony/http-client-contracts": "^2.5|^3", "symfony/process": "^6.4|^7.0", - "symfony/property-access": "^6.4|^7.0", + "symfony/property-access": "^7.1", "symfony/routing": "^6.4|^7.0", - "symfony/serializer": "^6.4|^7.0", + "symfony/serializer": "^7.1", "symfony/stopwatch": "^6.4|^7.0", "symfony/translation": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0", "symfony/var-exporter": "^6.4|^7.0", "twig/twig": "^3.0.4" }, @@ -6287,7 +7031,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.0.1" + "source": "https://github.com/symfony/http-kernel/tree/v7.1.0" }, "funding": [ { @@ -6303,20 +7047,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T17:08:48+00:00" + "time": "2024-05-31T07:46:30+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v7.0.1", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "c2d059b25e31274157dd7727131cd1cf33650207" + "reference": "1168ef27edb094fe4ba755ec937cf62a6dff84eb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/c2d059b25e31274157dd7727131cd1cf33650207", - "reference": "c2d059b25e31274157dd7727131cd1cf33650207", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/1168ef27edb094fe4ba755ec937cf62a6dff84eb", + "reference": "1168ef27edb094fe4ba755ec937cf62a6dff84eb", "shasum": "" }, "require": { @@ -6368,7 +7112,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.0.1" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.0" }, "funding": [ { @@ -6384,20 +7128,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T09:26:31+00:00" + "time": "2024-05-17T10:55:18+00:00" }, { "name": "symfony/polyfill-php72", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179" + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/70f4aebd92afca2f865444d30a4d2151c13c3179", - "reference": "70f4aebd92afca2f865444d30a4d2151c13c3179", + "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", + "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", "shasum": "" }, "require": { @@ -6405,9 +7149,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6444,7 +7185,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" }, "funding": [ { @@ -6460,20 +7201,20 @@ "type": "tidelift" } ], - "time": "2023-01-26T09:26:14+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.28.0", + "version": "v1.29.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11" + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", - "reference": "b0f46ebbeeeda3e9d2faebdfbf4b4eae9b59fa11", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", + "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", "shasum": "" }, "require": { @@ -6482,9 +7223,6 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.28-dev" - }, "thanks": { "name": "symfony/polyfill", "url": "https://github.com/symfony/polyfill" @@ -6524,7 +7262,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.28.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" }, "funding": [ { @@ -6540,20 +7278,20 @@ "type": "tidelift" } ], - "time": "2023-08-16T06:22:46+00:00" + "time": "2024-01-29T20:11:03+00:00" }, { "name": "symfony/property-access", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "740e8cb8c54a4f16c82179e8558c29d9fc49901d" + "reference": "1e8c1e6ac1b19cf945d8094a0ee50296872c4cb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/740e8cb8c54a4f16c82179e8558c29d9fc49901d", - "reference": "740e8cb8c54a4f16c82179e8558c29d9fc49901d", + "url": "https://api.github.com/repos/symfony/property-access/zipball/1e8c1e6ac1b19cf945d8094a0ee50296872c4cb2", + "reference": "1e8c1e6ac1b19cf945d8094a0ee50296872c4cb2", "shasum": "" }, "require": { @@ -6600,7 +7338,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.0.0" + "source": "https://github.com/symfony/property-access/tree/v7.1.0" }, "funding": [ { @@ -6616,25 +7354,26 @@ "type": "tidelift" } ], - "time": "2023-09-27T14:05:33+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "symfony/property-info", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "ce627df05f5629ce4feec536ee827ad0a12689b6" + "reference": "b10cb8cf0179aec96769df2affb881ecfc293f79" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/ce627df05f5629ce4feec536ee827ad0a12689b6", - "reference": "ce627df05f5629ce4feec536ee827ad0a12689b6", + "url": "https://api.github.com/repos/symfony/property-info/zipball/b10cb8cf0179aec96769df2affb881ecfc293f79", + "reference": "b10cb8cf0179aec96769df2affb881ecfc293f79", "shasum": "" }, "require": { "php": ">=8.2", - "symfony/string": "^6.4|^7.0" + "symfony/string": "^6.4|^7.0", + "symfony/type-info": "^7.1" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", @@ -6683,7 +7422,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.0.0" + "source": "https://github.com/symfony/property-info/tree/v7.1.0" }, "funding": [ { @@ -6699,24 +7438,25 @@ "type": "tidelift" } ], - "time": "2023-11-25T08:38:27+00:00" + "time": "2024-05-30T12:09:55+00:00" }, { "name": "symfony/serializer", - "version": "v7.0.1", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "9c8f67c1444adf6dbcf90fb76da5b2f5c43af0ff" + "reference": "972eb05320d06d07399b71b05e6da9032c865f1d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/9c8f67c1444adf6dbcf90fb76da5b2f5c43af0ff", - "reference": "9c8f67c1444adf6dbcf90fb76da5b2f5c43af0ff", + "url": "https://api.github.com/repos/symfony/serializer/zipball/972eb05320d06d07399b71b05e6da9032c865f1d", + "reference": "972eb05320d06d07399b71b05e6da9032c865f1d", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8" }, "conflict": { @@ -6746,6 +7486,7 @@ "symfony/property-access": "^6.4|^7.0", "symfony/property-info": "^6.4|^7.0", "symfony/translation-contracts": "^2.5|^3", + "symfony/type-info": "^7.1", "symfony/uid": "^6.4|^7.0", "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0", @@ -6778,7 +7519,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.0.1" + "source": "https://github.com/symfony/serializer/tree/v7.1.0" }, "funding": [ { @@ -6794,20 +7535,20 @@ "type": "tidelift" } ], - "time": "2023-12-01T15:10:06+00:00" + "time": "2024-05-21T15:59:31+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.4.0", + "version": "v3.5.0", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5" + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/dee0c6e5b4c07ce851b462530088e64b255ac9c5", - "reference": "dee0c6e5b4c07ce851b462530088e64b255ac9c5", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", "shasum": "" }, "require": { @@ -6816,7 +7557,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "3.4-dev" + "dev-main": "3.5-dev" }, "thanks": { "name": "symfony/contracts", @@ -6856,7 +7597,89 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.4.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2024-04-18T09:32:20+00:00" + }, + { + "name": "symfony/type-info", + "version": "v7.1.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/type-info.git", + "reference": "b429d0710588fc396ba5def5329cf637d9861f9f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/type-info/zipball/b429d0710588fc396ba5def5329cf637d9861f9f", + "reference": "b429d0710588fc396ba5def5329cf637d9861f9f", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "psr/container": "^1.1|^2.0" + }, + "conflict": { + "phpstan/phpdoc-parser": "<1.0", + "symfony/dependency-injection": "<6.4", + "symfony/property-info": "<6.4" + }, + "require-dev": { + "phpstan/phpdoc-parser": "^1.0", + "symfony/dependency-injection": "^6.4|^7.0", + "symfony/property-info": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\TypeInfo\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mathias Arlaud", + "email": "mathias.arlaud@gmail.com" + }, + { + "name": "Baptiste LEDUC", + "email": "baptiste.leduc@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Extracts PHP types information.", + "homepage": "https://symfony.com/", + "keywords": [ + "PHPStan", + "phpdoc", + "symfony", + "type" + ], + "support": { + "source": "https://github.com/symfony/type-info/tree/v7.1.0" }, "funding": [ { @@ -6872,24 +7695,25 @@ "type": "tidelift" } ], - "time": "2023-07-25T15:08:44+00:00" + "time": "2024-05-02T10:19:13+00:00" }, { "name": "symfony/validator", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "616b39ffb22c1519f7fd2582b8052cde4c2d0b9f" + "reference": "ffcc8c56502f6adaeaf6307aef5b98b53a8d0326" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/616b39ffb22c1519f7fd2582b8052cde4c2d0b9f", - "reference": "616b39ffb22c1519f7fd2582b8052cde4c2d0b9f", + "url": "https://api.github.com/repos/symfony/validator/zipball/ffcc8c56502f6adaeaf6307aef5b98b53a8d0326", + "reference": "ffcc8c56502f6adaeaf6307aef5b98b53a8d0326", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-mbstring": "~1.0", "symfony/polyfill-php83": "^1.27", @@ -6903,7 +7727,7 @@ "symfony/http-kernel": "<6.4", "symfony/intl": "<6.4", "symfony/property-info": "<6.4", - "symfony/translation": "<6.4", + "symfony/translation": "<6.4.3|>=7.0,<7.0.3", "symfony/yaml": "<6.4" }, "require-dev": { @@ -6921,7 +7745,8 @@ "symfony/mime": "^6.4|^7.0", "symfony/property-access": "^6.4|^7.0", "symfony/property-info": "^6.4|^7.0", - "symfony/translation": "^6.4|^7.0", + "symfony/translation": "^6.4.3|^7.0.3", + "symfony/type-info": "^7.1", "symfony/yaml": "^6.4|^7.0" }, "type": "library", @@ -6950,7 +7775,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v7.0.0" + "source": "https://github.com/symfony/validator/tree/v7.1.0" }, "funding": [ { @@ -6966,20 +7791,20 @@ "type": "tidelift" } ], - "time": "2023-11-29T08:40:23+00:00" + "time": "2024-05-21T15:59:31+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "cf0220fc7607476fd0d001ab3ed9e830d1fdda56" + "reference": "595e4a4bc2118e7f4884315a684678b9403d44a6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/cf0220fc7607476fd0d001ab3ed9e830d1fdda56", - "reference": "cf0220fc7607476fd0d001ab3ed9e830d1fdda56", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/595e4a4bc2118e7f4884315a684678b9403d44a6", + "reference": "595e4a4bc2118e7f4884315a684678b9403d44a6", "shasum": "" }, "require": { @@ -7033,7 +7858,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.0.0" + "source": "https://github.com/symfony/var-dumper/tree/v7.1.0" }, "funding": [ { @@ -7049,20 +7874,20 @@ "type": "tidelift" } ], - "time": "2023-11-27T12:39:18+00:00" + "time": "2024-05-28T06:54:05+00:00" }, { "name": "symfony/web-link", - "version": "v7.0.0", + "version": "v7.1.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "378bcc80b48c51e32bf121bee684183ff879a62f" + "reference": "3953f0a3f0e371f2585337a95a1998cb6aacce8e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/378bcc80b48c51e32bf121bee684183ff879a62f", - "reference": "378bcc80b48c51e32bf121bee684183ff879a62f", + "url": "https://api.github.com/repos/symfony/web-link/zipball/3953f0a3f0e371f2585337a95a1998cb6aacce8e", + "reference": "3953f0a3f0e371f2585337a95a1998cb6aacce8e", "shasum": "" }, "require": { @@ -7116,7 +7941,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v7.0.0" + "source": "https://github.com/symfony/web-link/tree/v7.1.0" }, "funding": [ { @@ -7132,20 +7957,20 @@ "type": "tidelift" } ], - "time": "2023-07-25T09:50:29+00:00" + "time": "2024-04-18T09:32:20+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.2", + "version": "1.2.3", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96" + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b2ad5003ca10d4ee50a12da31de12a5774ba6b96", - "reference": "b2ad5003ca10d4ee50a12da31de12a5774ba6b96", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", "shasum": "" }, "require": { @@ -7174,7 +7999,7 @@ "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", "support": { "issues": "https://github.com/theseer/tokenizer/issues", - "source": "https://github.com/theseer/tokenizer/tree/1.2.2" + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" }, "funding": [ { @@ -7182,7 +8007,7 @@ "type": "github" } ], - "time": "2023-11-20T00:12:19+00:00" + "time": "2024-03-03T12:36:25+00:00" }, { "name": "webmozart/assert", diff --git a/scoper.inc.php b/scoper.inc.php index f7f60184..c404d2b7 100644 --- a/scoper.inc.php +++ b/scoper.inc.php @@ -13,8 +13,8 @@ return [ 'whitelist' => [ - \ApiPlatform\Core\Annotation\ApiProperty::class, - \ApiPlatform\Core\Annotation\ApiResource::class, + ApiPlatform\Core\Annotation\ApiProperty::class, + ApiPlatform\Core\Annotation\ApiResource::class, ], 'patchers' => [ function (string $filePath, string $prefix, string $content): string { diff --git a/src/FilesGenerator.php b/src/FilesGenerator.php index a2c17ac6..89655cc8 100644 --- a/src/FilesGenerator.php +++ b/src/FilesGenerator.php @@ -149,7 +149,7 @@ private function fixCs(array $files): void // to keep compatibility with both versions of php-cs-fixer: 2.x and 3.x // ruleset object must be created depending on which class is available - $rulesetClass = class_exists(LegacyRuleSet::class) ? LegacyRuleSet::class : Ruleset::class; + $rulesetClass = class_exists(LegacyRuleSet::class) ? LegacyRuleSet::class : RuleSet::class; $fixers = (new FixerFactory()) ->registerBuiltInFixers() ->useRuleSet(new $rulesetClass([ // @phpstan-ignore-line diff --git a/src/Model/Attribute.php b/src/Model/Attribute.php index 290f2f1a..cdb47f8b 100644 --- a/src/Model/Attribute.php +++ b/src/Model/Attribute.php @@ -28,14 +28,14 @@ final class Attribute /** * If this attribute can be appended if a same one has not previously been generated or if the same one is not mergeable? * - * @see \ApiPlatform\SchemaGenerator\Model\AddAttributeTrait + * @see AddAttributeTrait */ public bool $append = true; /** * If this attribute mergeable with the next one? * - * @see \ApiPlatform\SchemaGenerator\Model\AddAttributeTrait + * @see AddAttributeTrait */ public bool $mergeable = true; diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 7d892af5..ae1282c5 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -109,7 +109,7 @@ public function interfaceNamespace(): ?string return $this->interface ? $this->interface->namespace() : null; } - public function interfaceToNetteFile(string $fileHeader = null): PhpFile + public function interfaceToNetteFile(?string $fileHeader = null): PhpFile { if (!$this->interface) { throw new \LogicException(sprintf("'%s' has no interface attached.", $this->name)); @@ -214,7 +214,7 @@ public function isParentEnum(): bool /** * @param Configuration $config */ - public function toNetteFile(array $config, InflectorInterface $inflector, PhpFile $file = null): PhpFile + public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFile $file = null): PhpFile { $useDoctrineCollections = $config['doctrine']['useCollection']; $useAccessors = $config['accessorMethods']; diff --git a/src/Model/Interface_.php b/src/Model/Interface_.php index 6edee947..287d5e43 100644 --- a/src/Model/Interface_.php +++ b/src/Model/Interface_.php @@ -48,7 +48,7 @@ public function addAnnotation(string $annotation): self return $this; } - public function toNetteFile(string $fileHeader = null): PhpFile + public function toNetteFile(?string $fileHeader = null): PhpFile { $file = (new PhpFile()) ->setStrictTypes(true) diff --git a/src/Model/Property.php b/src/Model/Property.php index c44f1944..9083c338 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -140,7 +140,7 @@ public function markAsCustom(): self return $this; } - public function toNetteProperty(PhpNamespace $namespace, string $visibility = null, bool $useDoctrineCollections = true, NetteProperty $property = null): NetteProperty + public function toNetteProperty(PhpNamespace $namespace, ?string $visibility = null, bool $useDoctrineCollections = true, ?NetteProperty $property = null): NetteProperty { $property ??= new NetteProperty($this->name); diff --git a/src/Model/Type/ArrayType.php b/src/Model/Type/ArrayType.php index 4413373c..f6e496d1 100644 --- a/src/Model/Type/ArrayType.php +++ b/src/Model/Type/ArrayType.php @@ -17,7 +17,7 @@ final class ArrayType implements Type { public ?Type $type; - public function __construct(Type $type = null) + public function __construct(?Type $type = null) { $this->type = $type; } diff --git a/src/Model/Use_.php b/src/Model/Use_.php index e6c8483c..849146a7 100644 --- a/src/Model/Use_.php +++ b/src/Model/Use_.php @@ -19,7 +19,7 @@ final class Use_ private ?string $alias; - public function __construct(string $name, string $alias = null) + public function __construct(string $name, ?string $alias = null) { $this->name = $name; $this->alias = $alias; diff --git a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php index 2ba458e9..830f2c77 100644 --- a/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/IdPropertyGenerator.php @@ -24,12 +24,12 @@ final class IdPropertyGenerator implements IdPropertyGeneratorInterface { private IdPropertyGeneratorInterface $idPropertyGenerator; - public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator = null) + public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = null) { $this->idPropertyGenerator = $idPropertyGenerator ?? new CommonIdPropertyGenerator(); } - public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property { $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new OpenApiProperty('id')); diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index d7ab22de..94bcf8d3 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -33,7 +33,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface private PropertyGeneratorInterface $propertyGenerator; - public function __construct(PropertyGeneratorInterface $propertyGenerator = null) + public function __construct(?PropertyGeneratorInterface $propertyGenerator = null) { $this->propertyGenerator = $propertyGenerator ?? new CommonPropertyGenerator(); } @@ -42,7 +42,7 @@ public function __construct(PropertyGeneratorInterface $propertyGenerator = null * @param Configuration $config * @param array{schema: Schema, property: Schema} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property { $schema = $context['schema']; $schemaProperty = $context['property']; @@ -110,6 +110,11 @@ private function getType(Schema $schemaProperty, bool $inComposite = false): ?Ty return new ArrayType($schemaProperty->items instanceof Schema ? $this->getType($schemaProperty->items) : null); } + if (\is_array($schemaProperty->type)) { + // TODO: add support for OpenAPI 3.1 + return null; + } + $type = $schemaProperty->type; $format = $schemaProperty->format; diff --git a/src/PropertyGenerator/IdPropertyGenerator.php b/src/PropertyGenerator/IdPropertyGenerator.php index 2f09b9bd..2559f7b1 100644 --- a/src/PropertyGenerator/IdPropertyGenerator.php +++ b/src/PropertyGenerator/IdPropertyGenerator.php @@ -19,7 +19,7 @@ final class IdPropertyGenerator implements IdPropertyGeneratorInterface { - public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property { if (!$property) { throw new \LogicException('A property must be given.'); diff --git a/src/PropertyGenerator/IdPropertyGeneratorInterface.php b/src/PropertyGenerator/IdPropertyGeneratorInterface.php index df7c1d20..77b16ca8 100644 --- a/src/PropertyGenerator/IdPropertyGeneratorInterface.php +++ b/src/PropertyGenerator/IdPropertyGeneratorInterface.php @@ -17,5 +17,5 @@ interface IdPropertyGeneratorInterface { - public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property; + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property; } diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index e59ad5d8..0df61662 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -22,7 +22,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface * @param Configuration $config * @param array{} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property { if (!$property) { throw new \LogicException('A property must be given.'); diff --git a/src/PropertyGenerator/PropertyGeneratorInterface.php b/src/PropertyGenerator/PropertyGeneratorInterface.php index c1025284..e82c13f0 100644 --- a/src/PropertyGenerator/PropertyGeneratorInterface.php +++ b/src/PropertyGenerator/PropertyGeneratorInterface.php @@ -28,6 +28,6 @@ public function __invoke( Class_ $class, array $context, bool $isCustom = false, - Property $property = null + ?Property $property = null ): ?Property; } diff --git a/src/Schema/Model/Class_.php b/src/Schema/Model/Class_.php index 6d6a49b7..844c4e60 100644 --- a/src/Schema/Model/Class_.php +++ b/src/Schema/Model/Class_.php @@ -66,7 +66,7 @@ public function getSubClassOf(): array return array_filter($this->resource->all('rdfs:subClassOf', 'resource'), static fn (RdfResource $resource) => !$resource->isBNode()); } - public function isEnum(RdfResource $resource = null): bool + public function isEnum(?RdfResource $resource = null): bool { $parentClass = ($resource ?? $this->resource)->get('rdfs:subClassOf'); diff --git a/src/Schema/PropertyGenerator/IdPropertyGenerator.php b/src/Schema/PropertyGenerator/IdPropertyGenerator.php index 00413794..93cd83a7 100644 --- a/src/Schema/PropertyGenerator/IdPropertyGenerator.php +++ b/src/Schema/PropertyGenerator/IdPropertyGenerator.php @@ -25,12 +25,12 @@ final class IdPropertyGenerator implements IdPropertyGeneratorInterface { private IdPropertyGeneratorInterface $idPropertyGenerator; - public function __construct(IdPropertyGeneratorInterface $idPropertyGenerator = null) + public function __construct(?IdPropertyGeneratorInterface $idPropertyGenerator = null) { $this->idPropertyGenerator = $idPropertyGenerator ?? new CommonIdPropertyGenerator(); } - public function __invoke(string $generationStrategy, bool $supportsWritableId, Property $property = null): Property + public function __invoke(string $generationStrategy, bool $supportsWritableId, ?Property $property = null): Property { $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new SchemaProperty('id')); diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 47e2634b..23b4d304 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -42,7 +42,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface private TypeConverter $typeConverter; private PropertyGeneratorInterface $propertyGenerator; - public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, PropertyGeneratorInterface $propertyGenerator = null) + public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConverter $typeConverter, PhpTypeConverterInterface $phpTypeConverter, ?PropertyGeneratorInterface $propertyGenerator = null) { $this->goodRelationsBridge = $goodRelationsBridge; $this->typeConverter = $typeConverter; @@ -59,7 +59,7 @@ public function __construct(GoodRelationsBridge $goodRelationsBridge, TypeConver * property: RdfResource * } $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property { $type = $context['type']; $typeConfig = $context['typeConfig']; diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index 3195e7a1..ff9a3b50 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -36,7 +36,7 @@ final class SchemaGeneratorConfiguration implements ConfigurationInterface private ?string $defaultPrefix; - public function __construct(string $defaultPrefix = null) + public function __construct(?string $defaultPrefix = null) { $this->defaultPrefix = $defaultPrefix; } diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 7547dc47..5dd128c3 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -58,8 +58,8 @@ class TypesGenerator * @var string[] the RDF types of classes in the vocabs */ public static array $classTypes = [ - 'rdfs:Class', - 'owl:Class', + 'rdfs:Class', + 'owl:Class', ]; /** @@ -75,8 +75,8 @@ class TypesGenerator * @var string[] the RDF types of domains in the vocabs */ public static array $domainProperties = [ - 'schema:domainIncludes', - 'rdfs:domain', + 'schema:domainIncludes', + 'rdfs:domain', ]; private PhpTypeConverterInterface $phpTypeConverter; diff --git a/tests/ClassMutator/ClassParentMutatorTest.php b/tests/ClassMutator/ClassParentMutatorTest.php index 2d12ab7f..82598fbc 100644 --- a/tests/ClassMutator/ClassParentMutatorTest.php +++ b/tests/ClassMutator/ClassParentMutatorTest.php @@ -53,7 +53,7 @@ protected function setUp(): void /** * @dataProvider provideInvokeTestCases */ - public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, string $loggerMessage = null): void + public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?string $loggerMessage = null): void { if ($loggerMessage) { $this->loggerProphecy->info($loggerMessage)->shouldBeCalled(); diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index 8cbe5003..e387c5bb 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -75,7 +75,7 @@ protected function setUp(): void /** * @dataProvider provideInvokeTestCases */ - public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, RdfGraph &$graph = null, string $loggerMessage = null): void + public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?RdfGraph &$graph = null, ?string $loggerMessage = null): void { if ($graph) { $this->graph = $graph; From ea14c3b5c52a54e3b4b055a6d5da5a2397a1b3e0 Mon Sep 17 00:00:00 2001 From: gasparakos Date: Wed, 23 Oct 2024 21:32:16 +0200 Subject: [PATCH 253/258] fix: replace of GoodRelations OWL file (#431) * Replace inactive URL in GOOD_RELATIONS_URI Fix for https://github.com/api-platform/schema-generator/issues/428 * Fix test URI --- src/SchemaGeneratorConfiguration.php | 2 +- tests/Command/DumpConfigurationTest.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/SchemaGeneratorConfiguration.php b/src/SchemaGeneratorConfiguration.php index ff9a3b50..cb512079 100644 --- a/src/SchemaGeneratorConfiguration.php +++ b/src/SchemaGeneratorConfiguration.php @@ -31,7 +31,7 @@ final class SchemaGeneratorConfiguration implements ConfigurationInterface { public const SCHEMA_ORG_URI = 'https://schema.org/version/latest/schemaorg-current-https.rdf'; - public const GOOD_RELATIONS_URI = 'https://archive.org/services/purl/goodrelations/v1.owl'; + public const GOOD_RELATIONS_URI = 'https://www.heppnetz.de/ontologies/goodrelations/v1.owl'; public const SCHEMA_ORG_NAMESPACE = 'https://schema.org/'; private ?string $defaultPrefix; diff --git a/tests/Command/DumpConfigurationTest.php b/tests/Command/DumpConfigurationTest.php index feec7860..f8ce7614 100644 --- a/tests/Command/DumpConfigurationTest.php +++ b/tests/Command/DumpConfigurationTest.php @@ -56,10 +56,10 @@ public function testDumpConfiguration(): void relations: # OWL relation URIs containing cardinality information in the GoodRelations format - uris: # Example: 'https://archive.org/services/purl/goodrelations/v1.owl' + uris: # Example: 'https://www.heppnetz.de/ontologies/goodrelations/v1.owl' # Default: - - https://archive.org/services/purl/goodrelations/v1.owl + - https://www.heppnetz.de/ontologies/goodrelations/v1.owl # The default cardinality to use when it cannot be extracted defaultCardinality: (1..1) # One of "(0..1)"; "(0..*)"; "(1..1)"; "(1..*)"; "(*..0)"; "(*..1)"; "(*..*)" From ff9c3315d343c3765cc0ece2871c4b840357d10a Mon Sep 17 00:00:00 2001 From: soyuka Date: Tue, 28 Jan 2025 09:13:33 +0100 Subject: [PATCH 254/258] docs: changelog v5.2.3 --- CHANGELOG.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 78e73396..68c7891e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,12 @@ # Changelog +## 5.3.3 + +* [ea14c3b](https://github.com/api-platform/core/commit/ea14c3b5c52a54e3b4b055a6d5da5a2397a1b3e0) fix: replace of GoodRelations OWL file (#431) +* [1bb5502](https://github.com/api-platform/core/commit/1bb5502b9b7b0cb767f7fbb16f80934bb57fbbdd) chore: update deps (#426) +* [997f6f8](https://github.com/api-platform/core/commit/997f6f811faa75006aeff72cec26fe291bb8eaab) ci: upgrade deps and use PHP 8.3 (#420) +* [8d683f2](https://github.com/api-platform/core/commit/8d683f2504450a39ac787d8b4f7e5710d15dd129) feat: allow symfony 7 + ## 5.2.2 * fix: detect enum detection when an ancestor is an enum From d4183e22cf23c46fabc3b3a39c6137ec75a16d16 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 30 Jan 2025 15:58:39 +0100 Subject: [PATCH 255/258] chore: fix CS (#432) --- .../PhpDocAnnotationGenerator.php | 22 +++++++++---------- .../ApiPlatformCoreAttributeGenerator.php | 4 ++-- .../ConstraintAttributeGenerator.php | 4 ++-- .../DoctrineMongoDBAttributeGenerator.php | 2 +- .../DoctrineOrmAttributeGenerator.php | 14 ++++++------ src/ClassMutator/AnnotationsAppender.php | 4 ++-- src/ClassMutator/AttributeAppender.php | 4 ++-- src/ClassMutator/ClassInterfaceMutator.php | 2 +- src/ClassMutator/ClassParentMutator.php | 2 +- src/ClassMutator/ClassPropertiesAppender.php | 6 ++--- src/Command/GenerateCommand.php | 16 +++++++------- src/FilesGenerator.php | 10 ++++----- src/GoodRelationsBridge.php | 4 ++-- src/Model/Class_.php | 2 +- src/Model/Property.php | 12 +++++----- src/OpenApi/ClassGenerator.php | 12 +++++----- src/OpenApi/Generator.php | 2 +- .../PropertyGenerator/PropertyGenerator.php | 2 +- src/PhpTypeConverter.php | 2 +- .../PropertyGeneratorInterface.php | 2 +- .../PropertyGenerator/IdPropertyGenerator.php | 2 +- .../PropertyGenerator/PropertyGenerator.php | 10 ++++----- src/TypesGenerator.php | 4 ++-- 23 files changed, 72 insertions(+), 72 deletions(-) diff --git a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php index ba42d9e5..4cfe6390 100644 --- a/src/AnnotationGenerator/PhpDocAnnotationGenerator.php +++ b/src/AnnotationGenerator/PhpDocAnnotationGenerator.php @@ -51,7 +51,7 @@ public function generateInterfaceAnnotations(Class_ $class): array public function generateConstantAnnotations(Constant $constant): array { $annotations = $this->formatDoc($constant->comment(), true); - $annotations[0] = sprintf('@var string %s', $this->escapePhpDoc($annotations[0])); + $annotations[0] = \sprintf('@var string %s', $this->escapePhpDoc($annotations[0])); return $annotations; } @@ -62,14 +62,14 @@ public function generatePropertyAnnotations(Property $property, string $classNam $annotations = []; if ($this->isDocUseful($property) && $phpDocType = $this->toPhpDocType($property)) { - $annotations[] = sprintf('@var %s %s', $phpDocType, $this->escapePhpDoc($description[0])); + $annotations[] = \sprintf('@var %s %s', $phpDocType, $this->escapePhpDoc($description[0])); } else { $annotations = $description; $annotations[] = ''; } if (null !== $property->rdfType()) { - $annotations[] = sprintf('@see %s', $property->rdfType()); + $annotations[] = \sprintf('@see %s', $property->rdfType()); } $annotations[] = ''; @@ -83,7 +83,7 @@ public function generateGetterAnnotations(Property $property): array return []; } - return [sprintf('@return %s', $this->toPhpDocType($property))]; + return [\sprintf('@return %s', $this->toPhpDocType($property))]; } public function generateSetterAnnotations(Property $property): array @@ -92,7 +92,7 @@ public function generateSetterAnnotations(Property $property): array return []; } - return [sprintf('@param %s $%s', $this->toPhpDocType($property), $property->name())]; + return [\sprintf('@param %s $%s', $this->toPhpDocType($property), $property->name())]; } public function generateAdderAnnotations(Property $property): array @@ -101,7 +101,7 @@ public function generateAdderAnnotations(Property $property): array return []; } - return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; + return [\sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; } public function generateRemoverAnnotations(Property $property): array @@ -110,7 +110,7 @@ public function generateRemoverAnnotations(Property $property): array return []; } - return [sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; + return [\sprintf('@param %s $%s', $this->toPhpDocType($property, true), $this->inflector->singularize($property->name())[0])]; } private function isDocUseful(Property $property, bool $adderOrRemover = false): bool @@ -138,12 +138,12 @@ private function generateDoc(Class_ $class, bool $interface = false): array $annotations[] = ''; } if ($class->rdfType()) { - $annotations[] = sprintf('@see %s', $class->rdfType()); + $annotations[] = \sprintf('@see %s', $class->rdfType()); } } if ($this->config['author']) { - $annotations[] = sprintf('@author %s', $this->config['author']); + $annotations[] = \sprintf('@author %s', $this->config['author']); } return $annotations; @@ -197,10 +197,10 @@ protected function toPhpDocType(Property $property, bool $adderOrRemover = false } if ($this->config['doctrine']['useCollection']) { - return sprintf('Collection<%s>%s', $phpDocType, $suffix); + return \sprintf('Collection<%s>%s', $phpDocType, $suffix); } - return sprintf('%s[]%s', $phpDocType, $suffix); + return \sprintf('%s[]%s', $phpDocType, $suffix); } private function escapePhpDoc(string $text): string diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 35e4d7e8..452eccb7 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -73,7 +73,7 @@ public function generateClassAttributes(Class_ $class): array } $targetArguments[$method] = $methodArguments; } - $arguments[sprintf('%sOperations', $operationTarget)] = $targetArguments; + $arguments[\sprintf('%sOperations', $operationTarget)] = $targetArguments; } } else { $arguments['operations'] = []; @@ -85,7 +85,7 @@ public function generateClassAttributes(Class_ $class): array unset($methodConfig['class']); } - $arguments['operations'][] = new Literal(sprintf('new %s(...?:)', + $arguments['operations'][] = new Literal(\sprintf('new %s(...?:)', $operationMetadataClass, ), [$methodConfig ?? []]); } diff --git a/src/AttributeGenerator/ConstraintAttributeGenerator.php b/src/AttributeGenerator/ConstraintAttributeGenerator.php index 6c8e18cd..a11c8fe4 100644 --- a/src/AttributeGenerator/ConstraintAttributeGenerator.php +++ b/src/AttributeGenerator/ConstraintAttributeGenerator.php @@ -69,7 +69,7 @@ public function generatePropertyAttributes(Property $property, string $className } if ($property->isEnum && $property->reference) { - $args = ['callback' => [new Literal(sprintf('%s::class', $property->reference->name())), 'toArray']]; + $args = ['callback' => [new Literal(\sprintf('%s::class', $property->reference->name())), 'toArray']]; if ($property->isArray()) { $args['multiple'] = true; @@ -96,7 +96,7 @@ public function generateUses(Class_ $class): array $enumName = $property->reference->name(); $enumClass = $this->classes[$enumName]; $enumNamespace = $enumClass->namespace ?? $this->config['namespaces']['enum']; - $use = new Use_(sprintf('%s\%s', $enumNamespace, $enumName)); + $use = new Use_(\sprintf('%s\%s', $enumNamespace, $enumName)); if (!\in_array($use, $uses, true)) { $uses[] = $use; diff --git a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php index 1ee8ae89..ed0ba33e 100644 --- a/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineMongoDBAttributeGenerator.php @@ -61,7 +61,7 @@ public function generateClassAttributes(Class_ $class): array $attributes[] = new Attribute('MongoDB\Document'); $attributes[] = new Attribute('MongoDB\InheritanceType', [\in_array($this->config['doctrine']['inheritanceType'], ['SINGLE_COLLECTION', 'COLLECTION_PER_CLASS', 'NONE'], true) ? $this->config['doctrine']['inheritanceType'] : 'SINGLE_COLLECTION']); $attributes[] = new Attribute('MongoDB\DiscriminatorField', ['discr']); - $attributes[] = new Attribute('MongoDB\DiscriminatorMap', [array_reduce($mapNames, fn (array $map, string $mapName) => $map + [u($mapName)->camel()->toString() => new Literal(sprintf('%s::class', $mapName))], [])]); + $attributes[] = new Attribute('MongoDB\DiscriminatorMap', [array_reduce($mapNames, fn (array $map, string $mapName) => $map + [u($mapName)->camel()->toString() => new Literal(\sprintf('%s::class', $mapName))], [])]); } else { $attributes[] = new Attribute('MongoDB\Document'); } diff --git a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php index 0959d109..72938ded 100644 --- a/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php +++ b/src/AttributeGenerator/DoctrineOrmAttributeGenerator.php @@ -69,7 +69,7 @@ public function generateClassAttributes(Class_ $class): array $attributes[] = new Attribute('ORM\Entity'); $attributes[] = new Attribute('ORM\InheritanceType', [\in_array($this->config['doctrine']['inheritanceType'], ['JOINED', 'SINGLE_TABLE', 'TABLE_PER_CLASS', 'NONE'], true) ? $this->config['doctrine']['inheritanceType'] : 'JOINED']); $attributes[] = new Attribute('ORM\DiscriminatorColumn', ['name' => 'discr']); - $attributes[] = new Attribute('ORM\DiscriminatorMap', [array_reduce($mapNames, fn (array $map, string $mapName) => $map + [u($mapName)->camel()->toString() => new Literal(sprintf('%s::class', $mapName))], [])]); + $attributes[] = new Attribute('ORM\DiscriminatorMap', [array_reduce($mapNames, fn (array $map, string $mapName) => $map + [u($mapName)->camel()->toString() => new Literal(\sprintf('%s::class', $mapName))], [])]); } else { $attributes[] = new Attribute('ORM\Entity'); } @@ -79,7 +79,7 @@ public function generateClassAttributes(Class_ $class): array continue; } - $attributes[] = new Attribute('ORM\Table', ['name' => sprintf('`%s`', $this->generateIdentifierName($class->name(), 'table', $this->config))]); + $attributes[] = new Attribute('ORM\Table', ['name' => \sprintf('`%s`', $this->generateIdentifierName($class->name(), 'table', $this->config))]); } return $attributes; @@ -150,7 +150,7 @@ public function generatePropertyAttributes(Property $property, string $className foreach (self::RESERVED_KEYWORDS as $keyword) { if (0 === strcasecmp($keyword, $property->name())) { - $args['name'] = sprintf('`%s`', $property->name()); + $args['name'] = \sprintf('`%s`', $property->name()); break; } } @@ -281,16 +281,16 @@ private function getRelationName(Property $property): ?string if (null !== $reference->interfaceName()) { if (isset($this->config['types'][$reference->name()]['namespaces']['interface'])) { - return sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['interface'], $reference->interfaceName()); + return \sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['interface'], $reference->interfaceName()); } - return sprintf('%s\\%s', $this->config['namespaces']['interface'], $reference->interfaceName()); + return \sprintf('%s\\%s', $this->config['namespaces']['interface'], $reference->interfaceName()); } if (isset($this->config['types'][$reference->name()]['namespaces']['class'])) { - return sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['class'], $reference->name()); + return \sprintf('%s\\%s', $this->config['types'][$reference->name()]['namespaces']['class'], $reference->name()); } - return sprintf('%s\\%s', $this->config['namespaces']['entity'], $reference->name()); + return \sprintf('%s\\%s', $this->config['namespaces']['entity'], $reference->name()); } } diff --git a/src/ClassMutator/AnnotationsAppender.php b/src/ClassMutator/AnnotationsAppender.php index fc074e65..a02b9f78 100644 --- a/src/ClassMutator/AnnotationsAppender.php +++ b/src/ClassMutator/AnnotationsAppender.php @@ -58,12 +58,12 @@ private function generateClassUses(Class_ $class): void { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace) { - $class->addUse(new Use_(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName()))); + $class->addUse(new Use_(\sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName()))); } foreach ($class->properties() as $property) { if ($property->reference && $property->reference->interfaceName()) { - $class->addUse(new Use_(sprintf( + $class->addUse(new Use_(\sprintf( '%s\\%s', $property->reference->interfaceNamespace(), $property->reference->interfaceName() diff --git a/src/ClassMutator/AttributeAppender.php b/src/ClassMutator/AttributeAppender.php index ce3ac08a..3388f150 100644 --- a/src/ClassMutator/AttributeAppender.php +++ b/src/ClassMutator/AttributeAppender.php @@ -53,12 +53,12 @@ private function generateClassUses(Class_ $class): void { $interfaceNamespace = isset($this->classes[$class->name()]) ? $this->classes[$class->name()]->interfaceNamespace() : null; if ($interfaceNamespace && $class->interfaceNamespace() !== $class->namespace) { - $class->addUse(new Use_(sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName()))); + $class->addUse(new Use_(\sprintf('%s\\%s', $class->interfaceNamespace(), $class->interfaceName()))); } foreach ($class->properties() as $property) { if ($property->reference && $property->reference->interfaceName()) { - $class->addUse(new Use_(sprintf( + $class->addUse(new Use_(\sprintf( '%s\\%s', $property->reference->interfaceNamespace(), $property->reference->interfaceName() diff --git a/src/ClassMutator/ClassInterfaceMutator.php b/src/ClassMutator/ClassInterfaceMutator.php index 8b315afd..f215fa2b 100644 --- a/src/ClassMutator/ClassInterfaceMutator.php +++ b/src/ClassMutator/ClassInterfaceMutator.php @@ -30,6 +30,6 @@ public function __construct(string $desiredNamespace) */ public function __invoke(Class_ $class, array $context): void { - $class->interface = new Interface_(sprintf('%sInterface', $class->name()), $this->desiredNamespace); + $class->interface = new Interface_(\sprintf('%sInterface', $class->name()), $this->desiredNamespace); } } diff --git a/src/ClassMutator/ClassParentMutator.php b/src/ClassMutator/ClassParentMutator.php index 9d05a4f6..a90d1735 100644 --- a/src/ClassMutator/ClassParentMutator.php +++ b/src/ClassMutator/ClassParentMutator.php @@ -50,7 +50,7 @@ public function __invoke(Class_ $class, array $context): void if (null === $class->parent() && $subclassOf = $class->getSubClassOf()) { if (\count($subclassOf) > 1) { - $this->logger ? $this->logger->info(sprintf('The type "%s" has several supertypes. Using the first one.', $class->rdfType())) : null; + $this->logger ? $this->logger->info(\sprintf('The type "%s" has several supertypes. Using the first one.', $class->rdfType())) : null; } if (\is_string($parentLocalName = $subclassOf[0]->localName())) { diff --git a/src/ClassMutator/ClassPropertiesAppender.php b/src/ClassMutator/ClassPropertiesAppender.php index 988d135c..78d04cda 100644 --- a/src/ClassMutator/ClassPropertiesAppender.php +++ b/src/ClassMutator/ClassPropertiesAppender.php @@ -84,7 +84,7 @@ public function __invoke(Class_ $class, array $context): void } else { $remainingProperties = $typeConfig['properties'] ?? []; if (!isset($this->propertiesMap[$class->rdfType()])) { - $this->logger ? $this->logger->warning(sprintf('Properties for "%s" not found in the map.', $class->rdfType())) : null; + $this->logger ? $this->logger->warning(\sprintf('Properties for "%s" not found in the map.', $class->rdfType())) : null; } // All properties foreach ($this->propertiesMap[$class->rdfType()] ?? [] as $property) { @@ -93,7 +93,7 @@ public function __invoke(Class_ $class, array $context): void } if ($property->hasProperty(self::SCHEMA_ORG_SUPERSEDED_BY)) { $supersededBy = $property->get(self::SCHEMA_ORG_SUPERSEDED_BY); - $this->logger ? $this->logger->info(sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())) : null; + $this->logger ? $this->logger->info(\sprintf('The property "%s" is superseded by "%s". Using the superseding property.', $property->getUri(), $supersededBy->getUri())) : null; } else { $this->generateField($this->config, $class, $class->resource(), $typeConfig, $cardinalities, $property); } @@ -117,7 +117,7 @@ public function __invoke(Class_ $class, array $context): void */ private function generateCustomField(string $propertyName, RdfResource $type, ?array $typeConfig, array $cardinalities, SchemaClass $class, array $config): void { - $this->logger ? $this->logger->info(sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())) : null; + $this->logger ? $this->logger->info(\sprintf('The property "%s" (type "%s") is a custom property.', $propertyName, $type->getUri())) : null; $customResource = new RdfResource('_:'.$propertyName, new RdfGraph()); $customResource->add('rdfs:range', $type); diff --git a/src/Command/GenerateCommand.php b/src/Command/GenerateCommand.php index 35f55fec..40feae8b 100644 --- a/src/Command/GenerateCommand.php +++ b/src/Command/GenerateCommand.php @@ -80,7 +80,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int if ($dir = realpath($outputDir)) { if (!is_dir($dir)) { if (!$defaultOutput) { - throw new \InvalidArgumentException(sprintf('The file "%s" is not a directory.', $dir)); + throw new \InvalidArgumentException(\sprintf('The file "%s" is not a directory.', $dir)); } $dir = $defaultOutput; @@ -88,7 +88,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int } if (!is_writable($dir)) { - throw new \InvalidArgumentException(sprintf('The "%s" directory is not writable.', $dir)); + throw new \InvalidArgumentException(\sprintf('The "%s" directory is not writable.', $dir)); } $outputDir = $dir; @@ -96,29 +96,29 @@ protected function execute(InputInterface $input, OutputInterface $output): int (new Filesystem())->mkdir($outputDir); $outputDir = realpath($outputDir); if (!$outputDir) { - throw new \InvalidArgumentException(sprintf('The "%s" directory cannot be created.', $outputDir)); + throw new \InvalidArgumentException(\sprintf('The "%s" directory cannot be created.', $outputDir)); } } if ($configArgument) { if (!file_exists($configArgument)) { - throw new \InvalidArgumentException(sprintf('The file "%s" doesn\'t exist.', $configArgument)); + throw new \InvalidArgumentException(\sprintf('The file "%s" doesn\'t exist.', $configArgument)); } if (!is_file($configArgument)) { - throw new \InvalidArgumentException(sprintf('"%s" isn\'t a file.', $configArgument)); + throw new \InvalidArgumentException(\sprintf('"%s" isn\'t a file.', $configArgument)); } if (!is_readable($configArgument)) { - throw new \InvalidArgumentException(sprintf('The file "%s" isn\'t readable.', $configArgument)); + throw new \InvalidArgumentException(\sprintf('The file "%s" isn\'t readable.', $configArgument)); } if (false === ($configContent = file_get_contents($configArgument))) { - throw new \RuntimeException(sprintf('Cannot read "%s" content.', $configArgument)); + throw new \RuntimeException(\sprintf('Cannot read "%s" content.', $configArgument)); } } elseif (is_readable(self::DEFAULT_CONFIG_FILE)) { if (false === ($configContent = file_get_contents(self::DEFAULT_CONFIG_FILE))) { - throw new \RuntimeException(sprintf('Cannot read "%s" content.', self::DEFAULT_CONFIG_FILE)); + throw new \RuntimeException(\sprintf('Cannot read "%s" content.', self::DEFAULT_CONFIG_FILE)); } } else { if (!$io->askQuestion(new ConfirmationQuestion('Your project has no config file. The entire vocabulary will be imported.'.\PHP_EOL.'Continue?', false))) { diff --git a/src/FilesGenerator.php b/src/FilesGenerator.php index 89655cc8..e35289bd 100644 --- a/src/FilesGenerator.php +++ b/src/FilesGenerator.php @@ -65,14 +65,14 @@ public function generate(array $classes, array $config): void $classDir = $this->namespaceToDir($class->namespace, $config); $this->filesystem->mkdir($classDir); - $path = sprintf('%s%s.php', $classDir, $className); + $path = \sprintf('%s%s.php', $classDir, $className); $file = null; if (file_exists($path) && is_file($path) && is_readable($path) && $fileContent = file_get_contents($path)) { - $choice = $this->io->askQuestion(new ChoiceQuestion(sprintf('File "%s" already exists, keep your changes and update it (use) or overwrite it (overwrite)?', $path), ['use', 'overwrite'], 0)); + $choice = $this->io->askQuestion(new ChoiceQuestion(\sprintf('File "%s" already exists, keep your changes and update it (use) or overwrite it (overwrite)?', $path), ['use', 'overwrite'], 0)); if ('use' === $choice) { $file = PhpFile::fromCode($fileContent); - $this->logger ? $this->logger->info(sprintf('Using "%s" as base file.', $path)) : null; + $this->logger ? $this->logger->info(\sprintf('Using "%s" as base file.', $path)) : null; } } @@ -88,7 +88,7 @@ public function generate(array $classes, array $config): void $interfaceDir = $this->namespaceToDir($class->interfaceNamespace(), $config); $this->filesystem->mkdir($interfaceDir); - $path = sprintf('%s%s.php', $interfaceDir, $class->interfaceName()); + $path = \sprintf('%s%s.php', $interfaceDir, $class->interfaceName()); $generatedFiles[] = $path; file_put_contents($path, $this->printer->printFile($class->interfaceToNetteFile($config['header'] ?? null))); @@ -132,7 +132,7 @@ private function namespaceToDir(string $namespace, array $config): string $namespace = substr($namespace, \strlen($prefix)); } - return sprintf('%s/%s/', $config['output'], str_replace('\\', '/', $namespace)); + return \sprintf('%s/%s/', $config['output'], str_replace('\\', '/', $namespace)); } /** diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index 32aebcbb..e1d502b6 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -87,7 +87,7 @@ public function __construct(array $relations) public function exists(string $id): bool { foreach ($this->relations as $relation) { - $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]', $this->getPropertyUrl($id))); + $result = $relation->xpath(\sprintf('//*[@rdf:about="%s"]', $this->getPropertyUrl($id))); if (!empty($result)) { return true; } @@ -104,7 +104,7 @@ public function exists(string $id): bool public function extractCardinality(string $id) { foreach ($this->relations as $relation) { - $result = $relation->xpath(sprintf('//*[@rdf:about="%s"]/rdfs:label', $this->getPropertyUrl($id))); + $result = $relation->xpath(\sprintf('//*[@rdf:about="%s"]/rdfs:label', $this->getPropertyUrl($id))); if (!$result) { continue; } diff --git a/src/Model/Class_.php b/src/Model/Class_.php index ae1282c5..6d58bbb5 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -112,7 +112,7 @@ public function interfaceNamespace(): ?string public function interfaceToNetteFile(?string $fileHeader = null): PhpFile { if (!$this->interface) { - throw new \LogicException(sprintf("'%s' has no interface attached.", $this->name)); + throw new \LogicException(\sprintf("'%s' has no interface attached.", $this->name)); } return $this->interface->toNetteFile($fileHeader); diff --git a/src/Model/Property.php b/src/Model/Property.php index 9083c338..6f561d07 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -190,7 +190,7 @@ public function generateNetteMethods( \Closure $singularize, PhpNamespace $namespace, bool $useDoctrineCollections = true, - bool $useFluentMutators = false + bool $useFluentMutators = false, ): array { return array_merge( $this->generateMutators($singularize, $namespace, $useDoctrineCollections, $useFluentMutators), @@ -201,7 +201,7 @@ public function generateNetteMethods( private function generateGetter(PhpNamespace $namespace): Method { if (!$this->isReadable) { - throw new \LogicException(sprintf("Property '%s' is not readable.", $this->name)); + throw new \LogicException(\sprintf("Property '%s' is not readable.", $this->name)); } $getter = (new Method('get'.ucfirst($this->name)))->setVisibility(ClassType::VISIBILITY_PUBLIC); @@ -226,7 +226,7 @@ private function generateMutators( \Closure $singularize, PhpNamespace $namespace, bool $useDoctrineCollections = true, - bool $useFluentMutators = false + bool $useFluentMutators = false, ): array { if (!$this->isWritable) { return []; @@ -246,7 +246,7 @@ private function generateMutators( $parameter->setType($this->adderRemoverTypeHint ? $this->resolveName($namespace, $this->adderRemoverTypeHint) : $this->adderRemoverTypeHint); } $adder->addBody( - sprintf('$this->%s[] = %s;', $this->name(), ($this->isEnum ? '(string) ' : '')."$$singularProperty") + \sprintf('$this->%s[] = %s;', $this->name(), ($this->isEnum ? '(string) ' : '')."$$singularProperty") ); if ($useFluentMutators) { $adder->addBody(''); @@ -265,13 +265,13 @@ private function generateMutators( } if ($useDoctrineCollections && $this->typeHint && 'array' !== $this->typeHint && !$this->isEnum) { - $remover->addBody(sprintf( + $remover->addBody(\sprintf( '$this->%s->removeElement(%s);', $this->name(), "$$singularProperty" )); } else { - $remover->addBody(sprintf(<<<'PHP' + $remover->addBody(\sprintf(<<<'PHP' if (false !== $key = array_search(%s, %s, true)) { unset($this->%s[$key]); } diff --git a/src/OpenApi/ClassGenerator.php b/src/OpenApi/ClassGenerator.php index b23d50a9..49ea5ca6 100644 --- a/src/OpenApi/ClassGenerator.php +++ b/src/OpenApi/ClassGenerator.php @@ -78,26 +78,26 @@ public function generate(OpenApi $openApi, array $config): array $showOperation = $pathItem->get; $editOperation = $pathItem->put ?? $pathItem->patch; if (null === $showOperation && null === $editOperation) { - $this->logger ? $this->logger->warning(sprintf('No get, put or patch operation found for path "%s"', $path)) : null; + $this->logger ? $this->logger->warning(\sprintf('No get, put or patch operation found for path "%s"', $path)) : null; continue; } $showSchema = null; if ($showOperation && $showOperation->responses && null !== $responseSchema = ($showOperation->responses[200]->content['application/json']->schema ?? null)) { - $this->logger ? $this->logger->info(sprintf('Using show schema from get operation response for "%s" resource.', $name)) : null; + $this->logger ? $this->logger->info(\sprintf('Using show schema from get operation response for "%s" resource.', $name)) : null; $showSchema = $responseSchema; } if (!$showSchema && $openApi->components && isset($openApi->components->schemas[$name])) { - $this->logger ? $this->logger->info(sprintf('Using "%s" show schema from components.', $name)) : null; + $this->logger ? $this->logger->info(\sprintf('Using "%s" show schema from components.', $name)) : null; $showSchema = $openApi->components->schemas[$name]; } $editSchema = null; if ($editOperation && $editOperation->requestBody instanceof RequestBody && null !== $requestBodySchema = ($editOperation->requestBody->content['application/json']->schema ?? null)) { - $this->logger ? $this->logger->info(sprintf('Using edit schema from put operation request body for "%s" resource.', $name)) : null; + $this->logger ? $this->logger->info(\sprintf('Using edit schema from put operation request body for "%s" resource.', $name)) : null; $editSchema = $requestBodySchema; } if (null === $showSchema && null === $editSchema) { - $this->logger ? $this->logger->warning(sprintf('No schema found for path "%s"', $path)) : null; + $this->logger ? $this->logger->warning(\sprintf('No schema found for path "%s"', $path)) : null; continue; } @@ -122,7 +122,7 @@ public function generate(OpenApi $openApi, array $config): array $putOperation = $pathItem->put; $patchOperation = $pathItem->patch; $deleteOperation = $pathItem->delete; - $pathCollection = $openApi->paths->getPath(sprintf('/%s', $collectionResourceName)); + $pathCollection = $openApi->paths->getPath(\sprintf('/%s', $collectionResourceName)); $listOperation = $pathCollection->get ?? null; $createOperation = $pathCollection->post ?? null; $class->operations = array_merge( diff --git a/src/OpenApi/Generator.php b/src/OpenApi/Generator.php index 68cc7614..929a933f 100644 --- a/src/OpenApi/Generator.php +++ b/src/OpenApi/Generator.php @@ -36,7 +36,7 @@ public function generate(array $configuration, string $configurationPath, Output $configurationDirectory = Path::getDirectory($configurationPath); $openApiFilePath = Path::join($configurationDirectory, $openApiFile); if (!$openApiFileRealPath = realpath($openApiFilePath)) { - throw new \InvalidArgumentException(sprintf('The file "%s" isn\'t readable.', $openApiFilePath)); + throw new \InvalidArgumentException(\sprintf('The file "%s" isn\'t readable.', $openApiFilePath)); } $extension = Path::getExtension($openApiFileRealPath); if ('json' === $extension) { diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index 94bcf8d3..ee90257b 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -53,7 +53,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $openApiProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $openApiProperty); if (!$openApiProperty instanceof OpenApiProperty) { - throw new \LogicException(sprintf('Property has to be an instance of "%s".', OpenApiProperty::class)); + throw new \LogicException(\sprintf('Property has to be an instance of "%s".', OpenApiProperty::class)); } $requiredFields = $schema->required ?? []; diff --git a/src/PhpTypeConverter.php b/src/PhpTypeConverter.php index e06a924d..139ee70c 100644 --- a/src/PhpTypeConverter.php +++ b/src/PhpTypeConverter.php @@ -22,7 +22,7 @@ final class PhpTypeConverter implements PhpTypeConverterInterface public function getPhpType(Property $property, array $config = [], array $classes = []): ?string { if (!$property instanceof SchemaProperty) { - throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); + throw new \LogicException(\sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); } if ($property->reference && $property->isArray()) { diff --git a/src/PropertyGenerator/PropertyGeneratorInterface.php b/src/PropertyGenerator/PropertyGeneratorInterface.php index e82c13f0..96f6b944 100644 --- a/src/PropertyGenerator/PropertyGeneratorInterface.php +++ b/src/PropertyGenerator/PropertyGeneratorInterface.php @@ -28,6 +28,6 @@ public function __invoke( Class_ $class, array $context, bool $isCustom = false, - ?Property $property = null + ?Property $property = null, ): ?Property; } diff --git a/src/Schema/PropertyGenerator/IdPropertyGenerator.php b/src/Schema/PropertyGenerator/IdPropertyGenerator.php index 93cd83a7..de8e9c2c 100644 --- a/src/Schema/PropertyGenerator/IdPropertyGenerator.php +++ b/src/Schema/PropertyGenerator/IdPropertyGenerator.php @@ -35,7 +35,7 @@ public function __invoke(string $generationStrategy, bool $supportsWritableId, ? $idProperty = ($this->idPropertyGenerator)($generationStrategy, $supportsWritableId, new SchemaProperty('id')); if (!$idProperty instanceof SchemaProperty) { - throw new \LogicException(sprintf('ID property has to be an instance of "%s".', SchemaProperty::class)); + throw new \LogicException(\sprintf('ID property has to be an instance of "%s".', SchemaProperty::class)); } $idProperty->type = $idProperty->type instanceof PrimitiveType ? new SchemaPrimitiveType($idProperty->type->name) : null; diff --git a/src/Schema/PropertyGenerator/PropertyGenerator.php b/src/Schema/PropertyGenerator/PropertyGenerator.php index 23b4d304..f016776d 100644 --- a/src/Schema/PropertyGenerator/PropertyGenerator.php +++ b/src/Schema/PropertyGenerator/PropertyGenerator.php @@ -73,12 +73,12 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont // Warn when property are not part of GoodRelations if ($config['checkIsGoodRelations'] && !$this->goodRelationsBridge->exists($name)) { - $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyUri, $typeUri)) : null; + $this->logger ? $this->logger->warning(\sprintf('The property "%s" (type "%s") is not part of GoodRelations.', $propertyUri, $typeUri)) : null; } // Warn when properties are legacy if (preg_match('/legacy spelling/', (string) $typeProperty->get('rdfs:comment'))) { - $this->logger ? $this->logger->warning(sprintf('The property "%s" (type "%s") is legacy.', $propertyUri, $typeUri)) : null; + $this->logger ? $this->logger->warning(\sprintf('The property "%s" (type "%s") is legacy.', $propertyUri, $typeUri)) : null; } $ranges = []; @@ -94,12 +94,12 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont if (isset($propertyConfig['range'])) { $ranges[] = new RdfResource($propertyConfig['range'], $type->getGraph()); } else { - $this->logger ? $this->logger->error(sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyUri, $typeUri)) : null; + $this->logger ? $this->logger->error(\sprintf('The property "%s" (type "%s") has an unknown type. Add its type to the config file.', $propertyUri, $typeUri)) : null; } } if (\count($ranges) > 1) { - $this->logger ? $this->logger->info(sprintf('The property "%s" (type "%s") has several types. Using the first one ("%s"). Other possible options: "%s".', $propertyUri, $typeUri, $ranges[0]->getUri(), implode('", "', array_map(static fn (RdfResource $range) => $range->getUri(), $ranges)))) : null; + $this->logger ? $this->logger->info(\sprintf('The property "%s" (type "%s") has several types. Using the first one ("%s"). Other possible options: "%s".', $propertyUri, $typeUri, $ranges[0]->getUri(), implode('", "', array_map(static fn (RdfResource $range) => $range->getUri(), $ranges)))) : null; } $rangeName = null; @@ -145,7 +145,7 @@ public function __invoke(string $name, array $config, Class_ $class, array $cont $schemaProperty = ($this->propertyGenerator)($name, $config, $class, $context, $isCustom, $schemaProperty); if (!$schemaProperty instanceof SchemaProperty) { - throw new \LogicException(sprintf('Property has to be an instance of "%s".', SchemaProperty::class)); + throw new \LogicException(\sprintf('Property has to be an instance of "%s".', SchemaProperty::class)); } $isNullable = (bool) ($propertyConfig['nullable'] ?? !\in_array($cardinality, [ diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 5dd128c3..606aa437 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -124,7 +124,7 @@ public function generate(array $graphs, array $config): array $class = $classes[$typeNameToGenerate]; while (($parent = $class->parent()) && !$class->isParentEnum()) { if (!isset($classes[$parent])) { - $this->logger ? $this->logger->error(sprintf('The type "%s" (parent of "%s") doesn\'t exist', $parent, $class->rdfType())) : null; + $this->logger ? $this->logger->error(\sprintf('The type "%s" (parent of "%s") doesn\'t exist', $parent, $class->rdfType())) : null; break; } if (!\in_array($parent, $typeNamesToGenerate, true)) { @@ -151,7 +151,7 @@ public function generate(array $graphs, array $config): array foreach ($class->properties() as $property) { if (!$property instanceof SchemaProperty) { - throw new \LogicException(sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); + throw new \LogicException(\sprintf('Property "%s" has to be an instance of "%s".', $property->name(), SchemaProperty::class)); } $typeName = $property->rangeName; if (isset($classes[$typeName])) { From c8c455663e23b9ef3a94e490086fa805b0e5198c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 30 Jan 2025 18:35:19 +0100 Subject: [PATCH 256/258] feat: compatibility with PHP 8.4 (#433) * chore: bump deps and fix tests * use normal phpunit * fix * fix 8.4 * fix PHPUnit config * fix * fix * run PHP CS Fixer on 8.3 * fix e2e tests * fix coverage --- .github/workflows/ci.yml | 25 +- .github/workflows/release.yml | 2 +- composer.json | 29 +- composer.lock | 2362 +++++++++-------- phpstan.neon | 2 +- phpunit.xml.dist | 32 +- .../ApiPlatformCoreAttributeGenerator.php | 7 +- src/GoodRelationsBridge.php | 2 +- src/Model/Class_.php | 6 +- src/Model/Property.php | 6 +- src/Model/ResolveNameTrait.php | 2 +- src/OpenApi/Model/Constant.php | 3 +- src/OpenApi/PhpTypeConverter.php | 2 +- .../PropertyGenerator/PropertyGenerator.php | 2 +- src/Printer.php | 2 +- src/PropertyGenerator/PropertyGenerator.php | 2 +- src/TypesGenerator.php | 5 +- .../PhpDocAnnotationGeneratorTest.php | 13 +- .../ApiPlatformCoreAttributeGeneratorTest.php | 13 +- .../ConfigurationAttributeGeneratorTest.php | 19 +- .../ConstraintAttributeGeneratorTest.php | 13 +- tests/ClassMutator/ClassParentMutatorTest.php | 7 +- .../ClassPropertiesAppenderTest.php | 7 +- tests/Command/GenerateCommandTest.php | 7 +- .../App/Schema/Entity/PostalAddress.php | 2 +- .../original/App/Schema/Enum/GenderType.php | 6 +- 26 files changed, 1305 insertions(+), 1273 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 14f0720e..b504cf2a 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,14 +15,9 @@ jobs: strategy: matrix: php: - - '7.4' - - '8.0' - - '8.1' - '8.2' - '8.3' - include: - - php: '8.3' - latest: true + - '8.4' fail-fast: false steps: - uses: actions/checkout@v4 @@ -47,39 +42,39 @@ jobs: - name: Install prerequisites run: | - wget -O box.phar https://github.com/humbug/box/releases/download/4.5.1/box.phar + wget -O box.phar https://github.com/humbug/box/releases/download/4.6.2/box.phar echo "BOX_BIN=$(pwd)/box.phar" >> $GITHUB_ENV sudo chown -R $(whoami):$(whoami) . - name: Install dependencies - if: matrix.latest + if: "matrix.php == '8.4'" run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Update dependencies - if: '!matrix.latest' + if: "matrix.php != '8.4'" run: composer update --no-interaction --no-progress --ansi - name: Enable code coverage - if: matrix.latest + if: "matrix.php == '8.4'" run: echo "COVERAGE=1" >> $GITHUB_ENV - name: Run PHPUnit - run: vendor/bin/simple-phpunit ${{ matrix.latest && '--coverage-clover build/logs/phpunit/clover.xml' || '' }} + run: vendor/bin/phpunit ${{ matrix.php == '8.4' && '--coverage-clover build/logs/phpunit/clover.xml' || '' }} - name: Run PHP CS Fixer - if: matrix.latest + if: "matrix.php == '8.3'" run: php-cs-fixer fix --dry-run --format=checkstyle --ansi | cs2pr - name: Run PHPStan - if: matrix.latest + if: "matrix.php == '8.4'" run: vendor/bin/phpstan analyse --ansi - name: Run e2e tests - if: matrix.latest + if: "matrix.php == '8.4'" run: bin/compile - name: Upload coverage results to Coveralls - if: matrix.latest + if: "matrix.php == '8.4'" env: COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: | diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fb37875f..0a997cb1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -16,7 +16,7 @@ jobs: - name: Setup PHP with extensions uses: shivammathur/setup-php@v2 with: - php-version: '8.3' + php-version: '8.4' extensions: json ini-values: memory_limit=-1 tools: composer diff --git a/composer.json b/composer.json index 1cd1e87b..9e3d285c 100644 --- a/composer.json +++ b/composer.json @@ -39,30 +39,27 @@ "friendsofphp/php-cs-fixer": "^2.15 || ^3.0", "league/html-to-markdown": "^5.0", "psr/log": "^1.0 || ^2.0 || ^3.0", - "symfony/config": "^5.2 || ^6.0 || ^7.0" , - "symfony/console": "^5.2 || ^6.0 || ^7.0", - "symfony/yaml": "^5.2 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.2 || ^6.0 || ^7.0", + "symfony/config": "^5.4 || ^6.4 || ^7.0" , + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/yaml": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", "twig/twig": "^3.0", "nette/php-generator": "^3.6 || ^4.0", "nikic/php-parser": "^4.13 || ^5.0", "devizzent/cebe-php-openapi": "^1.0.3", - "symfony/string": "^5.2 || ^6.0 || ^7.0" + "symfony/string": "^5.4 || ^6.4 || ^7.0" }, "require-dev": { - "api-platform/core": "^2.7 || ^3.0", - "doctrine/orm": "^2.7", + "api-platform/core": "^3.0 || ^4.0", + "doctrine/orm": "^2.7 || ^3.0", "myclabs/php-enum": "^1.7", - "symfony/doctrine-bridge": "^5.2 || ^6.0 || ^7.0", - "symfony/phpunit-bridge": "^5.2 || ^6.0 || ^7.0", - "symfony/serializer": "^5.2 || ^6.0 || ^7.0", - "symfony/validator": "^5.2 || ^6.0 || ^7.0", + "symfony/doctrine-bridge": "^5.4 || ^6.4 || ^7.0", + "symfony/phpunit-bridge": "^5.4 || ^6.4 || ^7.0", + "symfony/serializer": "^5.4 || ^6.4 || ^7.0", + "symfony/validator": "^5.4 || ^6.4 || ^7.0", "phpspec/prophecy-phpunit": "^2.0", - "phpstan/phpstan": "^1.2.0", - "symfony/finder": "^5.2 || ^6.0 || ^7.0" - }, - "conflict": { - "sebastian/comparator": ">=5.0" + "phpstan/phpstan": "^2.1", + "symfony/finder": "^5.4 || ^6.4 || ^7.0" }, "bin": [ "bin/schema" diff --git a/composer.lock b/composer.lock index f11029f4..42a0fb5b 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "361ed8a36c253f2e709b8aa97ef133b7", + "content-hash": "472049b60481f3b6d841700bcd23b751", "packages": [ { "name": "clue/ndjson-react", @@ -72,28 +72,36 @@ }, { "name": "composer/pcre", - "version": "3.1.4", + "version": "3.3.2", "source": { "type": "git", "url": "https://github.com/composer/pcre.git", - "reference": "04229f163664973f68f38f6f73d917799168ef24" + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/pcre/zipball/04229f163664973f68f38f6f73d917799168ef24", - "reference": "04229f163664973f68f38f6f73d917799168ef24", + "url": "https://api.github.com/repos/composer/pcre/zipball/b2bed4734f0cc156ee1fe9c0da2550420d99a21e", + "reference": "b2bed4734f0cc156ee1fe9c0da2550420d99a21e", "shasum": "" }, "require": { "php": "^7.4 || ^8.0" }, + "conflict": { + "phpstan/phpstan": "<1.11.10" + }, "require-dev": { - "phpstan/phpstan": "^1.3", - "phpstan/phpstan-strict-rules": "^1.1", - "symfony/phpunit-bridge": "^5" + "phpstan/phpstan": "^1.12 || ^2", + "phpstan/phpstan-strict-rules": "^1 || ^2", + "phpunit/phpunit": "^8 || ^9" }, "type": "library", "extra": { + "phpstan": { + "includes": [ + "extension.neon" + ] + }, "branch-alias": { "dev-main": "3.x-dev" } @@ -123,7 +131,7 @@ ], "support": { "issues": "https://github.com/composer/pcre/issues", - "source": "https://github.com/composer/pcre/tree/3.1.4" + "source": "https://github.com/composer/pcre/tree/3.3.2" }, "funding": [ { @@ -139,28 +147,28 @@ "type": "tidelift" } ], - "time": "2024-05-27T13:40:54+00:00" + "time": "2024-11-12T16:29:46+00:00" }, { "name": "composer/semver", - "version": "3.4.0", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32" + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/35e8d0af4486141bc745f23a29cc2091eb624a32", - "reference": "35e8d0af4486141bc745f23a29cc2091eb624a32", + "url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", + "reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12", "shasum": "" }, "require": { "php": "^5.3.2 || ^7.0 || ^8.0" }, "require-dev": { - "phpstan/phpstan": "^1.4", - "symfony/phpunit-bridge": "^4.2 || ^5" + "phpstan/phpstan": "^1.11", + "symfony/phpunit-bridge": "^3 || ^7" }, "type": "library", "extra": { @@ -204,7 +212,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/semver/issues", - "source": "https://github.com/composer/semver/tree/3.4.0" + "source": "https://github.com/composer/semver/tree/3.4.3" }, "funding": [ { @@ -220,7 +228,7 @@ "type": "tidelift" } ], - "time": "2023-08-31T09:50:34+00:00" + "time": "2024-09-19T14:15:21+00:00" }, { "name": "composer/xdebug-handler", @@ -290,27 +298,30 @@ }, { "name": "devizzent/cebe-php-openapi", - "version": "1.0.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/DEVizzent/cebe-php-openapi.git", - "reference": "b5a5de835dcb1642094fe76568451bd73b8fc0ab" + "reference": "af42b77f339b6b2920b65bae5df748e47391e11d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/DEVizzent/cebe-php-openapi/zipball/b5a5de835dcb1642094fe76568451bd73b8fc0ab", - "reference": "b5a5de835dcb1642094fe76568451bd73b8fc0ab", + "url": "https://api.github.com/repos/DEVizzent/cebe-php-openapi/zipball/af42b77f339b6b2920b65bae5df748e47391e11d", + "reference": "af42b77f339b6b2920b65bae5df748e47391e11d", "shasum": "" }, "require": { "ext-json": "*", - "justinrainbow/json-schema": "^5.2", + "justinrainbow/json-schema": "^5.2 || ^6.0", "php": ">=7.1.0", "symfony/yaml": "^3.4 || ^4 || ^5 || ^6 || ^7" }, "conflict": { "symfony/yaml": "3.4.0 - 3.4.4 || 4.0.0 - 4.4.17 || 5.0.0 - 5.1.9 || 5.2.0" }, + "replace": { + "cebe/php-openapi": "1.7.0" + }, "require-dev": { "apis-guru/openapi-directory": "1.0.0", "cebe/indent": "*", @@ -318,7 +329,7 @@ "oai/openapi-specification-3.0": "3.0.3", "oai/openapi-specification-3.1": "3.1.0", "phpstan/phpstan": "^0.12.0", - "phpunit/phpunit": "^6.5 || ^7.5 || ^8.5 || ^9.4" + "phpunit/phpunit": "^6.5 || ^7.5 || ^8.5 || ^9.4 || ^11.4" }, "bin": [ "bin/php-openapi" @@ -359,7 +370,7 @@ "issues": "https://github.com/DEVizzent/cebe-php-openapi/issues", "source": "https://github.com/DEVizzent/cebe-php-openapi" }, - "time": "2024-01-10T11:41:55+00:00" + "time": "2025-01-16T11:12:34+00:00" }, { "name": "doctrine/inflector", @@ -501,16 +512,16 @@ }, { "name": "fidry/cpu-core-counter", - "version": "1.1.0", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/theofidry/cpu-core-counter.git", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42" + "reference": "8520451a140d3f46ac33042715115e290cf5785f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/f92996c4d5c1a696a6a970e20f7c4216200fcc42", - "reference": "f92996c4d5c1a696a6a970e20f7c4216200fcc42", + "url": "https://api.github.com/repos/theofidry/cpu-core-counter/zipball/8520451a140d3f46ac33042715115e290cf5785f", + "reference": "8520451a140d3f46ac33042715115e290cf5785f", "shasum": "" }, "require": { @@ -550,7 +561,7 @@ ], "support": { "issues": "https://github.com/theofidry/cpu-core-counter/issues", - "source": "https://github.com/theofidry/cpu-core-counter/tree/1.1.0" + "source": "https://github.com/theofidry/cpu-core-counter/tree/1.2.0" }, "funding": [ { @@ -558,20 +569,20 @@ "type": "github" } ], - "time": "2024-02-07T09:43:46+00:00" + "time": "2024-08-06T10:04:20+00:00" }, { "name": "friendsofphp/php-cs-fixer", - "version": "v3.58.1", + "version": "v3.68.3", "source": { "type": "git", "url": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer.git", - "reference": "04e9424025677a86914b9a4944dbbf4060bb0aff" + "reference": "85fd31cced824749a732e697acdd1a3d657312f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/04e9424025677a86914b9a4944dbbf4060bb0aff", - "reference": "04e9424025677a86914b9a4944dbbf4060bb0aff", + "url": "https://api.github.com/repos/PHP-CS-Fixer/PHP-CS-Fixer/zipball/85fd31cced824749a732e697acdd1a3d657312f0", + "reference": "85fd31cced824749a732e697acdd1a3d657312f0", "shasum": "" }, "require": { @@ -581,38 +592,38 @@ "ext-filter": "*", "ext-json": "*", "ext-tokenizer": "*", - "fidry/cpu-core-counter": "^1.0", + "fidry/cpu-core-counter": "^1.2", "php": "^7.4 || ^8.0", "react/child-process": "^0.6.5", "react/event-loop": "^1.0", "react/promise": "^2.0 || ^3.0", "react/socket": "^1.0", "react/stream": "^1.0", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0", - "symfony/console": "^5.4 || ^6.0 || ^7.0", - "symfony/event-dispatcher": "^5.4 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0", - "symfony/finder": "^5.4 || ^6.0 || ^7.0", - "symfony/options-resolver": "^5.4 || ^6.0 || ^7.0", - "symfony/polyfill-mbstring": "^1.28", - "symfony/polyfill-php80": "^1.28", - "symfony/polyfill-php81": "^1.28", - "symfony/process": "^5.4 || ^6.0 || ^7.0", - "symfony/stopwatch": "^5.4 || ^6.0 || ^7.0" + "sebastian/diff": "^4.0 || ^5.1 || ^6.0", + "symfony/console": "^5.4 || ^6.4 || ^7.0", + "symfony/event-dispatcher": "^5.4 || ^6.4 || ^7.0", + "symfony/filesystem": "^5.4 || ^6.4 || ^7.0", + "symfony/finder": "^5.4 || ^6.4 || ^7.0", + "symfony/options-resolver": "^5.4 || ^6.4 || ^7.0", + "symfony/polyfill-mbstring": "^1.31", + "symfony/polyfill-php80": "^1.31", + "symfony/polyfill-php81": "^1.31", + "symfony/process": "^5.4 || ^6.4 || ^7.2", + "symfony/stopwatch": "^5.4 || ^6.4 || ^7.0" }, "require-dev": { - "facile-it/paraunit": "^1.3 || ^2.0", - "infection/infection": "^0.27.11", - "justinrainbow/json-schema": "^5.2", + "facile-it/paraunit": "^1.3.1 || ^2.4", + "infection/infection": "^0.29.8", + "justinrainbow/json-schema": "^5.3 || ^6.0", "keradus/cli-executor": "^2.1", - "mikey179/vfsstream": "^1.6.11", + "mikey179/vfsstream": "^1.6.12", "php-coveralls/php-coveralls": "^2.7", "php-cs-fixer/accessible-object": "^1.1", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.4", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.4", - "phpunit/phpunit": "^9.6 || ^10.5.5 || ^11.0.2", - "symfony/var-dumper": "^5.4 || ^6.0 || ^7.0", - "symfony/yaml": "^5.4 || ^6.0 || ^7.0" + "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.5", + "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.5", + "phpunit/phpunit": "^9.6.22 || ^10.5.40 || ^11.5.2", + "symfony/var-dumper": "^5.4.48 || ^6.4.15 || ^7.2.0", + "symfony/yaml": "^5.4.45 || ^6.4.13 || ^7.2.0" }, "suggest": { "ext-dom": "For handling output formats in XML", @@ -625,7 +636,10 @@ "autoload": { "psr-4": { "PhpCsFixer\\": "src/" - } + }, + "exclude-from-classmap": [ + "src/Fixer/Internal/*" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -650,7 +664,7 @@ ], "support": { "issues": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/issues", - "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.58.1" + "source": "https://github.com/PHP-CS-Fixer/PHP-CS-Fixer/tree/v3.68.3" }, "funding": [ { @@ -658,27 +672,144 @@ "type": "github" } ], - "time": "2024-05-29T16:39:07+00:00" + "time": "2025-01-27T16:37:32+00:00" + }, + { + "name": "icecave/parity", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/icecave/parity.git", + "reference": "0109fef58b3230d23b20b2ac52ecdf477218d300" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icecave/parity/zipball/0109fef58b3230d23b20b2ac52ecdf477218d300", + "reference": "0109fef58b3230d23b20b2ac52ecdf477218d300", + "shasum": "" + }, + "require": { + "icecave/repr": "~1", + "php": ">=5.3" + }, + "require-dev": { + "eloquent/liberator": "~1", + "icecave/archer": "~1" + }, + "suggest": { + "eloquent/asplode": "Drop-in exception-based error handling." + }, + "type": "library", + "autoload": { + "psr-0": { + "Icecave\\Parity": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Harris", + "email": "james.harris@icecave.com.au", + "homepage": "https://github.com/jmalloc" + } + ], + "description": "A customizable deep comparison library.", + "homepage": "https://github.com/IcecaveStudios/parity", + "keywords": [ + "compare", + "comparison", + "equal", + "equality", + "greater", + "less", + "sort", + "sorting" + ], + "support": { + "issues": "https://github.com/icecave/parity/issues", + "source": "https://github.com/icecave/parity/tree/1.0.0" + }, + "time": "2014-01-17T05:56:27+00:00" + }, + { + "name": "icecave/repr", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/icecave/repr.git", + "reference": "8a3d2953adf5f464a06e3e2587aeacc97e2bed07" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/icecave/repr/zipball/8a3d2953adf5f464a06e3e2587aeacc97e2bed07", + "reference": "8a3d2953adf5f464a06e3e2587aeacc97e2bed07", + "shasum": "" + }, + "require": { + "php": ">=5.3" + }, + "require-dev": { + "icecave/archer": "~1" + }, + "suggest": { + "eloquent/asplode": "Drop-in exception-based error handling." + }, + "type": "library", + "autoload": { + "psr-4": { + "Icecave\\Repr\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Harris", + "email": "james.harris@icecave.com.au", + "homepage": "https://github.com/jmalloc" + } + ], + "description": "A library for generating string representations of any value, inspired by Python's reprlib library.", + "homepage": "https://github.com/IcecaveStudios/repr", + "keywords": [ + "human", + "readable", + "repr", + "representation", + "string" + ], + "support": { + "issues": "https://github.com/icecave/repr/issues", + "source": "https://github.com/icecave/repr/tree/1.0.1" + }, + "time": "2014-07-25T05:44:41+00:00" }, { "name": "justinrainbow/json-schema", - "version": "v5.2.13", + "version": "6.0.0", "source": { "type": "git", "url": "https://github.com/jsonrainbow/json-schema.git", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793" + "reference": "a38c6198d53b09c0702f440585a4f4a5d9137bd9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/fbbe7e5d79f618997bc3332a6f49246036c45793", - "reference": "fbbe7e5d79f618997bc3332a6f49246036c45793", + "url": "https://api.github.com/repos/jsonrainbow/json-schema/zipball/a38c6198d53b09c0702f440585a4f4a5d9137bd9", + "reference": "a38c6198d53b09c0702f440585a4f4a5d9137bd9", "shasum": "" }, "require": { + "icecave/parity": "1.0.0", + "marc-mabe/php-enum": "^2.0 || ^3.0 || ^4.0", "php": ">=5.3.3" }, "require-dev": { - "friendsofphp/php-cs-fixer": "~2.2.20||~2.15.1", + "friendsofphp/php-cs-fixer": "~2.2.20 || ~2.19.0", "json-schema/json-schema-test-suite": "1.2.0", "phpunit/phpunit": "^4.8.35" }, @@ -688,7 +819,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0.x-dev" + "dev-master": "6.x-dev" } }, "autoload": { @@ -719,16 +850,16 @@ } ], "description": "A library to validate a json schema.", - "homepage": "https://github.com/justinrainbow/json-schema", + "homepage": "https://github.com/jsonrainbow/json-schema", "keywords": [ "json", "schema" ], "support": { "issues": "https://github.com/jsonrainbow/json-schema/issues", - "source": "https://github.com/jsonrainbow/json-schema/tree/v5.2.13" + "source": "https://github.com/jsonrainbow/json-schema/tree/6.0.0" }, - "time": "2023-09-26T02:20:38+00:00" + "time": "2024-07-30T17:49:21+00:00" }, { "name": "league/html-to-markdown", @@ -819,23 +950,96 @@ ], "time": "2023-07-12T21:21:09+00:00" }, + { + "name": "marc-mabe/php-enum", + "version": "v4.7.1", + "source": { + "type": "git", + "url": "https://github.com/marc-mabe/php-enum.git", + "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/marc-mabe/php-enum/zipball/7159809e5cfa041dca28e61f7f7ae58063aae8ed", + "reference": "7159809e5cfa041dca28e61f7f7ae58063aae8ed", + "shasum": "" + }, + "require": { + "ext-reflection": "*", + "php": "^7.1 | ^8.0" + }, + "require-dev": { + "phpbench/phpbench": "^0.16.10 || ^1.0.4", + "phpstan/phpstan": "^1.3.1", + "phpunit/phpunit": "^7.5.20 | ^8.5.22 | ^9.5.11", + "vimeo/psalm": "^4.17.0 | ^5.26.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.2-dev", + "dev-master": "4.7-dev" + } + }, + "autoload": { + "psr-4": { + "MabeEnum\\": "src/" + }, + "classmap": [ + "stubs/Stringable.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Marc Bennewitz", + "email": "dev@mabe.berlin", + "homepage": "https://mabe.berlin/", + "role": "Lead" + } + ], + "description": "Simple and fast implementation of enumerations with native PHP", + "homepage": "https://github.com/marc-mabe/php-enum", + "keywords": [ + "enum", + "enum-map", + "enum-set", + "enumeration", + "enumerator", + "enummap", + "enumset", + "map", + "set", + "type", + "type-hint", + "typehint" + ], + "support": { + "issues": "https://github.com/marc-mabe/php-enum/issues", + "source": "https://github.com/marc-mabe/php-enum/tree/v4.7.1" + }, + "time": "2024-11-28T04:54:44+00:00" + }, { "name": "nette/php-generator", - "version": "v4.1.5", + "version": "v4.1.7", "source": { "type": "git", "url": "https://github.com/nette/php-generator.git", - "reference": "690b00d81d42d5633e4457c43ef9754573b6f9d6" + "reference": "d201c9bc217e0969d1b678d286be49302972fb56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/php-generator/zipball/690b00d81d42d5633e4457c43ef9754573b6f9d6", - "reference": "690b00d81d42d5633e4457c43ef9754573b6f9d6", + "url": "https://api.github.com/repos/nette/php-generator/zipball/d201c9bc217e0969d1b678d286be49302972fb56", + "reference": "d201c9bc217e0969d1b678d286be49302972fb56", "shasum": "" }, "require": { "nette/utils": "^3.2.9 || ^4.0", - "php": "8.0 - 8.3" + "php": "8.0 - 8.4" }, "require-dev": { "jetbrains/phpstorm-attributes": "dev-master", @@ -874,7 +1078,7 @@ "homepage": "https://nette.org/contributors" } ], - "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.3 features.", + "description": "🐘 Nette PHP Generator: generates neat PHP code for you. Supports new PHP 8.4 features.", "homepage": "https://nette.org/", "keywords": [ "code", @@ -884,26 +1088,26 @@ ], "support": { "issues": "https://github.com/nette/php-generator/issues", - "source": "https://github.com/nette/php-generator/tree/v4.1.5" + "source": "https://github.com/nette/php-generator/tree/v4.1.7" }, - "time": "2024-05-12T17:31:02+00:00" + "time": "2024-11-29T01:41:18+00:00" }, { "name": "nette/utils", - "version": "v4.0.4", + "version": "v4.0.5", "source": { "type": "git", "url": "https://github.com/nette/utils.git", - "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218" + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nette/utils/zipball/d3ad0aa3b9f934602cb3e3902ebccf10be34d218", - "reference": "d3ad0aa3b9f934602cb3e3902ebccf10be34d218", + "url": "https://api.github.com/repos/nette/utils/zipball/736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", + "reference": "736c567e257dbe0fcf6ce81b4d6dbe05c6899f96", "shasum": "" }, "require": { - "php": ">=8.0 <8.4" + "php": "8.0 - 8.4" }, "conflict": { "nette/finder": "<3", @@ -970,22 +1174,22 @@ ], "support": { "issues": "https://github.com/nette/utils/issues", - "source": "https://github.com/nette/utils/tree/v4.0.4" + "source": "https://github.com/nette/utils/tree/v4.0.5" }, - "time": "2024-01-17T16:50:36+00:00" + "time": "2024-08-07T15:39:19+00:00" }, { "name": "nikic/php-parser", - "version": "v5.0.2", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" + "reference": "447a020a1f875a434d62f2a401f53b82a396e494" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/447a020a1f875a434d62f2a401f53b82a396e494", + "reference": "447a020a1f875a434d62f2a401f53b82a396e494", "shasum": "" }, "require": { @@ -996,7 +1200,7 @@ }, "require-dev": { "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" + "phpunit/phpunit": "^9.0" }, "bin": [ "bin/php-parse" @@ -1028,9 +1232,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" + "source": "https://github.com/nikic/PHP-Parser/tree/v5.4.0" }, - "time": "2024-03-05T20:51:40+00:00" + "time": "2024-12-30T11:07:19+00:00" }, { "name": "psr/container", @@ -1190,16 +1394,16 @@ }, { "name": "psr/log", - "version": "3.0.0", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001" + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/fe5ea303b0887d5caefd3d431c3e61ad47037001", - "reference": "fe5ea303b0887d5caefd3d431c3e61ad47037001", + "url": "https://api.github.com/repos/php-fig/log/zipball/f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", + "reference": "f16e1d5863e37f8d8c2a01719f5b34baa2b714d3", "shasum": "" }, "require": { @@ -1234,9 +1438,9 @@ "psr-3" ], "support": { - "source": "https://github.com/php-fig/log/tree/3.0.0" + "source": "https://github.com/php-fig/log/tree/3.0.2" }, - "time": "2021-07-14T16:46:02+00:00" + "time": "2024-09-11T13:17:53+00:00" }, { "name": "react/cache", @@ -1312,33 +1516,33 @@ }, { "name": "react/child-process", - "version": "v0.6.5", + "version": "v0.6.6", "source": { "type": "git", "url": "https://github.com/reactphp/child-process.git", - "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43" + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/child-process/zipball/e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", - "reference": "e71eb1aa55f057c7a4a0d08d06b0b0a484bead43", + "url": "https://api.github.com/repos/reactphp/child-process/zipball/1721e2b93d89b745664353b9cfc8f155ba8a6159", + "reference": "1721e2b93d89b745664353b9cfc8f155ba8a6159", "shasum": "" }, "require": { "evenement/evenement": "^3.0 || ^2.0 || ^1.0", "php": ">=5.3.0", "react/event-loop": "^1.2", - "react/stream": "^1.2" + "react/stream": "^1.4" }, "require-dev": { - "phpunit/phpunit": "^9.3 || ^5.7 || ^4.8.35", - "react/socket": "^1.8", + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", + "react/socket": "^1.16", "sebastian/environment": "^5.0 || ^3.0 || ^2.0 || ^1.0" }, "type": "library", "autoload": { "psr-4": { - "React\\ChildProcess\\": "src" + "React\\ChildProcess\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1375,44 +1579,40 @@ ], "support": { "issues": "https://github.com/reactphp/child-process/issues", - "source": "https://github.com/reactphp/child-process/tree/v0.6.5" + "source": "https://github.com/reactphp/child-process/tree/v0.6.6" }, "funding": [ { - "url": "https://github.com/WyriHaximus", - "type": "github" - }, - { - "url": "https://github.com/clue", - "type": "github" + "url": "https://opencollective.com/reactphp", + "type": "open_collective" } ], - "time": "2022-09-16T13:41:56+00:00" + "time": "2025-01-01T16:37:48+00:00" }, { "name": "react/dns", - "version": "v1.12.0", + "version": "v1.13.0", "source": { "type": "git", "url": "https://github.com/reactphp/dns.git", - "reference": "c134600642fa615b46b41237ef243daa65bb64ec" + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/dns/zipball/c134600642fa615b46b41237ef243daa65bb64ec", - "reference": "c134600642fa615b46b41237ef243daa65bb64ec", + "url": "https://api.github.com/repos/reactphp/dns/zipball/eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", + "reference": "eb8ae001b5a455665c89c1df97f6fb682f8fb0f5", "shasum": "" }, "require": { "php": ">=5.3.0", "react/cache": "^1.0 || ^0.6 || ^0.5", "react/event-loop": "^1.2", - "react/promise": "^3.0 || ^2.7 || ^1.2.1" + "react/promise": "^3.2 || ^2.7 || ^1.2.1" }, "require-dev": { "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4 || ^3 || ^2", - "react/promise-timer": "^1.9" + "react/async": "^4.3 || ^3 || ^2", + "react/promise-timer": "^1.11" }, "type": "library", "autoload": { @@ -1455,7 +1655,7 @@ ], "support": { "issues": "https://github.com/reactphp/dns/issues", - "source": "https://github.com/reactphp/dns/tree/v1.12.0" + "source": "https://github.com/reactphp/dns/tree/v1.13.0" }, "funding": [ { @@ -1463,7 +1663,7 @@ "type": "open_collective" } ], - "time": "2023-11-29T12:41:06+00:00" + "time": "2024-06-13T14:18:03+00:00" }, { "name": "react/event-loop", @@ -1612,31 +1812,31 @@ }, { "name": "react/socket", - "version": "v1.15.0", + "version": "v1.16.0", "source": { "type": "git", "url": "https://github.com/reactphp/socket.git", - "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038" + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/socket/zipball/216d3aec0b87f04a40ca04f481e6af01bdd1d038", - "reference": "216d3aec0b87f04a40ca04f481e6af01bdd1d038", + "url": "https://api.github.com/repos/reactphp/socket/zipball/23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", + "reference": "23e4ff33ea3e160d2d1f59a0e6050e4b0fb0eac1", "shasum": "" }, "require": { "evenement/evenement": "^3.0 || ^2.0 || ^1.0", "php": ">=5.3.0", - "react/dns": "^1.11", + "react/dns": "^1.13", "react/event-loop": "^1.2", - "react/promise": "^3 || ^2.6 || ^1.2.1", - "react/stream": "^1.2" + "react/promise": "^3.2 || ^2.6 || ^1.2.1", + "react/stream": "^1.4" }, "require-dev": { "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36", - "react/async": "^4 || ^3 || ^2", + "react/async": "^4.3 || ^3.3 || ^2", "react/promise-stream": "^1.4", - "react/promise-timer": "^1.10" + "react/promise-timer": "^1.11" }, "type": "library", "autoload": { @@ -1680,7 +1880,7 @@ ], "support": { "issues": "https://github.com/reactphp/socket/issues", - "source": "https://github.com/reactphp/socket/tree/v1.15.0" + "source": "https://github.com/reactphp/socket/tree/v1.16.0" }, "funding": [ { @@ -1688,20 +1888,20 @@ "type": "open_collective" } ], - "time": "2023-12-15T11:02:10+00:00" + "time": "2024-07-26T10:38:09+00:00" }, { "name": "react/stream", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/reactphp/stream.git", - "reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66" + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/reactphp/stream/zipball/6fbc9672905c7d5a885f2da2fc696f65840f4a66", - "reference": "6fbc9672905c7d5a885f2da2fc696f65840f4a66", + "url": "https://api.github.com/repos/reactphp/stream/zipball/1e5b0acb8fe55143b5b426817155190eb6f5b18d", + "reference": "1e5b0acb8fe55143b5b426817155190eb6f5b18d", "shasum": "" }, "require": { @@ -1711,7 +1911,7 @@ }, "require-dev": { "clue/stream-filter": "~1.2", - "phpunit/phpunit": "^9.5 || ^5.7 || ^4.8.35" + "phpunit/phpunit": "^9.6 || ^5.7 || ^4.8.36" }, "type": "library", "autoload": { @@ -1758,7 +1958,7 @@ ], "support": { "issues": "https://github.com/reactphp/stream/issues", - "source": "https://github.com/reactphp/stream/tree/v1.3.0" + "source": "https://github.com/reactphp/stream/tree/v1.4.0" }, "funding": [ { @@ -1766,33 +1966,33 @@ "type": "open_collective" } ], - "time": "2023-06-16T10:52:11+00:00" + "time": "2024-06-11T12:45:25+00:00" }, { "name": "sebastian/diff", - "version": "4.0.6", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", - "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/b4ccd857127db5d41a5b676f24b51371d76d8544", + "reference": "b4ccd857127db5d41a5b676f24b51371d76d8544", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3", + "phpunit/phpunit": "^11.0", "symfony/process": "^4.2 || ^5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -1824,7 +2024,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.2" }, "funding": [ { @@ -1832,20 +2033,20 @@ "type": "github" } ], - "time": "2024-03-02T06:30:58+00:00" + "time": "2024-07-03T04:53:05+00:00" }, { "name": "sweetrdf/easyrdf", - "version": "1.14.1", + "version": "1.16.1", "source": { "type": "git", "url": "https://github.com/sweetrdf/easyrdf.git", - "reference": "b5eeeb31795fedd773acd867a461aeba75f8a347" + "reference": "f42130dc7188f89f5fc9539e3be0dc854145dd77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/b5eeeb31795fedd773acd867a461aeba75f8a347", - "reference": "b5eeeb31795fedd773acd867a461aeba75f8a347", + "url": "https://api.github.com/repos/sweetrdf/easyrdf/zipball/f42130dc7188f89f5fc9539e3be0dc854145dd77", + "reference": "f42130dc7188f89f5fc9539e3be0dc854145dd77", "shasum": "" }, "require": { @@ -1870,6 +2071,10 @@ "semsol/arc2": "^3", "zendframework/zend-http": "^2" }, + "suggest": { + "ml/json-ld": "^1.0", + "semsol/arc2": "^3" + }, "type": "library", "autoload": { "psr-4": { @@ -1911,9 +2116,9 @@ ], "support": { "issues": "https://github.com/sweetrdf/easyrdf/issues", - "source": "https://github.com/sweetrdf/easyrdf/tree/1.14.1" + "source": "https://github.com/sweetrdf/easyrdf/tree/1.16.1" }, - "time": "2024-05-27T10:24:12+00:00" + "time": "2025-01-28T18:31:07+00:00" }, { "name": "sweetrdf/rdf-helpers", @@ -1965,16 +2170,16 @@ }, { "name": "sweetrdf/rdf-interface", - "version": "2.0.0", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/sweetrdf/rdfInterface.git", - "reference": "9a8c01779a214fa37f3420aa1d7228d51c170a19" + "reference": "eeee78832fe87c3ee6834df67b5b0cfb73eb503b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/9a8c01779a214fa37f3420aa1d7228d51c170a19", - "reference": "9a8c01779a214fa37f3420aa1d7228d51c170a19", + "url": "https://api.github.com/repos/sweetrdf/rdfInterface/zipball/eeee78832fe87c3ee6834df67b5b0cfb73eb503b", + "reference": "eeee78832fe87c3ee6834df67b5b0cfb73eb503b", "shasum": "" }, "require": { @@ -2006,22 +2211,22 @@ "homepage": "https://github.com/sweetrdf/rdfInterface", "support": { "issues": "https://github.com/sweetrdf/rdfInterface/issues", - "source": "https://github.com/sweetrdf/rdfInterface/tree/2.0.0" + "source": "https://github.com/sweetrdf/rdfInterface/tree/2.1.0" }, - "time": "2024-02-09T12:03:33+00:00" + "time": "2024-11-22T19:09:12+00:00" }, { "name": "symfony/config", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "c4a60be1c7ec93aa8b7f19e07b6427143a502ef4" + "reference": "7716594aaae91d9141be080240172a92ecca4d44" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/c4a60be1c7ec93aa8b7f19e07b6427143a502ef4", - "reference": "c4a60be1c7ec93aa8b7f19e07b6427143a502ef4", + "url": "https://api.github.com/repos/symfony/config/zipball/7716594aaae91d9141be080240172a92ecca4d44", + "reference": "7716594aaae91d9141be080240172a92ecca4d44", "shasum": "" }, "require": { @@ -2067,7 +2272,7 @@ "description": "Helps you find, load, combine, autofill and validate configuration values of any kind", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/config/tree/v7.1.0" + "source": "https://github.com/symfony/config/tree/v7.2.3" }, "funding": [ { @@ -2083,20 +2288,20 @@ "type": "tidelift" } ], - "time": "2024-05-28T06:54:05+00:00" + "time": "2025-01-22T12:07:01+00:00" }, { "name": "symfony/console", - "version": "v7.1.0", + "version": "v7.2.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "5bcde9e0b2ea9bd9772bca17618365ea921c5707" + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/5bcde9e0b2ea9bd9772bca17618365ea921c5707", - "reference": "5bcde9e0b2ea9bd9772bca17618365ea921c5707", + "url": "https://api.github.com/repos/symfony/console/zipball/fefcc18c0f5d0efe3ab3152f15857298868dc2c3", + "reference": "fefcc18c0f5d0efe3ab3152f15857298868dc2c3", "shasum": "" }, "require": { @@ -2160,7 +2365,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v7.1.0" + "source": "https://github.com/symfony/console/tree/v7.2.1" }, "funding": [ { @@ -2176,20 +2381,20 @@ "type": "tidelift" } ], - "time": "2024-05-17T10:55:18+00:00" + "time": "2024-12-11T03:49:26+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1" + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", - "reference": "0e0d29ce1f20deffb4ab1b016a7257c4f1e789a1", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", + "reference": "74c71c939a79f7d5bf3c1ce9f5ea37ba0114c6f6", "shasum": "" }, "require": { @@ -2197,12 +2402,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2227,7 +2432,7 @@ "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.5.1" }, "funding": [ { @@ -2243,20 +2448,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "522d2772d6c7bab843b0c52466dc7844622bacc2" + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/522d2772d6c7bab843b0c52466dc7844622bacc2", - "reference": "522d2772d6c7bab843b0c52466dc7844622bacc2", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/910c5db85a5356d0fea57680defec4e99eb9c8c1", + "reference": "910c5db85a5356d0fea57680defec4e99eb9c8c1", "shasum": "" }, "require": { @@ -2307,7 +2512,7 @@ "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/event-dispatcher/tree/v7.1.0" + "source": "https://github.com/symfony/event-dispatcher/tree/v7.2.0" }, "funding": [ { @@ -2323,20 +2528,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "symfony/event-dispatcher-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50" + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/8f93aec25d41b72493c6ddff14e916177c9efc50", - "reference": "8f93aec25d41b72493c6ddff14e916177c9efc50", + "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/7642f5e970b672283b7823222ae8ef8bbc160b9f", + "reference": "7642f5e970b672283b7823222ae8ef8bbc160b9f", "shasum": "" }, "require": { @@ -2345,12 +2550,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -2383,7 +2588,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/event-dispatcher-contracts/tree/v3.5.1" }, "funding": [ { @@ -2399,20 +2604,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/filesystem", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "8ecdde25881598f86cdd7cfe8b25302b66a402e9" + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/8ecdde25881598f86cdd7cfe8b25302b66a402e9", - "reference": "8ecdde25881598f86cdd7cfe8b25302b66a402e9", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8dce482de9d7c9fe2891155035a7248ab5c7fdb", + "reference": "b8dce482de9d7c9fe2891155035a7248ab5c7fdb", "shasum": "" }, "require": { @@ -2449,7 +2654,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/filesystem/tree/v7.1.0" + "source": "https://github.com/symfony/filesystem/tree/v7.2.0" }, "funding": [ { @@ -2465,20 +2670,20 @@ "type": "tidelift" } ], - "time": "2024-05-17T10:55:18+00:00" + "time": "2024-10-25T15:15:23+00:00" }, { "name": "symfony/finder", - "version": "v7.1.0", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "fb6c2d65c3dbf7ad83201a4168d4510c8dddaac7" + "reference": "87a71856f2f56e4100373e92529eed3171695cfb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/fb6c2d65c3dbf7ad83201a4168d4510c8dddaac7", - "reference": "fb6c2d65c3dbf7ad83201a4168d4510c8dddaac7", + "url": "https://api.github.com/repos/symfony/finder/zipball/87a71856f2f56e4100373e92529eed3171695cfb", + "reference": "87a71856f2f56e4100373e92529eed3171695cfb", "shasum": "" }, "require": { @@ -2513,7 +2718,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/finder/tree/v7.1.0" + "source": "https://github.com/symfony/finder/tree/v7.2.2" }, "funding": [ { @@ -2529,20 +2734,20 @@ "type": "tidelift" } ], - "time": "2024-04-28T18:29:00+00:00" + "time": "2024-12-30T19:00:17+00:00" }, { "name": "symfony/options-resolver", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/options-resolver.git", - "reference": "9564f64c16f99e29f252eafc642965e8fcb755ce" + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/9564f64c16f99e29f252eafc642965e8fcb755ce", - "reference": "9564f64c16f99e29f252eafc642965e8fcb755ce", + "url": "https://api.github.com/repos/symfony/options-resolver/zipball/7da8fbac9dcfef75ffc212235d76b2754ce0cf50", + "reference": "7da8fbac9dcfef75ffc212235d76b2754ce0cf50", "shasum": "" }, "require": { @@ -2580,7 +2785,7 @@ "options" ], "support": { - "source": "https://github.com/symfony/options-resolver/tree/v7.1.0" + "source": "https://github.com/symfony/options-resolver/tree/v7.2.0" }, "funding": [ { @@ -2596,24 +2801,24 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-11-20T11:17:29+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4" + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/ef4d7e442ca910c4764bce785146269b30cb5fc4", - "reference": "ef4d7e442ca910c4764bce785146269b30cb5fc4", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/a3cc8b044a6ea513310cbd48ef7333b384945638", + "reference": "a3cc8b044a6ea513310cbd48ef7333b384945638", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-ctype": "*" @@ -2624,8 +2829,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2659,7 +2864,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.31.0" }, "funding": [ { @@ -2675,24 +2880,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f" + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/32a9da87d7b3245e09ac426c83d334ae9f06f80f", - "reference": "32a9da87d7b3245e09ac426c83d334ae9f06f80f", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", + "reference": "b9123926e3b7bc2f98c02ad54f6a4b02b91a8abe", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -2700,8 +2905,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2737,7 +2942,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.31.0" }, "funding": [ { @@ -2753,24 +2958,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d" + "reference": "3833d7255cc303546435cb650316bff708a1c75c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/bc45c394692b948b4d383a08d7753968bed9a83d", - "reference": "bc45c394692b948b4d383a08d7753968bed9a83d", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/3833d7255cc303546435cb650316bff708a1c75c", + "reference": "3833d7255cc303546435cb650316bff708a1c75c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "suggest": { "ext-intl": "For best performance" @@ -2778,8 +2983,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2818,7 +3023,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.31.0" }, "funding": [ { @@ -2834,24 +3039,24 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec" + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9773676c8a1bb1f8d4340a62efe641cf76eda7ec", - "reference": "9773676c8a1bb1f8d4340a62efe641cf76eda7ec", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/85181ba99b2345b0ef10ce42ecac37612d9fd341", + "reference": "85181ba99b2345b0ef10ce42ecac37612d9fd341", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "provide": { "ext-mbstring": "*" @@ -2862,8 +3067,8 @@ "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2898,7 +3103,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.31.0" }, "funding": [ { @@ -2914,30 +3119,30 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b" + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", - "reference": "87b68208d5c1188808dd7839ee1e6c8ec3b02f1b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", + "reference": "60328e362d4c2c802a54fcbf04f9d3fb892b4cf8", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -2978,7 +3183,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.31.0" }, "funding": [ { @@ -2994,30 +3199,30 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/polyfill-php81", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php81.git", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d" + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/c565ad1e63f30e7477fc40738343c62b40bc672d", - "reference": "c565ad1e63f30e7477fc40738343c62b40bc672d", + "url": "https://api.github.com/repos/symfony/polyfill-php81/zipball/4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", + "reference": "4a4cfc2d253c21a5ad0e53071df248ed48c6ce5c", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -3054,7 +3259,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php81/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php81/tree/v1.31.0" }, "funding": [ { @@ -3070,20 +3275,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/process", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "56c8a1ea51eb70003fee94a78c7d6d0f44832ce7" + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/56c8a1ea51eb70003fee94a78c7d6d0f44832ce7", - "reference": "56c8a1ea51eb70003fee94a78c7d6d0f44832ce7", + "url": "https://api.github.com/repos/symfony/process/zipball/d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", + "reference": "d34b22ba9390ec19d2dd966c40aa9e8462f27a7e", "shasum": "" }, "require": { @@ -3115,7 +3320,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/process/tree/v7.1.0" + "source": "https://github.com/symfony/process/tree/v7.2.0" }, "funding": [ { @@ -3131,20 +3336,20 @@ "type": "tidelift" } ], - "time": "2024-05-17T10:55:18+00:00" + "time": "2024-11-06T14:24:19+00:00" }, { "name": "symfony/service-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f" + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", - "reference": "bd1d9e59a81d8fa4acdcea3f617c581f7475a80f", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/e53260aabf78fb3d63f8d79d69ece59f80d5eda0", + "reference": "e53260aabf78fb3d63f8d79d69ece59f80d5eda0", "shasum": "" }, "require": { @@ -3157,12 +3362,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -3198,7 +3403,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/service-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/service-contracts/tree/v3.5.1" }, "funding": [ { @@ -3214,20 +3419,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/stopwatch", - "version": "v7.1.0", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/stopwatch.git", - "reference": "13c750a45ac43c45f45d944d22499768aa1b72d8" + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/13c750a45ac43c45f45d944d22499768aa1b72d8", - "reference": "13c750a45ac43c45f45d944d22499768aa1b72d8", + "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e46690d5b9d7164a6d061cab1e8d46141b9f49df", + "reference": "e46690d5b9d7164a6d061cab1e8d46141b9f49df", "shasum": "" }, "require": { @@ -3260,7 +3465,7 @@ "description": "Provides a way to profile code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/stopwatch/tree/v7.1.0" + "source": "https://github.com/symfony/stopwatch/tree/v7.2.2" }, "funding": [ { @@ -3276,20 +3481,20 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-12-18T14:28:33+00:00" }, { "name": "symfony/string", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "6f41b185e742737917e6f2e3eca37767fba5f17a" + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/6f41b185e742737917e6f2e3eca37767fba5f17a", - "reference": "6f41b185e742737917e6f2e3eca37767fba5f17a", + "url": "https://api.github.com/repos/symfony/string/zipball/446e0d146f991dde3e73f45f2c97a9faad773c82", + "reference": "446e0d146f991dde3e73f45f2c97a9faad773c82", "shasum": "" }, "require": { @@ -3347,7 +3552,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v7.1.0" + "source": "https://github.com/symfony/string/tree/v7.2.0" }, "funding": [ { @@ -3363,24 +3568,25 @@ "type": "tidelift" } ], - "time": "2024-05-17T10:55:18+00:00" + "time": "2024-11-13T13:31:26+00:00" }, { "name": "symfony/yaml", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "c5f718c94e3c37dd77b77484e6cf0b524b2d405e" + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/c5f718c94e3c37dd77b77484e6cf0b524b2d405e", - "reference": "c5f718c94e3c37dd77b77484e6cf0b524b2d405e", + "url": "https://api.github.com/repos/symfony/yaml/zipball/ac238f173df0c9c1120f862d0f599e17535a87ec", + "reference": "ac238f173df0c9c1120f862d0f599e17535a87ec", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { @@ -3418,7 +3624,7 @@ "description": "Loads and dumps YAML files", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/yaml/tree/v7.1.0" + "source": "https://github.com/symfony/yaml/tree/v7.2.3" }, "funding": [ { @@ -3434,30 +3640,31 @@ "type": "tidelift" } ], - "time": "2024-04-28T18:29:00+00:00" + "time": "2025-01-07T12:55:42+00:00" }, { "name": "twig/twig", - "version": "v3.10.3", + "version": "v3.19.0", "source": { "type": "git", "url": "https://github.com/twigphp/Twig.git", - "reference": "67f29781ffafa520b0bbfbd8384674b42db04572" + "reference": "d4f8c2b86374f08efc859323dbcd95c590f7124e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/twigphp/Twig/zipball/67f29781ffafa520b0bbfbd8384674b42db04572", - "reference": "67f29781ffafa520b0bbfbd8384674b42db04572", + "url": "https://api.github.com/repos/twigphp/Twig/zipball/d4f8c2b86374f08efc859323dbcd95c590f7124e", + "reference": "d4f8c2b86374f08efc859323dbcd95c590f7124e", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "^1.8", "symfony/polyfill-mbstring": "^1.3", - "symfony/polyfill-php80": "^1.22" + "symfony/polyfill-php81": "^1.29" }, "require-dev": { + "phpstan/phpstan": "^2.0", "psr/container": "^1.0|^2.0", "symfony/phpunit-bridge": "^5.4.9|^6.4|^7.0" }, @@ -3501,7 +3708,7 @@ ], "support": { "issues": "https://github.com/twigphp/Twig/issues", - "source": "https://github.com/twigphp/Twig/tree/v3.10.3" + "source": "https://github.com/twigphp/Twig/tree/v3.19.0" }, "funding": [ { @@ -3513,7 +3720,7 @@ "type": "tidelift" } ], - "time": "2024-05-16T10:04:27+00:00" + "time": "2025-01-29T07:06:14+00:00" }, { "name": "zozlak/rdf-constants", @@ -3557,21 +3764,21 @@ "packages-dev": [ { "name": "api-platform/core", - "version": "v3.3.5", + "version": "v4.0.16", "source": { "type": "git", "url": "https://github.com/api-platform/core.git", - "reference": "b5a93fb0bb855273aabb0807505ba61b68813246" + "reference": "6cc70d3bc9695cb323a7117c90d992c8ca959ec1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/api-platform/core/zipball/b5a93fb0bb855273aabb0807505ba61b68813246", - "reference": "b5a93fb0bb855273aabb0807505ba61b68813246", + "url": "https://api.github.com/repos/api-platform/core/zipball/6cc70d3bc9695cb323a7117c90d992c8ca959ec1", + "reference": "6cc70d3bc9695cb323a7117c90d992c8ca959ec1", "shasum": "" }, "require": { "doctrine/inflector": "^1.0 || ^2.0", - "php": ">=8.1", + "php": ">=8.2", "psr/cache": "^1.0 || ^2.0 || ^3.0", "psr/container": "^1.0 || ^2.0", "symfony/deprecation-contracts": "^3.1", @@ -3582,7 +3789,7 @@ "symfony/serializer": "^6.4 || ^7.0", "symfony/translation-contracts": "^3.3", "symfony/web-link": "^6.4 || ^7.0", - "willdurand/negotiation": "^3.0" + "willdurand/negotiation": "^3.1" }, "conflict": { "doctrine/common": "<3.2.2", @@ -3590,43 +3797,73 @@ "doctrine/mongodb-odm": "<2.4", "doctrine/orm": "<2.14.0", "doctrine/persistence": "<1.3", - "elasticsearch/elasticsearch": ">=8.0,<8.4", "phpspec/prophecy": "<1.15", "phpunit/phpunit": "<9.5", "symfony/framework-bundle": "6.4.6 || 7.0.6", "symfony/var-exporter": "<6.1.1" }, + "replace": { + "api-platform/doctrine-common": "self.version", + "api-platform/doctrine-odm": "self.version", + "api-platform/doctrine-orm": "self.version", + "api-platform/documentation": "self.version", + "api-platform/elasticsearch": "self.version", + "api-platform/graphql": "self.version", + "api-platform/http-cache": "self.version", + "api-platform/hydra": "self.version", + "api-platform/json-api": "self.version", + "api-platform/json-hal": "self.version", + "api-platform/json-schema": "self.version", + "api-platform/jsonld": "self.version", + "api-platform/laravel": "self.version", + "api-platform/metadata": "self.version", + "api-platform/openapi": "self.version", + "api-platform/parameter-validator": "self.version", + "api-platform/ramsey-uuid": "self.version", + "api-platform/serializer": "self.version", + "api-platform/state": "self.version", + "api-platform/symfony": "self.version", + "api-platform/validator": "self.version" + }, "require-dev": { "behat/behat": "^3.11", "behat/mink": "^1.9", "doctrine/cache": "^1.11 || ^2.1", "doctrine/common": "^3.2.2", - "doctrine/dbal": "^3.4.0", - "doctrine/doctrine-bundle": "^1.12 || ^2.0", - "doctrine/mongodb-odm": "^2.2", + "doctrine/dbal": "^4.0", + "doctrine/doctrine-bundle": "^2.11", + "doctrine/mongodb-odm": "^2.6", "doctrine/mongodb-odm-bundle": "^4.0 || ^5.0", - "doctrine/orm": "^2.14 || ^3.0", - "elasticsearch/elasticsearch": "^7.11 || ^8.4", + "doctrine/orm": "^2.17 || ^3.0", + "elasticsearch/elasticsearch": "^8.4", "friends-of-behat/mink-browserkit-driver": "^1.3.1", "friends-of-behat/mink-extension": "^2.2", "friends-of-behat/symfony-extension": "^2.1", "guzzlehttp/guzzle": "^6.0 || ^7.0", + "illuminate/config": "^11.0", + "illuminate/contracts": "^11.0", + "illuminate/database": "^11.0", + "illuminate/http": "^11.0", + "illuminate/pagination": "^11.0", + "illuminate/routing": "^11.0", + "illuminate/support": "^11.0", "jangregor/phpstan-prophecy": "^1.0", - "justinrainbow/json-schema": "^5.2.1", - "phpspec/prophecy-phpunit": "^2.0", + "justinrainbow/json-schema": "^5.2.11", + "laravel/framework": "^11.0", + "orchestra/testbench": "^9.1", + "phpspec/prophecy-phpunit": "^2.2", "phpstan/extension-installer": "^1.1", - "phpstan/phpdoc-parser": "^1.13", + "phpstan/phpdoc-parser": "^1.13|^2.0", "phpstan/phpstan": "^1.10", "phpstan/phpstan-doctrine": "^1.0", "phpstan/phpstan-phpunit": "^1.0", "phpstan/phpstan-symfony": "^1.0", - "phpunit/phpunit": "^9.6", + "phpunit/phpunit": "^11.2", "psr/log": "^1.0 || ^2.0 || ^3.0", - "ramsey/uuid": "^3.9.7 || ^4.0", - "ramsey/uuid-doctrine": "^1.4 || ^2.0", - "sebastian/comparator": "<5.0", - "soyuka/contexts": "v3.3.9", - "soyuka/pmu": "^0.0.2", + "ramsey/uuid": "^4.0", + "ramsey/uuid-doctrine": "^2.0", + "soyuka/contexts": "^3.3.10", + "soyuka/pmu": "^0.0.15", "soyuka/stubs-mongodb": "^1.0", "symfony/asset": "^6.4 || ^7.0", "symfony/browser-kit": "^6.4 || ^7.0", @@ -3634,8 +3871,8 @@ "symfony/config": "^6.4 || ^7.0", "symfony/console": "^6.4 || ^7.0", "symfony/css-selector": "^6.4 || ^7.0", - "symfony/dependency-injection": "^6.4 || ^7.0.12", - "symfony/doctrine-bridge": "^6.4 || ^7.0", + "symfony/dependency-injection": "^6.4 || ^7.0", + "symfony/doctrine-bridge": "^6.4.2 || ^7.0.2", "symfony/dom-crawler": "^6.4 || ^7.0", "symfony/error-handler": "^6.4 || ^7.0", "symfony/event-dispatcher": "^6.4 || ^7.0", @@ -3648,18 +3885,18 @@ "symfony/maker-bundle": "^1.24", "symfony/mercure-bundle": "*", "symfony/messenger": "^6.4 || ^7.0", - "symfony/phpunit-bridge": "^6.4.1 || ^7.0", "symfony/routing": "^6.4 || ^7.0", "symfony/security-bundle": "^6.4 || ^7.0", "symfony/security-core": "^6.4 || ^7.0", "symfony/stopwatch": "^6.4 || ^7.0", + "symfony/string": "^6.4 || ^7.0", "symfony/twig-bundle": "^6.4 || ^7.0", "symfony/uid": "^6.4 || ^7.0", "symfony/validator": "^6.4 || ^7.0", "symfony/web-profiler-bundle": "^6.4 || ^7.0", "symfony/yaml": "^6.4 || ^7.0", "twig/twig": "^1.42.3 || ^2.12 || ^3.0", - "webonyx/graphql-php": "^14.0 || ^15.0" + "webonyx/graphql-php": "^15.0" }, "suggest": { "doctrine/mongodb-odm-bundle": "To support MongoDB. Only versions 4.0 and later are supported.", @@ -3681,34 +3918,28 @@ }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "3.3.x-dev" + "pmu": { + "projects": [ + "./src/*/composer.json", + "src/Doctrine/*/composer.json" + ] + }, + "thanks": { + "url": "https://github.com/api-platform/api-platform", + "name": "api-platform/api-platform" }, "symfony": { - "require": "^6.4 || ^7.0" - }, - "projects": [ - "api-platform/doctrine-common", - "api-platform/doctrine-orm", - "api-platform/doctrine-odm", - "api-platform/metadata", - "api-platform/json-schema", - "api-platform/elasticsearch", - "api-platform/jsonld", - "api-platform/hydra", - "api-platform/openapi", - "api-platform/graphql", - "api-platform/http-cache", - "api-platform/documentation", - "api-platform/parameter-validator", - "api-platform/ramsey-uuid", - "api-platform/serializer", - "api-platform/state", - "api-platform/symfony", - "api-platform/validator" - ] + "require": "^6.4 || ^7.1" + }, + "branch-alias": { + "dev-3.4": "3.4.x-dev", + "dev-main": "4.0.x-dev" + } }, "autoload": { + "files": [ + "src/JsonLd/HydraContext.php" + ], "psr-4": { "ApiPlatform\\": "src/" } @@ -3733,108 +3964,17 @@ "graphql", "hal", "jsonapi", + "laravel", "openapi", "rest", - "swagger" + "swagger", + "symfony" ], "support": { "issues": "https://github.com/api-platform/core/issues", - "source": "https://github.com/api-platform/core/tree/v3.3.5" - }, - "time": "2024-05-29T05:48:47+00:00" - }, - { - "name": "doctrine/cache", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/1ca8f21980e770095a31456042471a57bc4c68fb", - "reference": "1ca8f21980e770095a31456042471a57bc4c68fb", - "shasum": "" - }, - "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "doctrine/coding-standard": "^9", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psr/cache": "^1.0 || ^2.0 || ^3.0", - "symfony/cache": "^4.4 || ^5.4 || ^6", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", - "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" - ], - "support": { - "issues": "https://github.com/doctrine/cache/issues", - "source": "https://github.com/doctrine/cache/tree/2.2.0" + "source": "https://github.com/api-platform/core/tree/v4.0.16" }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", - "type": "tidelift" - } - ], - "time": "2022-05-20T20:07:39+00:00" + "time": "2025-01-17T14:21:29+00:00" }, { "name": "doctrine/collections", @@ -3923,143 +4063,45 @@ "time": "2024-04-18T06:56:21+00:00" }, { - "name": "doctrine/common", - "version": "3.4.4", + "name": "doctrine/dbal", + "version": "4.2.2", "source": { "type": "git", - "url": "https://github.com/doctrine/common.git", - "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a" + "url": "https://github.com/doctrine/dbal.git", + "reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/common/zipball/0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", - "reference": "0aad4b7ab7ce8c6602dfbb1e1a24581275fb9d1a", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/19a2b7deb5fe8c2df0ff817ecea305e50acb62ec", + "reference": "19a2b7deb5fe8c2df0ff817ecea305e50acb62ec", "shasum": "" }, "require": { - "doctrine/persistence": "^2.0 || ^3.0", - "php": "^7.1 || ^8.0" + "doctrine/deprecations": "^0.5.3|^1", + "php": "^8.1", + "psr/cache": "^1|^2|^3", + "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "^9.0 || ^10.0", - "doctrine/collections": "^1", - "phpstan/phpstan": "^1.4.1", - "phpstan/phpstan-phpunit": "^1", - "phpunit/phpunit": "^7.5.20 || ^8.5 || ^9.0", - "squizlabs/php_codesniffer": "^3.0", - "symfony/phpunit-bridge": "^6.1", - "vimeo/psalm": "^4.4" + "doctrine/coding-standard": "12.0.0", + "fig/log-test": "^1", + "jetbrains/phpstorm-stubs": "2023.2", + "phpstan/phpstan": "2.1.1", + "phpstan/phpstan-phpunit": "2.0.3", + "phpstan/phpstan-strict-rules": "^2", + "phpunit/phpunit": "10.5.39", + "slevomat/coding-standard": "8.13.1", + "squizlabs/php_codesniffer": "3.10.2", + "symfony/cache": "^6.3.8|^7.0", + "symfony/console": "^5.4|^6.3|^7.0" + }, + "suggest": { + "symfony/console": "For helpful console commands such as SQL execution and import of files." }, "type": "library", "autoload": { "psr-4": { - "Doctrine\\Common\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - }, - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com" - } - ], - "description": "PHP Doctrine Common project is a library that provides additional functionality that other Doctrine projects depend on such as better reflection support, proxies and much more.", - "homepage": "https://www.doctrine-project.org/projects/common.html", - "keywords": [ - "common", - "doctrine", - "php" - ], - "support": { - "issues": "https://github.com/doctrine/common/issues", - "source": "https://github.com/doctrine/common/tree/3.4.4" - }, - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcommon", - "type": "tidelift" - } - ], - "time": "2024-04-16T13:35:33+00:00" - }, - { - "name": "doctrine/dbal", - "version": "3.8.4", - "source": { - "type": "git", - "url": "https://github.com/doctrine/dbal.git", - "reference": "b05e48a745f722801f55408d0dbd8003b403dbbd" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/b05e48a745f722801f55408d0dbd8003b403dbbd", - "reference": "b05e48a745f722801f55408d0dbd8003b403dbbd", - "shasum": "" - }, - "require": { - "composer-runtime-api": "^2", - "doctrine/cache": "^1.11|^2.0", - "doctrine/deprecations": "^0.5.3|^1", - "doctrine/event-manager": "^1|^2", - "php": "^7.4 || ^8.0", - "psr/cache": "^1|^2|^3", - "psr/log": "^1|^2|^3" - }, - "require-dev": { - "doctrine/coding-standard": "12.0.0", - "fig/log-test": "^1", - "jetbrains/phpstorm-stubs": "2023.1", - "phpstan/phpstan": "1.10.58", - "phpstan/phpstan-strict-rules": "^1.5", - "phpunit/phpunit": "9.6.16", - "psalm/plugin-phpunit": "0.18.4", - "slevomat/coding-standard": "8.13.1", - "squizlabs/php_codesniffer": "3.9.0", - "symfony/cache": "^5.4|^6.0|^7.0", - "symfony/console": "^4.4|^5.4|^6.0|^7.0", - "vimeo/psalm": "4.30.0" - }, - "suggest": { - "symfony/console": "For helpful console commands such as SQL execution and import of files." - }, - "bin": [ - "bin/doctrine-dbal" - ], - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\DBAL\\": "src" + "Doctrine\\DBAL\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4108,7 +4150,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.8.4" + "source": "https://github.com/doctrine/dbal/tree/4.2.2" }, "funding": [ { @@ -4124,33 +4166,31 @@ "type": "tidelift" } ], - "time": "2024-04-25T07:04:44+00:00" + "time": "2025-01-16T08:40:56+00:00" }, { "name": "doctrine/deprecations", - "version": "1.1.3", + "version": "1.1.4", "source": { "type": "git", "url": "https://github.com/doctrine/deprecations.git", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab" + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/deprecations/zipball/dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", - "reference": "dfbaa3c2d2e9a9df1118213f3b8b0c597bb99fab", + "url": "https://api.github.com/repos/doctrine/deprecations/zipball/31610dbb31faa98e6b5447b62340826f54fbc4e9", + "reference": "31610dbb31faa98e6b5447b62340826f54fbc4e9", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "require-dev": { - "doctrine/coding-standard": "^9", - "phpstan/phpstan": "1.4.10 || 1.10.15", - "phpstan/phpstan-phpunit": "^1.0", + "doctrine/coding-standard": "^9 || ^12", + "phpstan/phpstan": "1.4.10 || 2.0.3", + "phpstan/phpstan-phpunit": "^1.0 || ^2", "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", - "psalm/plugin-phpunit": "0.18.4", - "psr/log": "^1 || ^2 || ^3", - "vimeo/psalm": "4.30.0 || 5.12.0" + "psr/log": "^1 || ^2 || ^3" }, "suggest": { "psr/log": "Allows logging deprecations via PSR-3 logger implementation" @@ -4158,7 +4198,7 @@ "type": "library", "autoload": { "psr-4": { - "Doctrine\\Deprecations\\": "lib/Doctrine/Deprecations" + "Doctrine\\Deprecations\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -4169,9 +4209,9 @@ "homepage": "https://www.doctrine-project.org/", "support": { "issues": "https://github.com/doctrine/deprecations/issues", - "source": "https://github.com/doctrine/deprecations/tree/1.1.3" + "source": "https://github.com/doctrine/deprecations/tree/1.1.4" }, - "time": "2024-01-30T19:34:25+00:00" + "time": "2024-12-07T21:18:45+00:00" }, { "name": "doctrine/event-manager", @@ -4413,61 +4453,50 @@ }, { "name": "doctrine/orm", - "version": "2.19.5", + "version": "3.3.1", "source": { "type": "git", "url": "https://github.com/doctrine/orm.git", - "reference": "94986af28452da42a46a4489d1c958a2e5d710e5" + "reference": "b1f8253105aa5382c495e5f9f8ef34e297775428" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/orm/zipball/94986af28452da42a46a4489d1c958a2e5d710e5", - "reference": "94986af28452da42a46a4489d1c958a2e5d710e5", + "url": "https://api.github.com/repos/doctrine/orm/zipball/b1f8253105aa5382c495e5f9f8ef34e297775428", + "reference": "b1f8253105aa5382c495e5f9f8ef34e297775428", "shasum": "" }, "require": { "composer-runtime-api": "^2", - "doctrine/cache": "^1.12.1 || ^2.1.1", - "doctrine/collections": "^1.5 || ^2.1", - "doctrine/common": "^3.0.3", - "doctrine/dbal": "^2.13.1 || ^3.2", + "doctrine/collections": "^2.2", + "doctrine/dbal": "^3.8.2 || ^4", "doctrine/deprecations": "^0.5.3 || ^1", "doctrine/event-manager": "^1.2 || ^2", "doctrine/inflector": "^1.4 || ^2.0", "doctrine/instantiator": "^1.3 || ^2", - "doctrine/lexer": "^2 || ^3", - "doctrine/persistence": "^2.4 || ^3", + "doctrine/lexer": "^3", + "doctrine/persistence": "^3.3.1 || ^4", "ext-ctype": "*", - "php": "^7.1 || ^8.0", + "php": "^8.1", "psr/cache": "^1 || ^2 || ^3", - "symfony/console": "^4.2 || ^5.0 || ^6.0 || ^7.0", - "symfony/polyfill-php72": "^1.23", - "symfony/polyfill-php80": "^1.16" - }, - "conflict": { - "doctrine/annotations": "<1.13 || >= 3.0" + "symfony/console": "^5.4 || ^6.0 || ^7.0", + "symfony/var-exporter": "^6.3.9 || ^7.0" }, "require-dev": { - "doctrine/annotations": "^1.13 || ^2", - "doctrine/coding-standard": "^9.0.2 || ^12.0", - "phpbench/phpbench": "^0.16.10 || ^1.0", - "phpstan/phpstan": "~1.4.10 || 1.10.59", - "phpunit/phpunit": "^7.5 || ^8.5 || ^9.6", + "doctrine/coding-standard": "^12.0", + "phpbench/phpbench": "^1.0", + "phpdocumentor/guides-cli": "^1.4", + "phpstan/extension-installer": "^1.4", + "phpstan/phpstan": "2.0.3", + "phpstan/phpstan-deprecation-rules": "^2", + "phpunit/phpunit": "^10.4.0", "psr/log": "^1 || ^2 || ^3", "squizlabs/php_codesniffer": "3.7.2", - "symfony/cache": "^4.4 || ^5.4 || ^6.4 || ^7.0", - "symfony/var-exporter": "^4.4 || ^5.4 || ^6.2 || ^7.0", - "symfony/yaml": "^3.4 || ^4.0 || ^5.0 || ^6.0 || ^7.0", - "vimeo/psalm": "4.30.0 || 5.22.2" + "symfony/cache": "^5.4 || ^6.2 || ^7.0" }, "suggest": { "ext-dom": "Provides support for XSD validation for XML mapping files", - "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0", - "symfony/yaml": "If you want to use YAML Metadata Mapping Driver" + "symfony/cache": "Provides cache support for Setup Tool with doctrine/cache 2.0" }, - "bin": [ - "bin/doctrine" - ], "type": "library", "autoload": { "psr-4": { @@ -4508,42 +4537,39 @@ ], "support": { "issues": "https://github.com/doctrine/orm/issues", - "source": "https://github.com/doctrine/orm/tree/2.19.5" + "source": "https://github.com/doctrine/orm/tree/3.3.1" }, - "time": "2024-04-30T06:49:54+00:00" + "time": "2024-12-19T07:08:14+00:00" }, { "name": "doctrine/persistence", - "version": "3.3.2", + "version": "4.0.0", "source": { "type": "git", "url": "https://github.com/doctrine/persistence.git", - "reference": "477da35bd0255e032826f440b94b3e37f2d56f42" + "reference": "45004aca79189474f113cbe3a53847c2115a55fa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/persistence/zipball/477da35bd0255e032826f440b94b3e37f2d56f42", - "reference": "477da35bd0255e032826f440b94b3e37f2d56f42", + "url": "https://api.github.com/repos/doctrine/persistence/zipball/45004aca79189474f113cbe3a53847c2115a55fa", + "reference": "45004aca79189474f113cbe3a53847c2115a55fa", "shasum": "" }, "require": { "doctrine/event-manager": "^1 || ^2", - "php": "^7.2 || ^8.0", + "php": "^8.1", "psr/cache": "^1.0 || ^2.0 || ^3.0" }, "conflict": { "doctrine/common": "<2.10" }, "require-dev": { - "composer/package-versions-deprecated": "^1.11", - "doctrine/coding-standard": "^11", - "doctrine/common": "^3.0", - "phpstan/phpstan": "1.9.4", + "doctrine/coding-standard": "^12", + "phpstan/phpstan": "1.12.7", "phpstan/phpstan-phpunit": "^1", "phpstan/phpstan-strict-rules": "^1.1", - "phpunit/phpunit": "^8.5 || ^9.5", - "symfony/cache": "^4.4 || ^5.4 || ^6.0", - "vimeo/psalm": "4.30.0 || 5.3.0" + "phpunit/phpunit": "^9.6", + "symfony/cache": "^4.4 || ^5.4 || ^6.0 || ^7.0" }, "type": "library", "autoload": { @@ -4592,7 +4618,7 @@ ], "support": { "issues": "https://github.com/doctrine/persistence/issues", - "source": "https://github.com/doctrine/persistence/tree/3.3.2" + "source": "https://github.com/doctrine/persistence/tree/4.0.0" }, "funding": [ { @@ -4608,20 +4634,20 @@ "type": "tidelift" } ], - "time": "2024-03-12T14:54:36+00:00" + "time": "2024-11-01T21:49:07+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.11.1", + "version": "1.12.1", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", - "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/123267b2c49fbf30d78a7b2d333f6be754b94845", + "reference": "123267b2c49fbf30d78a7b2d333f6be754b94845", "shasum": "" }, "require": { @@ -4629,11 +4655,12 @@ }, "conflict": { "doctrine/collections": "<1.6.8", - "doctrine/common": "<2.13.3 || >=3,<3.2.2" + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, "require-dev": { "doctrine/collections": "^1.6.8", "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", @@ -4659,7 +4686,7 @@ ], "support": { "issues": "https://github.com/myclabs/DeepCopy/issues", - "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" + "source": "https://github.com/myclabs/DeepCopy/tree/1.12.1" }, "funding": [ { @@ -4667,20 +4694,20 @@ "type": "tidelift" } ], - "time": "2023-03-08T13:26:56+00:00" + "time": "2024-11-08T17:47:46+00:00" }, { "name": "myclabs/php-enum", - "version": "1.8.4", + "version": "1.8.5", "source": { "type": "git", "url": "https://github.com/myclabs/php-enum.git", - "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483" + "reference": "e7be26966b7398204a234f8673fdad5ac6277802" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/php-enum/zipball/a867478eae49c9f59ece437ae7f9506bfaa27483", - "reference": "a867478eae49c9f59ece437ae7f9506bfaa27483", + "url": "https://api.github.com/repos/myclabs/php-enum/zipball/e7be26966b7398204a234f8673fdad5ac6277802", + "reference": "e7be26966b7398204a234f8673fdad5ac6277802", "shasum": "" }, "require": { @@ -4690,7 +4717,7 @@ "require-dev": { "phpunit/phpunit": "^9.5", "squizlabs/php_codesniffer": "1.*", - "vimeo/psalm": "^4.6.2" + "vimeo/psalm": "^4.6.2 || ^5.2" }, "type": "library", "autoload": { @@ -4712,13 +4739,13 @@ } ], "description": "PHP Enum implementation", - "homepage": "http://github.com/myclabs/php-enum", + "homepage": "https://github.com/myclabs/php-enum", "keywords": [ "enum" ], "support": { "issues": "https://github.com/myclabs/php-enum/issues", - "source": "https://github.com/myclabs/php-enum/tree/1.8.4" + "source": "https://github.com/myclabs/php-enum/tree/1.8.5" }, "funding": [ { @@ -4730,7 +4757,7 @@ "type": "tidelift" } ], - "time": "2022-08-04T09:53:51+00:00" + "time": "2025-01-14T11:49:03+00:00" }, { "name": "phar-io/manifest", @@ -4905,16 +4932,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.4.1", + "version": "5.6.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c" + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", - "reference": "9d07b3f7fdcf5efec5d1609cba3c19c5ea2bdc9c", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", + "reference": "e5e784149a09bd69d9a5e3b01c5cbd2e2bd653d8", "shasum": "" }, "require": { @@ -4923,17 +4950,17 @@ "php": "^7.4 || ^8.0", "phpdocumentor/reflection-common": "^2.2", "phpdocumentor/type-resolver": "^1.7", - "phpstan/phpdoc-parser": "^1.7", + "phpstan/phpdoc-parser": "^1.7|^2.0", "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.5", + "mockery/mockery": "~1.3.5 || ~1.6.0", "phpstan/extension-installer": "^1.1", "phpstan/phpstan": "^1.8", "phpstan/phpstan-mockery": "^1.1", "phpstan/phpstan-webmozart-assert": "^1.2", "phpunit/phpunit": "^9.5", - "vimeo/psalm": "^5.13" + "psalm/phar": "^5.26" }, "type": "library", "extra": { @@ -4963,29 +4990,29 @@ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", "support": { "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.4.1" + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.6.1" }, - "time": "2024-05-21T05:55:05+00:00" + "time": "2024-12-07T09:39:29+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.8.2", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "153ae662783729388a584b4361f2545e4d841e3c" + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/153ae662783729388a584b4361f2545e4d841e3c", - "reference": "153ae662783729388a584b4361f2545e4d841e3c", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/679e3ce485b99e84c775d28e2e96fade9a7fb50a", + "reference": "679e3ce485b99e84c775d28e2e96fade9a7fb50a", "shasum": "" }, "require": { "doctrine/deprecations": "^1.0", "php": "^7.3 || ^8.0", "phpdocumentor/reflection-common": "^2.0", - "phpstan/phpdoc-parser": "^1.13" + "phpstan/phpdoc-parser": "^1.18|^2.0" }, "require-dev": { "ext-tokenizer": "*", @@ -5021,32 +5048,33 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.8.2" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.10.0" }, - "time": "2024-02-23T11:10:43+00:00" + "time": "2024-11-09T15:12:26+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.19.0", + "version": "v1.20.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87" + "reference": "a0165c648cab6a80311c74ffc708a07bb53ecc93" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/67a759e7d8746d501c41536ba40cd9c0a07d6a87", - "reference": "67a759e7d8746d501c41536ba40cd9c0a07d6a87", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/a0165c648cab6a80311c74ffc708a07bb53ecc93", + "reference": "a0165c648cab6a80311c74ffc708a07bb53ecc93", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2 || ^2.0", - "php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.*", + "php": "^7.2 || 8.0.* || 8.1.* || 8.2.* || 8.3.* || 8.4.*", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0 || ^5.0 || ^6.0", "sebastian/recursion-context": "^3.0 || ^4.0 || ^5.0 || ^6.0" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^3.40", "phpspec/phpspec": "^6.0 || ^7.0", "phpstan/phpstan": "^1.9", "phpunit/phpunit": "^8.0 || ^9.0 || ^10.0" @@ -5090,22 +5118,22 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.19.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.20.0" }, - "time": "2024-02-29T11:52:51+00:00" + "time": "2024-11-19T13:12:41+00:00" }, { "name": "phpspec/prophecy-phpunit", - "version": "v2.2.0", + "version": "v2.3.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy-phpunit.git", - "reference": "16e1247e139434bce0bac09848bc5c8d882940fc" + "reference": "8819516c1b489ecee4c60db5f5432fac1ea8ac6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/16e1247e139434bce0bac09848bc5c8d882940fc", - "reference": "16e1247e139434bce0bac09848bc5c8d882940fc", + "url": "https://api.github.com/repos/phpspec/prophecy-phpunit/zipball/8819516c1b489ecee4c60db5f5432fac1ea8ac6f", + "reference": "8819516c1b489ecee4c60db5f5432fac1ea8ac6f", "shasum": "" }, "require": { @@ -5113,6 +5141,9 @@ "phpspec/prophecy": "^1.18", "phpunit/phpunit": "^9.1 || ^10.1 || ^11.0" }, + "require-dev": { + "phpstan/phpstan": "^1.10" + }, "type": "library", "extra": { "branch-alias": { @@ -5142,36 +5173,36 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy-phpunit/issues", - "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.2.0" + "source": "https://github.com/phpspec/prophecy-phpunit/tree/v2.3.0" }, - "time": "2024-03-01T08:33:58+00:00" + "time": "2024-11-19T13:24:17+00:00" }, { "name": "phpstan/phpdoc-parser", - "version": "1.29.1", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpdoc-parser.git", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4" + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/fcaefacf2d5c417e928405b71b400d4ce10daaf4", - "reference": "fcaefacf2d5c417e928405b71b400d4ce10daaf4", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/c00d78fb6b29658347f9d37ebe104bffadf36299", + "reference": "c00d78fb6b29658347f9d37ebe104bffadf36299", "shasum": "" }, "require": { - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "doctrine/annotations": "^2.0", - "nikic/php-parser": "^4.15", + "nikic/php-parser": "^5.3.0", "php-parallel-lint/php-parallel-lint": "^1.2", "phpstan/extension-installer": "^1.0", - "phpstan/phpstan": "^1.5", - "phpstan/phpstan-phpunit": "^1.1", - "phpstan/phpstan-strict-rules": "^1.0", - "phpunit/phpunit": "^9.5", + "phpstan/phpstan": "^2.0", + "phpstan/phpstan-phpunit": "^2.0", + "phpstan/phpstan-strict-rules": "^2.0", + "phpunit/phpunit": "^9.6", "symfony/process": "^5.2" }, "type": "library", @@ -5189,26 +5220,26 @@ "description": "PHPDoc parser with support for nullable, intersection and generic types", "support": { "issues": "https://github.com/phpstan/phpdoc-parser/issues", - "source": "https://github.com/phpstan/phpdoc-parser/tree/1.29.1" + "source": "https://github.com/phpstan/phpdoc-parser/tree/2.0.0" }, - "time": "2024-05-31T08:52:43+00:00" + "time": "2024-10-13T11:29:49+00:00" }, { "name": "phpstan/phpstan", - "version": "1.11.2", + "version": "2.1.2", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec" + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/0d5d4294a70deb7547db655c47685d680e39cfec", - "reference": "0d5d4294a70deb7547db655c47685d680e39cfec", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a", + "reference": "7d08f569e582ade182a375c366cbd896eccadd3a", "shasum": "" }, "require": { - "php": "^7.2|^8.0" + "php": "^7.4|^8.0" }, "conflict": { "phpstan/phpstan-shim": "*" @@ -5249,39 +5280,39 @@ "type": "github" } ], - "time": "2024-05-24T13:23:04+00:00" + "time": "2025-01-21T14:54:06+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.31", + "version": "11.0.8", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965" + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/48c34b5d8d983006bd2adc2d0de92963b9155965", - "reference": "48c34b5d8d983006bd2adc2d0de92963b9155965", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/418c59fd080954f8c4aa5631d9502ecda2387118", + "reference": "418c59fd080954f8c4aa5631d9502ecda2387118", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0.3", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" + "nikic/php-parser": "^5.3.1", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-text-template": "^4.0.1", + "sebastian/code-unit-reverse-lookup": "^4.0.1", + "sebastian/complexity": "^4.0.1", + "sebastian/environment": "^7.2.0", + "sebastian/lines-of-code": "^3.0.1", + "sebastian/version": "^5.0.2", + "theseer/tokenizer": "^1.2.3" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.5.0" }, "suggest": { "ext-pcov": "PHP extension that provides line coverage", @@ -5290,7 +5321,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.2-dev" + "dev-main": "11.0.x-dev" } }, "autoload": { @@ -5319,7 +5350,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.31" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.8" }, "funding": [ { @@ -5327,32 +5358,32 @@ "type": "github" } ], - "time": "2024-03-02T06:37:42+00:00" + "time": "2024-12-11T12:34:27+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.6", + "version": "5.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", - "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/118cfaaa8bc5aef3287bf315b6060b1174754af6", + "reference": "118cfaaa8bc5aef3287bf315b6060b1174754af6", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -5379,7 +5410,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.1.0" }, "funding": [ { @@ -5387,28 +5419,28 @@ "type": "github" } ], - "time": "2021-12-02T12:48:52+00:00" + "time": "2024-08-27T05:02:59+00:00" }, { "name": "phpunit/php-invoker", - "version": "3.1.1", + "version": "5.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", - "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/c1ca3814734c07492b3d4c5f794f4b0995333da2", + "reference": "c1ca3814734c07492b3d4c5f794f4b0995333da2", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { "ext-pcntl": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-pcntl": "*" @@ -5416,7 +5448,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.1-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -5442,7 +5474,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.1" }, "funding": [ { @@ -5450,32 +5483,32 @@ "type": "github" } ], - "time": "2020-09-28T05:58:55+00:00" + "time": "2024-07-03T05:07:44+00:00" }, { "name": "phpunit/php-text-template", - "version": "2.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", - "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/3e0404dc6b300e6bf56415467ebcb3fe4f33e964", + "reference": "3e0404dc6b300e6bf56415467ebcb3fe4f33e964", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -5501,7 +5534,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.1" }, "funding": [ { @@ -5509,32 +5543,32 @@ "type": "github" } ], - "time": "2020-10-26T05:33:50+00:00" + "time": "2024-07-03T05:08:43+00:00" }, { "name": "phpunit/php-timer", - "version": "5.0.3", + "version": "7.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", - "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", + "reference": "3b415def83fbcb41f991d9ebf16ae4ad8b7837b3", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -5560,7 +5594,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.1" }, "funding": [ { @@ -5568,54 +5603,52 @@ "type": "github" } ], - "time": "2020-10-26T13:16:10+00:00" + "time": "2024-07-03T05:09:35+00:00" }, { "name": "phpunit/phpunit", - "version": "9.6.19", + "version": "11.5.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8" + "reference": "b9a975972f580c0491f834eb0818ad2b32fd8bba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/a1a54a473501ef4cdeaae4e06891674114d79db8", - "reference": "a1a54a473501ef4cdeaae4e06891674114d79db8", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/b9a975972f580c0491f834eb0818ad2b32fd8bba", + "reference": "b9a975972f580c0491f834eb0818ad2b32fd8bba", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.3.1 || ^2", "ext-dom": "*", "ext-json": "*", "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.3", - "phar-io/version": "^3.0.2", - "php": ">=7.3", - "phpunit/php-code-coverage": "^9.2.28", - "phpunit/php-file-iterator": "^3.0.5", - "phpunit/php-invoker": "^3.1.1", - "phpunit/php-text-template": "^2.0.3", - "phpunit/php-timer": "^5.0.2", - "sebastian/cli-parser": "^1.0.1", - "sebastian/code-unit": "^1.0.6", - "sebastian/comparator": "^4.0.8", - "sebastian/diff": "^4.0.3", - "sebastian/environment": "^5.1.3", - "sebastian/exporter": "^4.0.5", - "sebastian/global-state": "^5.0.1", - "sebastian/object-enumerator": "^4.0.3", - "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.2", - "sebastian/version": "^3.0.2" + "myclabs/deep-copy": "^1.12.1", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0.8", + "phpunit/php-file-iterator": "^5.1.0", + "phpunit/php-invoker": "^5.0.1", + "phpunit/php-text-template": "^4.0.1", + "phpunit/php-timer": "^7.0.1", + "sebastian/cli-parser": "^3.0.2", + "sebastian/code-unit": "^3.0.2", + "sebastian/comparator": "^6.3.0", + "sebastian/diff": "^6.0.2", + "sebastian/environment": "^7.2.0", + "sebastian/exporter": "^6.3.0", + "sebastian/global-state": "^7.0.2", + "sebastian/object-enumerator": "^6.0.1", + "sebastian/type": "^5.1.0", + "sebastian/version": "^5.0.2", + "staabm/side-effects-detector": "^1.0.5" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-soap": "To be able to generate mocks based on WSDL files" }, "bin": [ "phpunit" @@ -5623,7 +5656,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "9.6-dev" + "dev-main": "11.5-dev" } }, "autoload": { @@ -5655,7 +5688,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.19" + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.5.5" }, "funding": [ { @@ -5671,7 +5704,7 @@ "type": "tidelift" } ], - "time": "2024-04-05T04:35:58+00:00" + "time": "2025-01-29T14:01:11+00:00" }, { "name": "psr/cache", @@ -5780,28 +5813,28 @@ }, { "name": "sebastian/cli-parser", - "version": "1.0.2", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", - "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/15c5dd40dc4f38794d383bb95465193f5e0ae180", + "reference": "15c5dd40dc4f38794d383bb95465193f5e0ae180", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -5824,7 +5857,8 @@ "homepage": "https://github.com/sebastianbergmann/cli-parser", "support": { "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.2" + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.2" }, "funding": [ { @@ -5832,32 +5866,32 @@ "type": "github" } ], - "time": "2024-03-02T06:27:43+00:00" + "time": "2024-07-03T04:41:36+00:00" }, { "name": "sebastian/code-unit", - "version": "1.0.8", + "version": "3.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", - "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", + "reference": "ee88b0cdbe74cf8dd3b54940ff17643c0d6543ca", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -5880,7 +5914,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit", "support": { "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.2" }, "funding": [ { @@ -5888,32 +5923,32 @@ "type": "github" } ], - "time": "2020-10-26T13:08:54+00:00" + "time": "2024-12-12T09:59:06+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.3", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + "reference": "183a9b2632194febd219bb9246eee421dad8d45e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", - "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/183a9b2632194febd219bb9246eee421dad8d45e", + "reference": "183a9b2632194febd219bb9246eee421dad8d45e", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -5935,7 +5970,8 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.1" }, "funding": [ { @@ -5943,34 +5979,39 @@ "type": "github" } ], - "time": "2020-09-28T05:30:19+00:00" + "time": "2024-07-03T04:45:54+00:00" }, { "name": "sebastian/comparator", - "version": "4.0.8", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a" + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/fa0f136dd2334583309d32b62544682ee972b51a", - "reference": "fa0f136dd2334583309d32b62544682ee972b51a", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/d4e47a769525c4dd38cea90e5dcd435ddbbc7115", + "reference": "d4e47a769525c4dd38cea90e5dcd435ddbbc7115", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.4" + }, + "suggest": { + "ext-bcmath": "For comparing BcMath\\Number objects" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.2-dev" } }, "autoload": { @@ -6009,7 +6050,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.8" + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.3.0" }, "funding": [ { @@ -6017,33 +6059,33 @@ "type": "github" } ], - "time": "2022-09-14T12:41:17+00:00" + "time": "2025-01-06T10:28:19+00:00" }, { "name": "sebastian/complexity", - "version": "2.0.3", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", - "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/ee41d384ab1906c68852636b6de493846e13e5a0", + "reference": "ee41d384ab1906c68852636b6de493846e13e5a0", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -6066,7 +6108,8 @@ "homepage": "https://github.com/sebastianbergmann/complexity", "support": { "issues": "https://github.com/sebastianbergmann/complexity/issues", - "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.3" + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.1" }, "funding": [ { @@ -6074,27 +6117,27 @@ "type": "github" } ], - "time": "2023-12-22T06:19:30+00:00" + "time": "2024-07-03T04:49:50+00:00" }, { "name": "sebastian/environment", - "version": "5.1.5", + "version": "7.2.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", - "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", + "reference": "855f3ae0ab316bbafe1ba4e16e9f3c078d24a0c5", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "suggest": { "ext-posix": "*" @@ -6102,7 +6145,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.1-dev" + "dev-main": "7.2-dev" } }, "autoload": { @@ -6121,7 +6164,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", + "homepage": "https://github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -6129,7 +6172,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.2.0" }, "funding": [ { @@ -6137,34 +6181,34 @@ "type": "github" } ], - "time": "2023-02-03T06:03:51+00:00" + "time": "2024-07-03T04:54:44+00:00" }, { "name": "sebastian/exporter", - "version": "4.0.6", + "version": "6.3.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72" + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/78c00df8f170e02473b682df15bfcdacc3d32d72", - "reference": "78c00df8f170e02473b682df15bfcdacc3d32d72", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/3473f61172093b2da7de1fb5782e1f24cc036dc3", + "reference": "3473f61172093b2da7de1fb5782e1f24cc036dc3", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/recursion-context": "^4.0" + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.1-dev" } }, "autoload": { @@ -6206,7 +6250,8 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.6" + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.3.0" }, "funding": [ { @@ -6214,38 +6259,35 @@ "type": "github" } ], - "time": "2024-03-02T06:33:00+00:00" + "time": "2024-12-05T09:17:50+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.7", + "version": "7.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9" + "reference": "3be331570a721f9a4b5917f4209773de17f747d7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", - "reference": "bca7df1f32ee6fe93b4d4a9abbf69e13a4ada2c9", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/3be331570a721f9a4b5917f4209773de17f747d7", + "reference": "3be331570a721f9a4b5917f4209773de17f747d7", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "5.0-dev" + "dev-main": "7.0-dev" } }, "autoload": { @@ -6264,13 +6306,14 @@ } ], "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", + "homepage": "https://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.7" + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.2" }, "funding": [ { @@ -6278,33 +6321,33 @@ "type": "github" } ], - "time": "2024-03-02T06:35:11+00:00" + "time": "2024-07-03T04:57:36+00:00" }, { "name": "sebastian/lines-of-code", - "version": "1.0.4", + "version": "3.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", - "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/d36ad0d782e5756913e42ad87cb2890f4ffe467a", + "reference": "d36ad0d782e5756913e42ad87cb2890f4ffe467a", "shasum": "" }, "require": { - "nikic/php-parser": "^4.18 || ^5.0", - "php": ">=7.3" + "nikic/php-parser": "^5.0", + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-main": "3.0-dev" } }, "autoload": { @@ -6327,7 +6370,8 @@ "homepage": "https://github.com/sebastianbergmann/lines-of-code", "support": { "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.4" + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.1" }, "funding": [ { @@ -6335,34 +6379,34 @@ "type": "github" } ], - "time": "2023-12-22T06:20:34+00:00" + "time": "2024-07-03T04:58:38+00:00" }, { "name": "sebastian/object-enumerator", - "version": "4.0.4", + "version": "6.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + "reference": "f5b498e631a74204185071eb41f33f38d64608aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", - "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f5b498e631a74204185071eb41f33f38d64608aa", + "reference": "f5b498e631a74204185071eb41f33f38d64608aa", "shasum": "" }, "require": { - "php": ">=7.3", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -6384,7 +6428,8 @@ "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.1" }, "funding": [ { @@ -6392,32 +6437,32 @@ "type": "github" } ], - "time": "2020-10-26T13:12:34+00:00" + "time": "2024-07-03T05:00:13+00:00" }, { "name": "sebastian/object-reflector", - "version": "2.0.4", + "version": "4.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", - "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/6e1a43b411b2ad34146dee7524cb13a068bb35f9", + "reference": "6e1a43b411b2ad34146dee7524cb13a068bb35f9", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0-dev" + "dev-main": "4.0-dev" } }, "autoload": { @@ -6439,7 +6484,8 @@ "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.1" }, "funding": [ { @@ -6447,32 +6493,32 @@ "type": "github" } ], - "time": "2020-10-26T13:14:26+00:00" + "time": "2024-07-03T05:01:32+00:00" }, { "name": "sebastian/recursion-context", - "version": "4.0.5", + "version": "6.0.2", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1" + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", - "reference": "e75bd0f07204fec2a0af9b0f3cfe97d05f92efc1", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/694d156164372abbd149a4b85ccda2e4670c0e16", + "reference": "694d156164372abbd149a4b85ccda2e4670c0e16", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.3" + "phpunit/phpunit": "^11.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0-dev" + "dev-main": "6.0-dev" } }, "autoload": { @@ -6502,7 +6548,8 @@ "homepage": "https://github.com/sebastianbergmann/recursion-context", "support": { "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.5" + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.2" }, "funding": [ { @@ -6510,32 +6557,32 @@ "type": "github" } ], - "time": "2023-02-03T06:07:39+00:00" + "time": "2024-07-03T05:10:34+00:00" }, { - "name": "sebastian/resource-operations", - "version": "3.0.4", + "name": "sebastian/type", + "version": "5.1.0", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", - "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/461b9c5da241511a2a0e8f240814fb23ce5c0aac", + "reference": "461b9c5da241511a2a0e8f240814fb23ce5c0aac", "shasum": "" }, "require": { - "php": ">=7.3" + "php": ">=8.2" }, "require-dev": { - "phpunit/phpunit": "^9.0" + "phpunit/phpunit": "^11.3" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-main": "5.1-dev" } }, "autoload": { @@ -6550,13 +6597,16 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", "support": { - "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.1.0" }, "funding": [ { @@ -6564,32 +6614,29 @@ "type": "github" } ], - "time": "2024-03-14T16:00:52+00:00" + "time": "2024-09-17T13:12:04+00:00" }, { - "name": "sebastian/type", - "version": "3.2.1", + "name": "sebastian/version", + "version": "5.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", - "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c687e3387b99f5b03b6caa64c74b63e2936ff874", + "reference": "c687e3387b99f5b03b6caa64c74b63e2936ff874", "shasum": "" }, "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.5" + "php": ">=8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2-dev" + "dev-main": "5.0-dev" } }, "autoload": { @@ -6608,11 +6655,12 @@ "role": "lead" } ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.2.1" + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.2" }, "funding": [ { @@ -6620,78 +6668,77 @@ "type": "github" } ], - "time": "2023-02-03T06:13:03+00:00" + "time": "2024-10-09T05:16:32+00:00" }, { - "name": "sebastian/version", - "version": "3.0.2", + "name": "staabm/side-effects-detector", + "version": "1.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "c6c1022351a901512170118436c764e473f6de8c" + "url": "https://github.com/staabm/side-effects-detector.git", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", - "reference": "c6c1022351a901512170118436c764e473f6de8c", + "url": "https://api.github.com/repos/staabm/side-effects-detector/zipball/d8334211a140ce329c13726d4a715adbddd0a163", + "reference": "d8334211a140ce329c13726d4a715adbddd0a163", "shasum": "" }, "require": { - "php": ">=7.3" + "ext-tokenizer": "*", + "php": "^7.4 || ^8.0" }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } + "require-dev": { + "phpstan/extension-installer": "^1.4.3", + "phpstan/phpstan": "^1.12.6", + "phpunit/phpunit": "^9.6.21", + "symfony/var-dumper": "^5.4.43", + "tomasvotruba/type-coverage": "1.0.0", + "tomasvotruba/unused-public": "1.0.0" }, + "type": "library", "autoload": { "classmap": [ - "src/" + "lib/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "BSD-3-Clause" + "MIT" ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } + "description": "A static analysis tool to detect side effects in PHP code", + "keywords": [ + "static analysis" ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", "support": { - "issues": "https://github.com/sebastianbergmann/version/issues", - "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + "issues": "https://github.com/staabm/side-effects-detector/issues", + "source": "https://github.com/staabm/side-effects-detector/tree/1.0.5" }, "funding": [ { - "url": "https://github.com/sebastianbergmann", + "url": "https://github.com/staabm", "type": "github" } ], - "time": "2020-09-28T06:39:44+00:00" + "time": "2024-10-20T05:08:20+00:00" }, { "name": "symfony/doctrine-bridge", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/doctrine-bridge.git", - "reference": "5ae0d9d1d54663daddd132ca6a5757e7d1f2fcd2" + "reference": "7a183fdfb472c5487480baa128a41ed47367723e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/5ae0d9d1d54663daddd132ca6a5757e7d1f2fcd2", - "reference": "5ae0d9d1d54663daddd132ca6a5757e7d1f2fcd2", + "url": "https://api.github.com/repos/symfony/doctrine-bridge/zipball/7a183fdfb472c5487480baa128a41ed47367723e", + "reference": "7a183fdfb472c5487480baa128a41ed47367723e", "shasum": "" }, "require": { "doctrine/event-manager": "^2", - "doctrine/persistence": "^3.1", + "doctrine/persistence": "^3.1|^4", "php": ">=8.2", "symfony/deprecation-contracts": "^2.5|^3", "symfony/polyfill-ctype": "~1.8", @@ -6699,6 +6746,7 @@ "symfony/service-contracts": "^2.5|^3" }, "conflict": { + "doctrine/collections": "<1.8", "doctrine/dbal": "<3.6", "doctrine/lexer": "<1.1", "doctrine/orm": "<2.15", @@ -6715,8 +6763,8 @@ "symfony/validator": "<6.4" }, "require-dev": { - "doctrine/collections": "^1.0|^2.0", - "doctrine/data-fixtures": "^1.1", + "doctrine/collections": "^1.8|^2.0", + "doctrine/data-fixtures": "^1.1|^2", "doctrine/dbal": "^3.6|^4", "doctrine/orm": "^2.15|^3", "psr/log": "^1|^2|^3", @@ -6765,7 +6813,7 @@ "description": "Provides integration for Doctrine with various Symfony components", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/doctrine-bridge/tree/v7.1.0" + "source": "https://github.com/symfony/doctrine-bridge/tree/v7.2.3" }, "funding": [ { @@ -6781,20 +6829,20 @@ "type": "tidelift" } ], - "time": "2024-05-30T18:00:20+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/error-handler", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "477d911900bf32fc43a675f78d4cbaedbb78378f" + "reference": "959a74d044a6db21f4caa6d695648dcb5584cb49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/477d911900bf32fc43a675f78d4cbaedbb78378f", - "reference": "477d911900bf32fc43a675f78d4cbaedbb78378f", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/959a74d044a6db21f4caa6d695648dcb5584cb49", + "reference": "959a74d044a6db21f4caa6d695648dcb5584cb49", "shasum": "" }, "require": { @@ -6840,7 +6888,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/error-handler/tree/v7.1.0" + "source": "https://github.com/symfony/error-handler/tree/v7.2.3" }, "funding": [ { @@ -6856,35 +6904,36 @@ "type": "tidelift" } ], - "time": "2024-05-17T10:55:18+00:00" + "time": "2025-01-07T09:39:55+00:00" }, { "name": "symfony/http-foundation", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "f9c54a6b1697d0b3b3d541e89e7843cdb3c9bfb7" + "reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f9c54a6b1697d0b3b3d541e89e7843cdb3c9bfb7", - "reference": "f9c54a6b1697d0b3b3d541e89e7843cdb3c9bfb7", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/ee1b504b8926198be89d05e5b6fc4c3810c090f0", + "reference": "ee1b504b8926198be89d05e5b6fc4c3810c090f0", "shasum": "" }, "require": { "php": ">=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-mbstring": "~1.1", "symfony/polyfill-php83": "^1.27" }, "conflict": { "doctrine/dbal": "<3.6", - "symfony/cache": "<6.4" + "symfony/cache": "<6.4.12|>=7.0,<7.1.5" }, "require-dev": { "doctrine/dbal": "^3.6|^4", "predis/predis": "^1.1|^2.0", - "symfony/cache": "^6.4|^7.0", + "symfony/cache": "^6.4.12|^7.1.5", "symfony/dependency-injection": "^6.4|^7.0", "symfony/expression-language": "^6.4|^7.0", "symfony/http-kernel": "^6.4|^7.0", @@ -6917,7 +6966,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v7.1.0" + "source": "https://github.com/symfony/http-foundation/tree/v7.2.3" }, "funding": [ { @@ -6933,20 +6982,20 @@ "type": "tidelift" } ], - "time": "2024-05-20T16:41:11+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/http-kernel", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "7eb093ee3911354aa13704d757127535dd8d371f" + "reference": "caae9807f8e25a9b43ce8cc6fafab6cf91f0cc9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/7eb093ee3911354aa13704d757127535dd8d371f", - "reference": "7eb093ee3911354aa13704d757127535dd8d371f", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/caae9807f8e25a9b43ce8cc6fafab6cf91f0cc9b", + "reference": "caae9807f8e25a9b43ce8cc6fafab6cf91f0cc9b", "shasum": "" }, "require": { @@ -6975,7 +7024,7 @@ "symfony/twig-bridge": "<6.4", "symfony/validator": "<6.4", "symfony/var-dumper": "<6.4", - "twig/twig": "<3.0.4" + "twig/twig": "<3.12" }, "provide": { "psr/log-implementation": "1.0|2.0|3.0" @@ -7003,7 +7052,7 @@ "symfony/validator": "^6.4|^7.0", "symfony/var-dumper": "^6.4|^7.0", "symfony/var-exporter": "^6.4|^7.0", - "twig/twig": "^3.0.4" + "twig/twig": "^3.12" }, "type": "library", "autoload": { @@ -7031,7 +7080,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v7.1.0" + "source": "https://github.com/symfony/http-kernel/tree/v7.2.3" }, "funding": [ { @@ -7047,20 +7096,20 @@ "type": "tidelift" } ], - "time": "2024-05-31T07:46:30+00:00" + "time": "2025-01-29T07:40:13+00:00" }, { "name": "symfony/phpunit-bridge", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/phpunit-bridge.git", - "reference": "1168ef27edb094fe4ba755ec937cf62a6dff84eb" + "reference": "2bbde92ab25a0e2c88160857af7be9db5da0d145" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/1168ef27edb094fe4ba755ec937cf62a6dff84eb", - "reference": "1168ef27edb094fe4ba755ec937cf62a6dff84eb", + "url": "https://api.github.com/repos/symfony/phpunit-bridge/zipball/2bbde92ab25a0e2c88160857af7be9db5da0d145", + "reference": "2bbde92ab25a0e2c88160857af7be9db5da0d145", "shasum": "" }, "require": { @@ -7080,8 +7129,8 @@ "type": "symfony-bridge", "extra": { "thanks": { - "name": "phpunit/phpunit", - "url": "https://github.com/sebastianbergmann/phpunit" + "url": "https://github.com/sebastianbergmann/phpunit", + "name": "phpunit/phpunit" } }, "autoload": { @@ -7092,7 +7141,8 @@ "Symfony\\Bridge\\PhpUnit\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7112,7 +7162,7 @@ "description": "Provides utilities for PHPUnit, especially user deprecation notices management", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/phpunit-bridge/tree/v7.1.0" + "source": "https://github.com/symfony/phpunit-bridge/tree/v7.2.0" }, "funding": [ { @@ -7128,104 +7178,30 @@ "type": "tidelift" } ], - "time": "2024-05-17T10:55:18+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.29.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/861391a8da9a04cbad2d232ddd9e4893220d6e25", - "reference": "861391a8da9a04cbad2d232ddd9e4893220d6e25", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, - "type": "library", - "extra": { - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "files": [ - "bootstrap.php" - ], - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com/", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "support": { - "source": "https://github.com/symfony/polyfill-php72/tree/v1.29.0" - }, - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-11-13T16:15:23+00:00" }, { "name": "symfony/polyfill-php83", - "version": "v1.29.0", + "version": "v1.31.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php83.git", - "reference": "86fcae159633351e5fd145d1c47de6c528f8caff" + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/86fcae159633351e5fd145d1c47de6c528f8caff", - "reference": "86fcae159633351e5fd145d1c47de6c528f8caff", + "url": "https://api.github.com/repos/symfony/polyfill-php83/zipball/2fb86d65e2d424369ad2905e83b236a8805ba491", + "reference": "2fb86d65e2d424369ad2905e83b236a8805ba491", "shasum": "" }, "require": { - "php": ">=7.1", - "symfony/polyfill-php80": "^1.14" + "php": ">=7.2" }, "type": "library", "extra": { "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { @@ -7262,7 +7238,7 @@ "shim" ], "support": { - "source": "https://github.com/symfony/polyfill-php83/tree/v1.29.0" + "source": "https://github.com/symfony/polyfill-php83/tree/v1.31.0" }, "funding": [ { @@ -7278,20 +7254,20 @@ "type": "tidelift" } ], - "time": "2024-01-29T20:11:03+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { "name": "symfony/property-access", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-access.git", - "reference": "1e8c1e6ac1b19cf945d8094a0ee50296872c4cb2" + "reference": "b28732e315d81fbec787f838034de7d6c9b2b902" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-access/zipball/1e8c1e6ac1b19cf945d8094a0ee50296872c4cb2", - "reference": "1e8c1e6ac1b19cf945d8094a0ee50296872c4cb2", + "url": "https://api.github.com/repos/symfony/property-access/zipball/b28732e315d81fbec787f838034de7d6c9b2b902", + "reference": "b28732e315d81fbec787f838034de7d6c9b2b902", "shasum": "" }, "require": { @@ -7338,7 +7314,7 @@ "reflection" ], "support": { - "source": "https://github.com/symfony/property-access/tree/v7.1.0" + "source": "https://github.com/symfony/property-access/tree/v7.2.3" }, "funding": [ { @@ -7354,36 +7330,37 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2025-01-17T10:56:55+00:00" }, { "name": "symfony/property-info", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/property-info.git", - "reference": "b10cb8cf0179aec96769df2affb881ecfc293f79" + "reference": "dedb118fd588a92f226b390250b384d25f4192fe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/property-info/zipball/b10cb8cf0179aec96769df2affb881ecfc293f79", - "reference": "b10cb8cf0179aec96769df2affb881ecfc293f79", + "url": "https://api.github.com/repos/symfony/property-info/zipball/dedb118fd588a92f226b390250b384d25f4192fe", + "reference": "dedb118fd588a92f226b390250b384d25f4192fe", "shasum": "" }, "require": { "php": ">=8.2", "symfony/string": "^6.4|^7.0", - "symfony/type-info": "^7.1" + "symfony/type-info": "~7.1.9|^7.2.2" }, "conflict": { "phpdocumentor/reflection-docblock": "<5.2", "phpdocumentor/type-resolver": "<1.5.1", + "symfony/cache": "<6.4", "symfony/dependency-injection": "<6.4", "symfony/serializer": "<6.4" }, "require-dev": { "phpdocumentor/reflection-docblock": "^5.2", - "phpstan/phpdoc-parser": "^1.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", "symfony/cache": "^6.4|^7.0", "symfony/dependency-injection": "^6.4|^7.0", "symfony/serializer": "^6.4|^7.0" @@ -7422,7 +7399,7 @@ "validator" ], "support": { - "source": "https://github.com/symfony/property-info/tree/v7.1.0" + "source": "https://github.com/symfony/property-info/tree/v7.2.3" }, "funding": [ { @@ -7438,20 +7415,20 @@ "type": "tidelift" } ], - "time": "2024-05-30T12:09:55+00:00" + "time": "2025-01-27T11:08:17+00:00" }, { "name": "symfony/serializer", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/serializer.git", - "reference": "972eb05320d06d07399b71b05e6da9032c865f1d" + "reference": "320f30beb419ce4f96363ada5e225c41f1ef08ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/serializer/zipball/972eb05320d06d07399b71b05e6da9032c865f1d", - "reference": "972eb05320d06d07399b71b05e6da9032c865f1d", + "url": "https://api.github.com/repos/symfony/serializer/zipball/320f30beb419ce4f96363ada5e225c41f1ef08ab", + "reference": "320f30beb419ce4f96363ada5e225c41f1ef08ab", "shasum": "" }, "require": { @@ -7471,11 +7448,12 @@ }, "require-dev": { "phpdocumentor/reflection-docblock": "^3.2|^4.0|^5.0", + "phpstan/phpdoc-parser": "^1.0|^2.0", "seld/jsonlint": "^1.10", "symfony/cache": "^6.4|^7.0", "symfony/config": "^6.4|^7.0", "symfony/console": "^6.4|^7.0", - "symfony/dependency-injection": "^6.4|^7.0", + "symfony/dependency-injection": "^7.2", "symfony/error-handler": "^6.4|^7.0", "symfony/filesystem": "^6.4|^7.0", "symfony/form": "^6.4|^7.0", @@ -7519,7 +7497,7 @@ "description": "Handles serializing and deserializing data structures, including object graphs, into array structures or other formats like XML and JSON.", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/serializer/tree/v7.1.0" + "source": "https://github.com/symfony/serializer/tree/v7.2.3" }, "funding": [ { @@ -7535,20 +7513,20 @@ "type": "tidelift" } ], - "time": "2024-05-21T15:59:31+00:00" + "time": "2025-01-29T07:13:55+00:00" }, { "name": "symfony/translation-contracts", - "version": "v3.5.0", + "version": "v3.5.1", "source": { "type": "git", "url": "https://github.com/symfony/translation-contracts.git", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a" + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", - "reference": "b9d2189887bb6b2e0367a9fc7136c5239ab9b05a", + "url": "https://api.github.com/repos/symfony/translation-contracts/zipball/4667ff3bd513750603a09c8dedbea942487fb07c", + "reference": "4667ff3bd513750603a09c8dedbea942487fb07c", "shasum": "" }, "require": { @@ -7556,12 +7534,12 @@ }, "type": "library", "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, "branch-alias": { "dev-main": "3.5-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" } }, "autoload": { @@ -7597,7 +7575,7 @@ "standards" ], "support": { - "source": "https://github.com/symfony/translation-contracts/tree/v3.5.0" + "source": "https://github.com/symfony/translation-contracts/tree/v3.5.1" }, "funding": [ { @@ -7613,35 +7591,28 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:20:29+00:00" }, { "name": "symfony/type-info", - "version": "v7.1.0", + "version": "v7.2.2", "source": { "type": "git", "url": "https://github.com/symfony/type-info.git", - "reference": "b429d0710588fc396ba5def5329cf637d9861f9f" + "reference": "3b5a17470fff0034f25fd4287cbdaa0010d2f749" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/type-info/zipball/b429d0710588fc396ba5def5329cf637d9861f9f", - "reference": "b429d0710588fc396ba5def5329cf637d9861f9f", + "url": "https://api.github.com/repos/symfony/type-info/zipball/3b5a17470fff0034f25fd4287cbdaa0010d2f749", + "reference": "3b5a17470fff0034f25fd4287cbdaa0010d2f749", "shasum": "" }, "require": { "php": ">=8.2", "psr/container": "^1.1|^2.0" }, - "conflict": { - "phpstan/phpdoc-parser": "<1.0", - "symfony/dependency-injection": "<6.4", - "symfony/property-info": "<6.4" - }, "require-dev": { - "phpstan/phpdoc-parser": "^1.0", - "symfony/dependency-injection": "^6.4|^7.0", - "symfony/property-info": "^6.4|^7.0" + "phpstan/phpdoc-parser": "^1.0|^2.0" }, "type": "library", "autoload": { @@ -7679,7 +7650,7 @@ "type" ], "support": { - "source": "https://github.com/symfony/type-info/tree/v7.1.0" + "source": "https://github.com/symfony/type-info/tree/v7.2.2" }, "funding": [ { @@ -7695,20 +7666,20 @@ "type": "tidelift" } ], - "time": "2024-05-02T10:19:13+00:00" + "time": "2024-12-20T13:38:37+00:00" }, { "name": "symfony/validator", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/validator.git", - "reference": "ffcc8c56502f6adaeaf6307aef5b98b53a8d0326" + "reference": "6faf9f671d522b76ce87e46a1d2d7740b4385c6f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/validator/zipball/ffcc8c56502f6adaeaf6307aef5b98b53a8d0326", - "reference": "ffcc8c56502f6adaeaf6307aef5b98b53a8d0326", + "url": "https://api.github.com/repos/symfony/validator/zipball/6faf9f671d522b76ce87e46a1d2d7740b4385c6f", + "reference": "6faf9f671d522b76ce87e46a1d2d7740b4385c6f", "shasum": "" }, "require": { @@ -7755,7 +7726,8 @@ "Symfony\\Component\\Validator\\": "" }, "exclude-from-classmap": [ - "/Tests/" + "/Tests/", + "/Resources/bin/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -7775,7 +7747,7 @@ "description": "Provides tools to validate values", "homepage": "https://symfony.com/", "support": { - "source": "https://github.com/symfony/validator/tree/v7.1.0" + "source": "https://github.com/symfony/validator/tree/v7.2.3" }, "funding": [ { @@ -7791,20 +7763,20 @@ "type": "tidelift" } ], - "time": "2024-05-21T15:59:31+00:00" + "time": "2025-01-28T15:51:35+00:00" }, { "name": "symfony/var-dumper", - "version": "v7.1.0", + "version": "v7.2.3", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "595e4a4bc2118e7f4884315a684678b9403d44a6" + "reference": "82b478c69745d8878eb60f9a049a4d584996f73a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/595e4a4bc2118e7f4884315a684678b9403d44a6", - "reference": "595e4a4bc2118e7f4884315a684678b9403d44a6", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/82b478c69745d8878eb60f9a049a4d584996f73a", + "reference": "82b478c69745d8878eb60f9a049a4d584996f73a", "shasum": "" }, "require": { @@ -7820,7 +7792,7 @@ "symfony/http-kernel": "^6.4|^7.0", "symfony/process": "^6.4|^7.0", "symfony/uid": "^6.4|^7.0", - "twig/twig": "^3.0.4" + "twig/twig": "^3.12" }, "bin": [ "Resources/bin/var-dump-server" @@ -7858,7 +7830,83 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v7.1.0" + "source": "https://github.com/symfony/var-dumper/tree/v7.2.3" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2025-01-17T11:39:41+00:00" + }, + { + "name": "symfony/var-exporter", + "version": "v7.2.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/var-exporter.git", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/var-exporter/zipball/1a6a89f95a46af0f142874c9d650a6358d13070d", + "reference": "1a6a89f95a46af0f142874c9d650a6358d13070d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "symfony/property-access": "^6.4|^7.0", + "symfony/serializer": "^6.4|^7.0", + "symfony/var-dumper": "^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\VarExporter\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Allows exporting any serializable PHP data structure to plain PHP code", + "homepage": "https://symfony.com/", + "keywords": [ + "clone", + "construct", + "export", + "hydrate", + "instantiate", + "lazy-loading", + "proxy", + "serialize" + ], + "support": { + "source": "https://github.com/symfony/var-exporter/tree/v7.2.0" }, "funding": [ { @@ -7874,20 +7922,20 @@ "type": "tidelift" } ], - "time": "2024-05-28T06:54:05+00:00" + "time": "2024-10-18T07:58:17+00:00" }, { "name": "symfony/web-link", - "version": "v7.1.0", + "version": "v7.2.0", "source": { "type": "git", "url": "https://github.com/symfony/web-link.git", - "reference": "3953f0a3f0e371f2585337a95a1998cb6aacce8e" + "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/web-link/zipball/3953f0a3f0e371f2585337a95a1998cb6aacce8e", - "reference": "3953f0a3f0e371f2585337a95a1998cb6aacce8e", + "url": "https://api.github.com/repos/symfony/web-link/zipball/f537556a885e14a1d28f6c759d41e57e93d0a532", + "reference": "f537556a885e14a1d28f6c759d41e57e93d0a532", "shasum": "" }, "require": { @@ -7941,7 +7989,7 @@ "push" ], "support": { - "source": "https://github.com/symfony/web-link/tree/v7.1.0" + "source": "https://github.com/symfony/web-link/tree/v7.2.0" }, "funding": [ { @@ -7957,7 +8005,7 @@ "type": "tidelift" } ], - "time": "2024-04-18T09:32:20+00:00" + "time": "2024-09-25T14:21:43+00:00" }, { "name": "theseer/tokenizer", @@ -8126,13 +8174,13 @@ ], "aliases": [], "minimum-stability": "stable", - "stability-flags": [], + "stability-flags": {}, "prefer-stable": false, "prefer-lowest": false, "platform": { "php": ">=7.4", "ext-json": "*" }, - "platform-dev": [], + "platform-dev": {}, "plugin-api-version": "2.6.0" } diff --git a/phpstan.neon b/phpstan.neon index 5d285b4b..4d0d6294 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -59,7 +59,7 @@ parameters: }, validator: array{assertType: boolean}, author: false|string, - fieldVisibility: string, + fieldVisibility: 'private'|'protected'|'public'|null, accessorMethods: boolean, fluentMutatorMethods: boolean, rangeMapping: array, diff --git a/phpunit.xml.dist b/phpunit.xml.dist index d70bb68e..659c34b3 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,24 +1,24 @@ - - - - - + cacheDirectory=".phpunit.cache" + executionOrder="depends,defects" + shortenArraysForExportThreshold="10" + beStrictAboutOutputDuringTests="true" + displayDetailsOnPhpunitDeprecations="true" + failOnPhpunitDeprecation="true" + failOnRisky="true" + failOnWarning="true"> + + + tests + + - + src - - - - - tests - - + diff --git a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php index 452eccb7..f9bf1f00 100644 --- a/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php +++ b/src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php @@ -111,7 +111,12 @@ private function validateClassOperations(array $operations): array $resolver->setAllowedTypes('item', 'array'); $resolver->setAllowedTypes('collection', 'array'); - return $resolver->resolve($operations); + /** + * @var T $operations + */ + $operations = $resolver->resolve($operations); + + return $operations; } public function generatePropertyAttributes(Property $property, string $className): array diff --git a/src/GoodRelationsBridge.php b/src/GoodRelationsBridge.php index e1d502b6..edc86c74 100644 --- a/src/GoodRelationsBridge.php +++ b/src/GoodRelationsBridge.php @@ -115,7 +115,7 @@ public function extractCardinality(string $id) } preg_match('/\(.\.\..\)/', $xmlResult, $matches); - return $matches[0]; + return $matches[0] ?? false; } return false; diff --git a/src/Model/Class_.php b/src/Model/Class_.php index 6d58bbb5..d9e87123 100644 --- a/src/Model/Class_.php +++ b/src/Model/Class_.php @@ -223,7 +223,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi $fieldVisibility = $config['fieldVisibility']; $file ??= new PhpFile(); - if (null !== $fileHeader && false !== $fileHeader && !$file->getComment()) { + if ($fileHeader && !$file->getComment()) { // avoid nested doc-block for configurations that already have * as delimiter $file->setComment(Helpers::unformatDocComment($fileHeader)); } @@ -255,7 +255,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi $netteAttributes[] = $attribute->toNetteAttribute($namespace); } } - $class->setAttributes($netteAttributes); + $class->setAttributes(array_values($netteAttributes)); if (!$class->getComment()) { foreach ($this->annotations as $annotation) { @@ -289,7 +289,7 @@ public function toNetteFile(array $config, InflectorInterface $inflector, ?PhpFi $netteConstants[] = $constant->toNetteConstant(); } } - $class->setConstants($netteConstants); + $class->setConstants(array_values($netteConstants)); $sortedProperties = isset($this->properties['id']) ? ['id' => $this->properties['id']] + $this->properties : $this->properties; diff --git a/src/Model/Property.php b/src/Model/Property.php index 6f561d07..977414f0 100644 --- a/src/Model/Property.php +++ b/src/Model/Property.php @@ -19,6 +19,7 @@ use Nette\PhpGenerator\Method; use Nette\PhpGenerator\PhpNamespace; use Nette\PhpGenerator\Property as NetteProperty; +use Nette\PhpGenerator\Visibility; abstract class Property { @@ -140,11 +141,14 @@ public function markAsCustom(): self return $this; } + /** + * @param 'private'|'protected'|'public'|null $visibility + */ public function toNetteProperty(PhpNamespace $namespace, ?string $visibility = null, bool $useDoctrineCollections = true, ?NetteProperty $property = null): NetteProperty { $property ??= new NetteProperty($this->name); - $property->setVisibility($visibility ?? ClassType::VISIBILITY_PRIVATE); + $property->setVisibility($visibility ?? Visibility::Private); if ($this->typeHint) { $property->setType($this->resolveName($namespace, $this->typeHint)); diff --git a/src/Model/ResolveNameTrait.php b/src/Model/ResolveNameTrait.php index e3af5821..b1bc97e2 100644 --- a/src/Model/ResolveNameTrait.php +++ b/src/Model/ResolveNameTrait.php @@ -22,7 +22,7 @@ trait ResolveNameTrait { private function resolveName(PhpNamespace $namespace, string $name): string { - if (method_exists(PhpNamespace::class, 'resolveName')) { + if (method_exists(PhpNamespace::class, 'resolveName')) { // @phpstan-ignore-line return $namespace->resolveName($name); } diff --git a/src/OpenApi/Model/Constant.php b/src/OpenApi/Model/Constant.php index 0996d6ae..f1561f1f 100644 --- a/src/OpenApi/Model/Constant.php +++ b/src/OpenApi/Model/Constant.php @@ -17,7 +17,6 @@ final class Constant extends BaseConstant { - private ?string $comment = null; private string $value; public function __construct(string $name, string $value) @@ -34,6 +33,6 @@ public function value(): string public function comment(): string { - return (string) $this->comment; + return ''; } } diff --git a/src/OpenApi/PhpTypeConverter.php b/src/OpenApi/PhpTypeConverter.php index e0b82fe0..d8315d69 100644 --- a/src/OpenApi/PhpTypeConverter.php +++ b/src/OpenApi/PhpTypeConverter.php @@ -18,7 +18,7 @@ final class PhpTypeConverter implements PhpTypeConverterInterface { - public function getPhpType(Property $property, array $config = [], array $classes = []): ?string + public function getPhpType(Property $property, array $config = [], array $classes = []): string { if ($property->reference && $property->isArray()) { return ($config['doctrine']['useCollection'] ?? false) ? 'Collection' : 'array'; diff --git a/src/OpenApi/PropertyGenerator/PropertyGenerator.php b/src/OpenApi/PropertyGenerator/PropertyGenerator.php index ee90257b..aec9c2e0 100644 --- a/src/OpenApi/PropertyGenerator/PropertyGenerator.php +++ b/src/OpenApi/PropertyGenerator/PropertyGenerator.php @@ -42,7 +42,7 @@ public function __construct(?PropertyGeneratorInterface $propertyGenerator = nul * @param Configuration $config * @param array{schema: Schema, property: Schema} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property { $schema = $context['schema']; $schemaProperty = $context['property']; diff --git a/src/Printer.php b/src/Printer.php index c9804e0f..13853384 100644 --- a/src/Printer.php +++ b/src/Printer.php @@ -25,7 +25,7 @@ public function __construct() $this->linesBetweenMethods = 1; // If the type name cannot be resolved with the namespace and its uses (nette/php-generator >= 4), // disable type resolving to avoid using the root namespace. - if (!method_exists(PhpNamespace::class, 'resolveName')) { + if (!method_exists(PhpNamespace::class, 'resolveName')) { // @phpstan-ignore-line $this->setTypeResolving(false); } } diff --git a/src/PropertyGenerator/PropertyGenerator.php b/src/PropertyGenerator/PropertyGenerator.php index 0df61662..7fb81065 100644 --- a/src/PropertyGenerator/PropertyGenerator.php +++ b/src/PropertyGenerator/PropertyGenerator.php @@ -22,7 +22,7 @@ final class PropertyGenerator implements PropertyGeneratorInterface * @param Configuration $config * @param array{} $context */ - public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): ?Property + public function __invoke(string $name, array $config, Class_ $class, array $context, bool $isCustom = false, ?Property $property = null): Property { if (!$property) { throw new \LogicException('A property must be given.'); diff --git a/src/TypesGenerator.php b/src/TypesGenerator.php index 606aa437..23f3ba7a 100644 --- a/src/TypesGenerator.php +++ b/src/TypesGenerator.php @@ -133,6 +133,9 @@ public function generate(array $graphs, array $config): array $class = $classes[$parent]; } } + /** + * @var array $classes + */ $classes = array_intersect_key($classes, array_flip($typeNamesToGenerate)); $types = array_intersect_key($types, array_flip($typeNamesToGenerate)); @@ -140,7 +143,6 @@ public function generate(array $graphs, array $config): array // Second pass foreach ($classes as $class) { - /** @var $class SchemaClass */ if ($class->hasParent() && !$class->isParentEnum()) { $parentClass = $classes[$class->parent()] ?? null; if ($parentClass) { @@ -183,7 +185,6 @@ public function generate(array $graphs, array $config): array } $parentConfig = $config['types'][$class->parent()] ?? null; - /** @var SchemaClass|null $parentClass */ $parentClass = $classes[$class->parent()]; while ($parentClass) { diff --git a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php index 85545a24..396039a3 100644 --- a/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php +++ b/tests/AnnotationGenerator/PhpDocAnnotationGeneratorTest.php @@ -25,6 +25,7 @@ use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Config\Definition\Processor; use Symfony\Component\String\Inflector\EnglishInflector; @@ -48,15 +49,13 @@ protected function setUp(): void ); } - /** - * @dataProvider provideGenerateClassAnnotationsCases - */ + #[DataProvider('provideGenerateClassAnnotationsCases')] public function testGenerateClassAnnotations(Class_ $class, array $annotations): void { $this->assertSame($annotations, $this->generator->generateClassAnnotations($class)); } - public function provideGenerateClassAnnotationsCases(): \Generator + public static function provideGenerateClassAnnotationsCases(): \Generator { $class = new SchemaClass('Res', new RdfResource('https://schema.org/Res')); $class->interface = new Interface_('Interface', '/foo'); @@ -66,15 +65,13 @@ public function provideGenerateClassAnnotationsCases(): \Generator yield 'with resource' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', $graph)), ['@see https://schema.org/Res', '@author Bill']]; } - /** - * @dataProvider provideGeneratePropertyAnnotationsCases - */ + #[DataProvider('provideGeneratePropertyAnnotationsCases')] public function testGeneratePropertyAnnotations(Property $property, string $className, array $annotations): void { $this->assertSame($annotations, $this->generator->generatePropertyAnnotations($property, $className)); } - public function provideGeneratePropertyAnnotationsCases(): \Generator + public static function provideGeneratePropertyAnnotationsCases(): \Generator { $property = new SchemaProperty('telephone'); $graph = new RdfGraph(); diff --git a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php index c2a4e637..3ff3a6f6 100644 --- a/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php @@ -33,6 +33,7 @@ use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use Nette\PhpGenerator\Literal; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\String\Inflector\EnglishInflector; @@ -51,15 +52,13 @@ private function generator(bool $oldAttributes = false): ApiPlatformCoreAttribut ); } - /** - * @dataProvider provideGenerateClassAttributesCases - */ + #[DataProvider('provideGenerateClassAttributesCases')] public function testGenerateClassAttributes(SchemaClass $class, array $attributes, bool $oldAttributes = false): void { $this->assertEquals($attributes, $this->generator($oldAttributes)->generateClassAttributes($class)); } - public function provideGenerateClassAttributesCases(): \Generator + public static function provideGenerateClassAttributesCases(): \Generator { yield 'classical' => [new SchemaClass('Res', new RdfResource('https://schema.org/Res', new RdfGraph())), [new Attribute('ApiResource', ['types' => ['https://schema.org/Res']])]]; @@ -97,15 +96,13 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'with short name' => [new SchemaClass('WithShortName', new RdfResource('https://schema.org/DifferentLocalName', new RdfGraph())), [new Attribute('ApiResource', ['shortName' => 'DifferentLocalName', 'types' => ['https://schema.org/DifferentLocalName']])]]; } - /** - * @dataProvider provideGeneratePropertyAttributesCases - */ + #[DataProvider('provideGeneratePropertyAttributesCases')] public function testGeneratePropertyAttributes(Property $property, array $attributes, bool $oldAttributes = false): void { $this->assertEquals($attributes, $this->generator($oldAttributes)->generatePropertyAttributes($property, 'Res')); } - public function provideGeneratePropertyAttributesCases(): \Generator + public static function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); $property->resource = new RdfResource('https://schema.org/prop'); diff --git a/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php b/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php index 1eb03797..e6198269 100644 --- a/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConfigurationAttributeGeneratorTest.php @@ -22,20 +22,19 @@ use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\String\Inflector\EnglishInflector; class ConfigurationAttributeGeneratorTest extends TestCase { - /** - * @dataProvider provideGenerateClassAttributesCases - */ + #[DataProvider('provideGenerateClassAttributesCases')] public function testGenerateClassAttributes(SchemaClass $class, array $config, array $attributes): void { $this->assertEquals($attributes, $this->generator($config)->generateClassAttributes($class)); } - public function provideGenerateClassAttributesCases(): \Generator + public static function provideGenerateClassAttributesCases(): \Generator { $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph())); @@ -72,15 +71,13 @@ public function provideGenerateClassAttributesCases(): \Generator ]; } - /** - * @dataProvider provideGeneratePropertyAttributesCases - */ + #[DataProvider('provideGeneratePropertyAttributesCases')] public function testGeneratePropertyAttributes(Property $property, array $config, array $attributes): void { $this->assertEquals($attributes, $this->generator($config)->generatePropertyAttributes($property, 'Res')); } - public function provideGeneratePropertyAttributesCases(): \Generator + public static function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); @@ -95,15 +92,13 @@ public function provideGeneratePropertyAttributesCases(): \Generator ]; } - /** - * @dataProvider provideGenerateUsesCases - */ + #[DataProvider('provideGenerateUsesCases')] public function testGenerateUses(SchemaClass $class, array $config, array $uses): void { $this->assertEquals($uses, $this->generator($config)->generateUses($class)); } - public function provideGenerateUsesCases(): \Generator + public static function provideGenerateUsesCases(): \Generator { $class = new SchemaClass('Foo', new RdfResource('https://schema.org/Foo', new RdfGraph())); diff --git a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php index 9f4d2e6f..496e18a0 100644 --- a/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php +++ b/tests/AttributeGenerator/ConstraintAttributeGeneratorTest.php @@ -25,6 +25,7 @@ use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; use Nette\PhpGenerator\Literal; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity; use Symfony\Component\String\Inflector\EnglishInflector; @@ -43,15 +44,13 @@ protected function setUp(): void ); } - /** - * @dataProvider provideGenerateClassAttributesCases - */ + #[DataProvider('provideGenerateClassAttributesCases')] public function testGenerateClassAttributes(SchemaClass $class, array $attributes): void { $this->assertEquals($attributes, $this->generator->generateClassAttributes($class)); } - public function provideGenerateClassAttributesCases(): \Generator + public static function provideGenerateClassAttributesCases(): \Generator { $graph = new RdfGraph(); $resource = new RdfResource('https://schema.org/Enum', $graph); @@ -79,15 +78,13 @@ public function provideGenerateClassAttributesCases(): \Generator yield 'multiple unique properties' => [$class, [new Attribute('UniqueEntity', ['fields' => ['bar', 'baz']])]]; } - /** - * @dataProvider provideGeneratePropertyAttributesCases - */ + #[DataProvider('provideGeneratePropertyAttributesCases')] public function testGeneratePropertyAttributes(Property $property, array $attributes): void { $this->assertEquals($attributes, $this->generator->generatePropertyAttributes($property, 'Res')); } - public function provideGeneratePropertyAttributesCases(): \Generator + public static function provideGeneratePropertyAttributesCases(): \Generator { $property = new Property('prop'); $property->isId = true; diff --git a/tests/ClassMutator/ClassParentMutatorTest.php b/tests/ClassMutator/ClassParentMutatorTest.php index 82598fbc..5ed3d84e 100644 --- a/tests/ClassMutator/ClassParentMutatorTest.php +++ b/tests/ClassMutator/ClassParentMutatorTest.php @@ -20,6 +20,7 @@ use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; @@ -50,9 +51,7 @@ protected function setUp(): void $this->classParentMutator->setLogger($this->loggerProphecy->reveal()); } - /** - * @dataProvider provideInvokeTestCases - */ + #[DataProvider('provideInvokeTestCases')] public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?string $loggerMessage = null): void { if ($loggerMessage) { @@ -67,7 +66,7 @@ public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?stri /** * @return \Generator */ - public function provideInvokeTestCases(): \Generator + public static function provideInvokeTestCases(): \Generator { $graph = new RdfGraph(); $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product', $graph)); diff --git a/tests/ClassMutator/ClassPropertiesAppenderTest.php b/tests/ClassMutator/ClassPropertiesAppenderTest.php index e387c5bb..0b5600cd 100644 --- a/tests/ClassMutator/ClassPropertiesAppenderTest.php +++ b/tests/ClassMutator/ClassPropertiesAppenderTest.php @@ -25,6 +25,7 @@ use ApiPlatform\SchemaGenerator\SchemaGeneratorConfiguration; use EasyRdf\Graph as RdfGraph; use EasyRdf\Resource as RdfResource; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Prophecy\PhpUnit\ProphecyTrait; use Prophecy\Prophecy\ObjectProphecy; @@ -72,9 +73,7 @@ protected function setUp(): void $this->classPropertiesAppender->setLogger($this->loggerProphecy->reveal()); } - /** - * @dataProvider provideInvokeTestCases - */ + #[DataProvider('provideInvokeTestCases')] public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?RdfGraph &$graph = null, ?string $loggerMessage = null): void { if ($graph) { @@ -94,7 +93,7 @@ public function testInvoke(SchemaClass $class, SchemaClass $expectedClass, ?RdfG /** * @return \Generator */ - public function provideInvokeTestCases(): \Generator + public static function provideInvokeTestCases(): \Generator { $product = new SchemaClass('Product', new RdfResource('https://schema.org/Product')); yield 'no configuration no properties in map' => [clone $product, clone $product, null, 'Properties for "https://schema.org/Product" not found in the map.']; diff --git a/tests/Command/GenerateCommandTest.php b/tests/Command/GenerateCommandTest.php index 53bd47d4..c9c60a88 100644 --- a/tests/Command/GenerateCommandTest.php +++ b/tests/Command/GenerateCommandTest.php @@ -14,6 +14,7 @@ namespace ApiPlatform\SchemaGenerator\Tests\Command; use ApiPlatform\SchemaGenerator\Command\GenerateCommand; +use PHPUnit\Framework\Attributes\DataProvider; use PHPUnit\Framework\TestCase; use Symfony\Component\Console\Application; use Symfony\Component\Console\Tester\CommandTester; @@ -31,9 +32,7 @@ protected function setUp(): void $this->fs = new Filesystem(); } - /** - * @dataProvider getArguments - */ + #[DataProvider('getArguments')] public function testCommand(string $output, string $config): void { $this->fs->mkdir($output); @@ -42,7 +41,7 @@ public function testCommand(string $output, string $config): void $this->assertEquals(0, $commandTester->execute(['output' => $output, 'config' => $config])); } - public function getArguments(): iterable + public static function getArguments(): iterable { yield 'blog' => [__DIR__.'/../../build/blog/', __DIR__.'/../config/blog.yaml']; yield 'ecommerce' => [__DIR__.'/../../build/ecommerce/', __DIR__.'/../config/ecommerce.yaml']; diff --git a/tests/e2e/original/App/Schema/Entity/PostalAddress.php b/tests/e2e/original/App/Schema/Entity/PostalAddress.php index 8aa1616c..5ec70411 100644 --- a/tests/e2e/original/App/Schema/Entity/PostalAddress.php +++ b/tests/e2e/original/App/Schema/Entity/PostalAddress.php @@ -18,7 +18,7 @@ class PostalAddress extends ContactPoint { /** - * The country. For example, USA. You can also provide the two-letter \[ISO 3166-1 alpha-2 country code\](http://en.wikipedia.org/wiki/ISO\_3166-1). + * The country. Recommended to be in 2-letter \[ISO 3166-1 alpha-2\](http://en.wikipedia.org/wiki/ISO\_3166-1) format, for example "US". For backward compatibility, a 3-letter \[ISO 3166-1 alpha-3\](https://en.wikipedia.org/wiki/ISO\_3166-1\_alpha-3) country code such as "SGP" or a full country name such as "Singapore" can also be used. * * @see https://schema.org/addressCountry */ diff --git a/tests/e2e/original/App/Schema/Enum/GenderType.php b/tests/e2e/original/App/Schema/Enum/GenderType.php index f2a24993..cbe6dbe4 100644 --- a/tests/e2e/original/App/Schema/Enum/GenderType.php +++ b/tests/e2e/original/App/Schema/Enum/GenderType.php @@ -13,9 +13,9 @@ */ class GenderType extends Enum { - /** @var string The female gender. */ - public const FEMALE = 'https://schema.org/Female'; - /** @var string The male gender. */ public const MALE = 'https://schema.org/Male'; + + /** @var string The female gender. */ + public const FEMALE = 'https://schema.org/Female'; } From a80faa2ffdbeeb04262b6324d0f64e94ad923d10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 30 Jan 2025 18:39:51 +0100 Subject: [PATCH 257/258] docs: changelog for 5.2.4 --- CHANGELOG.md | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 68c7891e..1122fda1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,11 +1,13 @@ # Changelog -## 5.3.3 +## 5.2.4 -* [ea14c3b](https://github.com/api-platform/core/commit/ea14c3b5c52a54e3b4b055a6d5da5a2397a1b3e0) fix: replace of GoodRelations OWL file (#431) -* [1bb5502](https://github.com/api-platform/core/commit/1bb5502b9b7b0cb767f7fbb16f80934bb57fbbdd) chore: update deps (#426) -* [997f6f8](https://github.com/api-platform/core/commit/997f6f811faa75006aeff72cec26fe291bb8eaab) ci: upgrade deps and use PHP 8.3 (#420) -* [8d683f2](https://github.com/api-platform/core/commit/8d683f2504450a39ac787d8b4f7e5710d15dd129) feat: allow symfony 7 +* feat: compatibility with PHP 8.4 + +## 5.2.3 + +* feat: compatibility with Symfony 7 +* fix: replace of GoodRelations OWL file (#431) ## 5.2.2 From c50ccf54d295bbcdb0d9354b7ac7a78a3b922a5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 30 Jan 2025 18:42:53 +0100 Subject: [PATCH 258/258] ci: update Box for releases --- .github/workflows/release.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0a997cb1..1eb8235e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -25,13 +25,13 @@ jobs: run: composer install --prefer-dist --no-interaction --no-progress --ansi - name: Download box.phar - run: wget -O box.phar https://github.com/humbug/box/releases/download/4.5.1/box.phar + run: wget -O box.phar https://github.com/humbug/box/releases/download/4.6.2/box.phar - name: Compile project run: php ./box.phar compile - name: Create Release - uses: softprops/action-gh-release@v1 + uses: softprops/action-gh-release@v2 with: name: Release ${{ github.ref_name }} body: ''