Skip to content

Commit 714b54e

Browse files
committed
[bugfix] know laravel can determine if geometry columns are dirty or not
1 parent 8cc8eeb commit 714b54e

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

src/GeometryCast.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
88
use Illuminate\Database\Eloquent\Model;
99
use Illuminate\Database\Query\Expression;
10+
use Illuminate\Support\Str;
1011
use InvalidArgumentException;
1112
use MatanYadaev\EloquentSpatial\Objects\Geometry;
1213

@@ -63,4 +64,37 @@ public function set($model, string $key, $geometry, array $attributes): Expressi
6364

6465
return $geometry->toWkt();
6566
}
67+
68+
/**
69+
* Compare current and original attribute values.
70+
* Returns true if values are equal and false otherwise.
71+
*
72+
* @param mixed $value
73+
* @param mixed $originalValue
74+
* @return bool
75+
*/
76+
public function compare(mixed $value, mixed $originalValue): bool
77+
{
78+
if ($value === $originalValue) {
79+
return true;
80+
}
81+
82+
if ($value === null and $originalValue) {
83+
return false;
84+
}
85+
86+
if ($value and is_a($value, Expression::class)) {
87+
if ($originalValue === null) {
88+
return false;
89+
}
90+
91+
if (Str::isJson($originalValue)) {
92+
$originalValue = $this->className::fromJson($originalValue)->toWkt();
93+
94+
return $originalValue->getValue() === $value->getValue();
95+
}
96+
}
97+
98+
return false;
99+
}
66100
}

src/Traits/HasSpatialColumns.php

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace MatanYadaev\EloquentSpatial\Traits;
44

5+
use Illuminate\Support\Arr;
56
use Illuminate\Support\Str;
67
use MatanYadaev\EloquentSpatial\Objects\GeometryCollection;
78
use MatanYadaev\EloquentSpatial\Objects\LineString;
@@ -53,6 +54,25 @@ public function setRawAttributes(array $attributes, $sync = false): self
5354
return parent::setRawAttributes($attributes, $sync);
5455
}
5556

57+
/**
58+
* @inheritDoc
59+
*/
60+
public function originalIsEquivalent($key): bool
61+
{
62+
if (! array_key_exists($key, $this->original)) {
63+
return false;
64+
}
65+
66+
if ($this->isClassComparable($key)) {
67+
$attribute = Arr::get($this->attributes, $key);
68+
$original = Arr::get($this->original, $key);
69+
70+
return $this->resolveCasterClass($key)->compare($attribute, $original);
71+
}
72+
73+
return parent::originalIsEquivalent($key);
74+
}
75+
5676
/**
5777
* @return array
5878
*/
@@ -68,4 +88,33 @@ private function getSpatialColumns(): array
6888

6989
return $columns;
7090
}
91+
92+
/**
93+
* Determine if an attribute can be checked for being dirty using a custom class.
94+
*
95+
* @param string $key
96+
* @return bool
97+
*
98+
* @throws \Illuminate\Database\Eloquent\InvalidCastException
99+
*/
100+
private function isClassComparable(string $key): bool
101+
{
102+
if ($this->isClassCastable($key)) {
103+
$castClass = $this->parseCasterClass($this->getCasts()[$key]);
104+
105+
if (method_exists($castClass, 'compare')) {
106+
return true;
107+
}
108+
109+
if (method_exists($castClass, 'castUsing')) {
110+
$castClass = $castClass::castUsing([]);
111+
112+
if (method_exists($castClass, 'compare')) {
113+
return true;
114+
}
115+
}
116+
}
117+
118+
return false;
119+
}
71120
}

0 commit comments

Comments
 (0)