From 3d014dd2ff154fe0ba7cdeea77908401c8a7f469 Mon Sep 17 00:00:00 2001 From: Julien RAVIA Date: Tue, 11 Mar 2025 08:09:47 +0000 Subject: [PATCH 1/5] Change signature --- Tests/Model/Issue46/Article.php | 8 +------- Tests/Model/Issue46/Section.php | 2 +- Tests/Model/Issue75/Article.php | 9 ++------- Tests/Model/Issue80/Article.php | 9 ++------- Tests/Model/JsonLd/Cart.php | 4 ++-- Tests/Model/JsonLd/CartItem.php | 2 +- Tests/Model/JsonLd/Model.php | 5 ----- src/Mapping/Relation.php | 8 +++++++- 8 files changed, 16 insertions(+), 31 deletions(-) diff --git a/Tests/Model/Issue46/Article.php b/Tests/Model/Issue46/Article.php index ac48748..e9b53f3 100644 --- a/Tests/Model/Issue46/Article.php +++ b/Tests/Model/Issue46/Article.php @@ -15,16 +15,10 @@ class Article ] private $iri; - /** - * @Rest\Attribute(name="id", type="string") - */ #[Rest\Attribute(name: 'id', type: 'string')] private $id; - /** - * @Rest\ManyToOne(name="section", targetEntity="Section") - */ - #[Rest\ManyToOne(name: 'section', targetEntity: 'Section')] + #[Rest\ManyToOne(name: 'section', targetEntity: Section::class)] private $section; public function setId($id): void diff --git a/Tests/Model/Issue46/Section.php b/Tests/Model/Issue46/Section.php index 7044a0e..a2fb68a 100644 --- a/Tests/Model/Issue46/Section.php +++ b/Tests/Model/Issue46/Section.php @@ -21,7 +21,7 @@ class Section #[Rest\Attribute(name: 'title', type: 'string')] private $title; - #[Rest\OneToMany(name: 'articleList', targetEntity: 'Article')] + #[Rest\OneToMany(name: 'articleList', targetEntity: Article::class)] private $articleList = []; public function setId($id): void diff --git a/Tests/Model/Issue75/Article.php b/Tests/Model/Issue75/Article.php index ea8671a..4d30695 100644 --- a/Tests/Model/Issue75/Article.php +++ b/Tests/Model/Issue75/Article.php @@ -9,11 +9,6 @@ #[Rest\Entity(key: 'articles')] class Article { - /** - * @Rest\Id - * - * @Rest\Attribute(name="@id", type="string") - */ #[ Rest\Id, Rest\Attribute(name: '@id', type: 'string') @@ -23,10 +18,10 @@ class Article #[Rest\Attribute(name: 'title', type: 'string')] private $title; - #[Rest\ManyToOne(name: 'tag', targetEntity: 'Tag')] + #[Rest\ManyToOne(name: 'tag', targetEntity: Tag::class)] private $tag; - #[Rest\OneToMany(name: 'tagList', targetEntity: 'Tag')] + #[Rest\OneToMany(name: 'tagList', targetEntity: Tag::class)] private $tagList; public function setTitle($title): void diff --git a/Tests/Model/Issue80/Article.php b/Tests/Model/Issue80/Article.php index 5a50736..a002613 100644 --- a/Tests/Model/Issue80/Article.php +++ b/Tests/Model/Issue80/Article.php @@ -11,16 +11,11 @@ class Article { /** * @var int - * - * @Rest\Id - * - * @Rest\Attribute(name="id", type="int") */ + #[Rest\Id] + #[Rest\Attribute(name: 'id', type: 'string')] private $id; - /** - * @Rest\Attribute(name="title", type="string") - */ #[Rest\Attribute(name: 'title', type: 'string')] private $title; diff --git a/Tests/Model/JsonLd/Cart.php b/Tests/Model/JsonLd/Cart.php index 13cb2e2..754ce67 100644 --- a/Tests/Model/JsonLd/Cart.php +++ b/Tests/Model/JsonLd/Cart.php @@ -27,7 +27,7 @@ class Cart #[Rest\Attribute(name: 'created_at', type: 'datetime')] private $createdAt; - #[Rest\OneToMany(name: 'cart_items', targetEntity: 'CartItem')] + #[Rest\OneToMany(name: 'cart_items', targetEntity: CartItem::class)] private $cartItemList = []; /** @@ -38,7 +38,7 @@ class Cart #[Rest\Attribute(name: 'clientPhoneNumber', type: 'phone_number')] private $clientPhoneNumber; - #[Rest\ManyToOne(name: 'order', targetEntity: 'Order')] + #[Rest\ManyToOne(name: 'order', targetEntity: Order::class)] private $order; /** diff --git a/Tests/Model/JsonLd/CartItem.php b/Tests/Model/JsonLd/CartItem.php index 28ba659..f4f61a7 100644 --- a/Tests/Model/JsonLd/CartItem.php +++ b/Tests/Model/JsonLd/CartItem.php @@ -43,7 +43,7 @@ class CartItem /** * cart */ - #[Rest\ManyToOne(name: 'cart', targetEntity: 'Cart')] + #[Rest\ManyToOne(name: 'cart', targetEntity: Cart::class)] private $cart; /** diff --git a/Tests/Model/JsonLd/Model.php b/Tests/Model/JsonLd/Model.php index 79bcb2e..7ee93ab 100644 --- a/Tests/Model/JsonLd/Model.php +++ b/Tests/Model/JsonLd/Model.php @@ -13,11 +13,6 @@ */ class Model { - /** - * @Rest\Id - * - * @Rest\Attribute(name="id", type="string") - */ #[Rest\Id] #[Rest\Attribute(name: 'id', type: 'string')] private $id; diff --git a/src/Mapping/Relation.php b/src/Mapping/Relation.php index f574195..0008cbe 100644 --- a/src/Mapping/Relation.php +++ b/src/Mapping/Relation.php @@ -25,10 +25,13 @@ class Relation private $type; /** - * @var string + * @var class-string */ private $targetEntity; + /** + * @param class-string $targetEntity + */ public function __construct( string $serializedKey, string $type, @@ -73,6 +76,9 @@ public function isManyToOne(): bool return self::MANY_TO_ONE === $this->getType(); } + /** + * @return class-string + */ public function getTargetEntity(): string { return $this->targetEntity; From ac94c82145b45e696aff9fa97502c8550c358d5a Mon Sep 17 00:00:00 2001 From: Julien RAVIA Date: Tue, 11 Mar 2025 08:23:58 +0000 Subject: [PATCH 2/5] fix phpstan --- package.json | 3 ++- src/Mapping/Attributes/Relation.php | 3 +++ src/Mapping/Driver/AttributeDriver.php | 3 ++- src/Mapping/Relation.php | 3 +++ 4 files changed, 10 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 6ceb4fa..82271be 100644 --- a/package.json +++ b/package.json @@ -13,5 +13,6 @@ "hooks": { "pre-commit": "lint-staged" } - } + }, + "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" } diff --git a/src/Mapping/Attributes/Relation.php b/src/Mapping/Attributes/Relation.php index bf8e074..12f0a17 100644 --- a/src/Mapping/Attributes/Relation.php +++ b/src/Mapping/Attributes/Relation.php @@ -6,6 +6,9 @@ abstract class Relation { + /** + * @param class-string $targetEntity + */ public function __construct( public readonly string $name, public readonly string $targetEntity, diff --git a/src/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php index dcc69f5..00f8316 100644 --- a/src/Mapping/Driver/AttributeDriver.php +++ b/src/Mapping/Driver/AttributeDriver.php @@ -137,7 +137,7 @@ private function getClassMetadataForClassname( ); } - if ($relation) { + if ($relation instanceof Attributes\Relation) { $attributeList[] = new Attribute( $relation->name, $property->getName(), @@ -145,6 +145,7 @@ private function getClassMetadataForClassname( $targetEntity = $relation->targetEntity; if (false === mb_strpos($targetEntity, '/')) { + /** @var class-string $targetEntity */ $targetEntity = mb_substr( $classname, diff --git a/src/Mapping/Relation.php b/src/Mapping/Relation.php index 0008cbe..f82b8bb 100644 --- a/src/Mapping/Relation.php +++ b/src/Mapping/Relation.php @@ -84,6 +84,9 @@ public function getTargetEntity(): string return $this->targetEntity; } + /** + * @param class-string $targetEntity + */ public function setTargetEntity(string $targetEntity): self { $this->targetEntity = $targetEntity; From 21aebd061301f4d5017e22102de2297817e6922d Mon Sep 17 00:00:00 2001 From: Julien RAVIA Date: Tue, 11 Mar 2025 09:54:08 +0100 Subject: [PATCH 3/5] Discard changes to package.json --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 82271be..6ceb4fa 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,5 @@ "hooks": { "pre-commit": "lint-staged" } - }, - "packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e" + } } From 06aa5b8c7a211495e451c6d57e4f1d29cd7e011f Mon Sep 17 00:00:00 2001 From: Julien RAVIA Date: Thu, 17 Jul 2025 14:24:33 +0000 Subject: [PATCH 4/5] fix --- .../Mapping/Driver/AttributeDriverTest.php | 8 ++++--- Tests/Units/Model/SerializerTest.php | 6 ++--- src/Mapping/Driver/AttributeDriver.php | 10 +------- src/Mapping/Relation.php | 24 +++---------------- 4 files changed, 12 insertions(+), 36 deletions(-) diff --git a/Tests/Units/Mapping/Driver/AttributeDriverTest.php b/Tests/Units/Mapping/Driver/AttributeDriverTest.php index 8021d15..a0e575a 100644 --- a/Tests/Units/Mapping/Driver/AttributeDriverTest.php +++ b/Tests/Units/Mapping/Driver/AttributeDriverTest.php @@ -6,6 +6,8 @@ use Mapado\RestClientSdk\Mapping\Driver\AttributeDriver; use Mapado\RestClientSdk\Mapping\Relation; +use Mapado\RestClientSdk\Tests\Model\JsonLd\Cart; +use Mapado\RestClientSdk\Tests\Model\JsonLd\CartItem; use PHPUnit\Framework\TestCase; /** @@ -56,7 +58,7 @@ public function testAnnotationDriverWithRelations(): void { $testedInstance = new AttributeDriver($this->getCacheDir(), true); - $mapping = $testedInstance->loadClassname('Mapado\RestClientSdk\Tests\Model\JsonLd\Cart'); + $mapping = $testedInstance->loadClassname(Cart::class); $this->assertCount(1, $mapping); $classMetadata = current($mapping); @@ -70,7 +72,7 @@ public function testAnnotationDriverWithRelations(): void $this->assertCount(2, $relationList); $this->assertEquals(Relation::ONE_TO_MANY, current($relationList)->getType()); - $mapping = $testedInstance->loadClassname('Mapado\RestClientSdk\Tests\Model\JsonLd\CartItem'); + $mapping = $testedInstance->loadClassname(CartItem::class); $this->assertCount(1, $mapping); $classMetadata = current($mapping); @@ -84,7 +86,7 @@ public function testAnnotationDriverWithRelations(): void $this->assertCount(1, $relationList); $relation = current($relationList); $this->assertEquals(Relation::MANY_TO_ONE, $relation->getType()); - $this->assertEquals('Mapado\RestClientSdk\Tests\Model\JsonLd\Cart', $relation->getTargetEntity()); + $this->assertEquals(Cart::class, $relation->getTargetEntity()); } public function testLoadDirectory(): void diff --git a/Tests/Units/Model/SerializerTest.php b/Tests/Units/Model/SerializerTest.php index e55376d..93428da 100644 --- a/Tests/Units/Model/SerializerTest.php +++ b/Tests/Units/Model/SerializerTest.php @@ -732,7 +732,7 @@ public function testSerializingIriManyToOne(): void ], $this->testedInstance->serialize( $article, - 'Mapado\RestClientSdk\Tests\Model\Issue46\Article' + Issue46\Article::class ) ); @@ -747,7 +747,7 @@ public function testSerializingIriManyToOne(): void ], $this->testedInstance->serialize( $section, - 'Mapado\RestClientSdk\Tests\Model\Issue46\Section' + Issue46\Section::class ) ); @@ -766,7 +766,7 @@ public function testSerializingIriManyToOne(): void ], $this->testedInstance->serialize( $section, - 'Mapado\RestClientSdk\Tests\Model\Issue46\Section', + Issue46\Section::class, ['serializeRelations' => ['articleList']] ) ); diff --git a/src/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php index 00f8316..f23007e 100644 --- a/src/Mapping/Driver/AttributeDriver.php +++ b/src/Mapping/Driver/AttributeDriver.php @@ -9,6 +9,7 @@ use Mapado\RestClientSdk\Mapping\Attributes; use Mapado\RestClientSdk\Mapping\ClassMetadata; use Mapado\RestClientSdk\Mapping\Relation; +use function PHPStan\dumpType; /** * Class AttributeDriver @@ -144,15 +145,6 @@ private function getClassMetadataForClassname( ); $targetEntity = $relation->targetEntity; - if (false === mb_strpos($targetEntity, '/')) { - /** @var class-string $targetEntity */ - $targetEntity = - mb_substr( - $classname, - 0, - mb_strrpos($classname, '\\') + 1, - ) . $targetEntity; - } $relationList[] = new Relation( $relation->name, diff --git a/src/Mapping/Relation.php b/src/Mapping/Relation.php index f82b8bb..81152e3 100644 --- a/src/Mapping/Relation.php +++ b/src/Mapping/Relation.php @@ -14,32 +14,14 @@ class Relation public const MANY_TO_ONE = 'ManyToOne'; public const ONE_TO_MANY = 'OneToMany'; - /** - * @var string - */ - private $serializedKey; - - /** - * @var string - */ - private $type; - - /** - * @var class-string - */ - private $targetEntity; - /** * @param class-string $targetEntity */ public function __construct( - string $serializedKey, - string $type, - string $targetEntity, + private string $serializedKey, + private string $type, + private string $targetEntity, ) { - $this->serializedKey = $serializedKey; - $this->type = $type; - $this->targetEntity = $targetEntity; } public function getSerializedKey(): string From d69b9680ee3c25aab4fc2f7548329f9565523d07 Mon Sep 17 00:00:00 2001 From: Julien RAVIA Date: Thu, 17 Jul 2025 15:52:42 +0000 Subject: [PATCH 5/5] add test --- Tests/Model/JsonLd/Invalid.php | 20 +++++++++++ .../Mapping/Driver/AttributeDriverTest.php | 35 ++++++++++++++----- src/Mapping/Driver/AttributeDriver.php | 3 ++ 3 files changed, 50 insertions(+), 8 deletions(-) create mode 100644 Tests/Model/JsonLd/Invalid.php diff --git a/Tests/Model/JsonLd/Invalid.php b/Tests/Model/JsonLd/Invalid.php new file mode 100644 index 0000000..1acf1ed --- /dev/null +++ b/Tests/Model/JsonLd/Invalid.php @@ -0,0 +1,20 @@ +client; + } +} diff --git a/Tests/Units/Mapping/Driver/AttributeDriverTest.php b/Tests/Units/Mapping/Driver/AttributeDriverTest.php index a0e575a..efb7574 100644 --- a/Tests/Units/Mapping/Driver/AttributeDriverTest.php +++ b/Tests/Units/Mapping/Driver/AttributeDriverTest.php @@ -4,10 +4,17 @@ namespace Mapado\RestClientSdk\Tests\Units\Mapping\Driver; +use Mapado\RestClientSdk\Exception\MappingException; +use Mapado\RestClientSdk\Mapping\Attribute; +use Mapado\RestClientSdk\Mapping\ClassMetadata; use Mapado\RestClientSdk\Mapping\Driver\AttributeDriver; use Mapado\RestClientSdk\Mapping\Relation; use Mapado\RestClientSdk\Tests\Model\JsonLd\Cart; use Mapado\RestClientSdk\Tests\Model\JsonLd\CartItem; +use Mapado\RestClientSdk\Tests\Model\JsonLd\Client; +use Mapado\RestClientSdk\Tests\Model\JsonLd\Invalid; +use Mapado\RestClientSdk\Tests\Model\JsonLd\ModelRepository; +use Mapado\RestClientSdk\Tests\Model\JsonLd\Product; use PHPUnit\Framework\TestCase; /** @@ -22,10 +29,22 @@ public function testClassWithoutEntityAnnotation(): void { $testedInstance = new AttributeDriver($this->getCacheDir(), true); - $mapping = $testedInstance->loadClassname('Mapado\RestClientSdk\Tests\Model\JsonLd\Client'); + $mapping = $testedInstance->loadClassname(Client::class); $this->assertEmpty($mapping); } + /** + * testClassWithoutEntityAnnotation + */ + public function testClassWithInvalidProperty(): void + { + $testedInstance = new AttributeDriver($this->getCacheDir(), true); + + $this->expectException(MappingException::class); + + $mapping = $testedInstance->loadClassname(Invalid::class); + } + /** * testAnnotationDriver */ @@ -33,20 +52,20 @@ public function testAnnotationDriver(): void { $testedInstance = new AttributeDriver($this->getCacheDir(), true); - $mapping = $testedInstance->loadClassname('Mapado\RestClientSdk\Tests\Model\JsonLd\Product'); + $mapping = $testedInstance->loadClassname(Product::class); $this->assertCount(1, $mapping); $classMetadata = current($mapping); - $this->assertInstanceOf('Mapado\RestClientSdk\Mapping\ClassMetadata', $classMetadata); + $this->assertInstanceOf(ClassMetadata::class, $classMetadata); $this->assertEquals('product', $classMetadata->getKey()); - $this->assertEquals('Mapado\RestClientSdk\Tests\Model\JsonLd\Product', $classMetadata->getModelName()); - $this->assertEquals('Mapado\RestClientSdk\Tests\Model\JsonLd\ModelRepository', $classMetadata->getRepositoryName()); + $this->assertEquals(Product::class, $classMetadata->getModelName()); + $this->assertEquals(ModelRepository::class, $classMetadata->getRepositoryName()); $attributeList = $classMetadata->getAttributeList(); $this->assertCount(3, $attributeList); $attribute = current($attributeList); - $this->assertInstanceOf('Mapado\RestClientSdk\Mapping\Attribute', $attribute); + $this->assertInstanceOf(Attribute::class, $attribute); $this->assertEquals('id', $attribute->getSerializedKey()); $attribute = next($attributeList); @@ -62,7 +81,7 @@ public function testAnnotationDriverWithRelations(): void $this->assertCount(1, $mapping); $classMetadata = current($mapping); - $this->assertInstanceOf('Mapado\RestClientSdk\Mapping\ClassMetadata', $classMetadata); + $this->assertInstanceOf(ClassMetadata::class, $classMetadata); $this->assertEquals('cart', $classMetadata->getKey()); $attributeList = $classMetadata->getAttributeList(); @@ -76,7 +95,7 @@ public function testAnnotationDriverWithRelations(): void $this->assertCount(1, $mapping); $classMetadata = current($mapping); - $this->assertInstanceOf('Mapado\RestClientSdk\Mapping\ClassMetadata', $classMetadata); + $this->assertInstanceOf(ClassMetadata::class, $classMetadata); $this->assertEquals('cart_item', $classMetadata->getKey()); $attributeList = $classMetadata->getAttributeList(); diff --git a/src/Mapping/Driver/AttributeDriver.php b/src/Mapping/Driver/AttributeDriver.php index f23007e..4558d03 100644 --- a/src/Mapping/Driver/AttributeDriver.php +++ b/src/Mapping/Driver/AttributeDriver.php @@ -145,6 +145,9 @@ private function getClassMetadataForClassname( ); $targetEntity = $relation->targetEntity; + if (null === $this->getClassMetadataForClassname($targetEntity)) { + throw new MappingException("Invalid targetEntity"); + } $relationList[] = new Relation( $relation->name,