From df3ed5547aa957dac9ad9ec94f0c078fc3eddec9 Mon Sep 17 00:00:00 2001 From: Matan Yadaev Date: Wed, 6 Mar 2024 00:14:57 +0200 Subject: [PATCH] override originalIsEquivalent to compare geometries (#115) --- src/GeometryCast.php | 2 +- src/Traits/HasSpatial.php | 20 ++++++++++++ tests/GeometryCastTest.php | 63 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 84 insertions(+), 1 deletion(-) diff --git a/src/GeometryCast.php b/src/GeometryCast.php index a994059..213f4f6 100644 --- a/src/GeometryCast.php +++ b/src/GeometryCast.php @@ -69,7 +69,7 @@ public function set($model, string $key, $value, array $attributes): ?Expression if (! ($value instanceof $this->className)) { $geometryType = is_object($value) ? $value::class : gettype($value); throw new InvalidArgumentException( - sprintf('Expected %s, %s given.', static::class, $geometryType) + sprintf('Expected %s, %s given.', $this->className, $geometryType) ); } diff --git a/src/Traits/HasSpatial.php b/src/Traits/HasSpatial.php index ad6ee75..14816f0 100644 --- a/src/Traits/HasSpatial.php +++ b/src/Traits/HasSpatial.php @@ -11,6 +11,26 @@ trait HasSpatial { + public function originalIsEquivalent($key) + { + if (! array_key_exists($key, $this->original)) { + return false; + } + + $casts = $this->getCasts(); + + if (array_key_exists($key, $casts)) { + $original = $this->getOriginal($key); + $attribute = $this->getAttributeValue($key); + + if ($original instanceof Geometry && $attribute instanceof Geometry) { + return $original->getWktData() === $attribute->getWktData(); + } + } + + return parent::originalIsEquivalent($key); + } + public function scopeWithDistance( Builder $query, ExpressionContract|Geometry|string $column, diff --git a/tests/GeometryCastTest.php b/tests/GeometryCastTest.php index 4073d14..5f98015 100644 --- a/tests/GeometryCastTest.php +++ b/tests/GeometryCastTest.php @@ -126,3 +126,66 @@ expect($testPlace->point)->toEqual($point); }); + +it('checks a model record is not dirty after creation', function (): void { + $point = new Point(0, 180); + + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); + + expect($testPlace->isDirty())->toBeFalse(); +}); + +it('checks a model record is not dirty after fetch', function (): void { + $point = new Point(0, 180); + TestPlace::factory()->create(['point' => $point]); + + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::firstOrFail(); + + expect($testPlace->isDirty())->toBeFalse(); +}); + +it('checks a model record is dirty after update from null before save', function (): void { + $point = new Point(0, 180); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create([]); + + $testPlace->point = $point; + + expect($testPlace->isDirty())->toBeTrue(); +}); + +it('checks a model record is dirty after update before save', function (): void { + $point = new Point(0, 180); + $point2 = new Point(0, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); + + $testPlace->point = $point2; + + expect($testPlace->isDirty())->toBeTrue(); +}); + +it('checks a model record is not dirty after update and save', function (): void { + $point = new Point(0, 180); + $point2 = new Point(0, 0); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); + + $testPlace->point = $point2; + $testPlace->save(); + + expect($testPlace->isDirty())->toBeFalse(); +}); + +it('checks a model record is not dirty after update to same value before save', function (): void { + $point = new Point(0, 180); + $point2 = new Point(0, 180); + /** @var TestPlace $testPlace */ + $testPlace = TestPlace::factory()->create(['point' => $point]); + + $testPlace->point = $point2; + + expect($testPlace->isDirty())->toBeFalse(); +});