From bd8d9ef8869c0e1365b066481d5e86de035076d5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Turan=20Karatu=C4=9F?= Date: Wed, 14 May 2025 17:19:49 +0300 Subject: [PATCH 1/2] feat(LocationCast): add expression support to get method --- src/Casts/LocationCast.php | 20 +++++++++++++++++++- tests/LocationCastTest.php | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/Casts/LocationCast.php b/src/Casts/LocationCast.php index 65bbf22..65feb31 100644 --- a/src/Casts/LocationCast.php +++ b/src/Casts/LocationCast.php @@ -19,7 +19,7 @@ public function get($model, string $key, $value, array $attributes): ?Point return null; } - $coordinates = explode(',', $value); + $coordinates = $this->getCoordinates($model, $value); if (count($coordinates) > 1) { $location = explode(',', str_replace(['POINT(', ')', ' '], ['', '', ','], $coordinates[0])); @@ -51,4 +51,22 @@ public function serialize($model, string $key, $value, array $attributes): array { return $value->toArray(); } + + private function getCoordinates($model, $value): array + { + if ($value instanceof Expression) { + preg_match( + pattern: "/ST_GeomFromText\(\s*'([^']+)'\s*(?:,\s*(\d+))?\s*(?:,\s*'([^']+)')?\s*\)/", + subject: (string) $value->getValue($model->getConnection()->getQueryGrammar()), + matches: $matches, + ); + + return [ + $matches[1], + (int) ($matches[2] ?? 0), + ]; + } + + return explode(',', $value); + } } diff --git a/tests/LocationCastTest.php b/tests/LocationCastTest.php index 3c440f0..7d380d7 100644 --- a/tests/LocationCastTest.php +++ b/tests/LocationCastTest.php @@ -2,6 +2,7 @@ namespace TarfinLabs\LaravelSpatial\Tests; +use Illuminate\Database\Query\Expression; use InvalidArgumentException; use Illuminate\Support\Facades\DB; use TarfinLabs\LaravelSpatial\Casts\LocationCast; @@ -73,6 +74,24 @@ public function it_can_get_a_casted_attribute(): void $this->assertEquals($point->getSrid(), $address->location->getSrid()); } + /** @test */ + public function it_can_get_a_casted_attribute_using_expression(): void + { + // 1. Arrange + $address = new Address(); + $point = new Point(27.1234, 39.1234); + + // 2. Act + $cast = new LocationCast(); + $result = $cast->get($address, 'location', new Expression($point->toGeomFromText()), $address->getAttributes()); + + // 3. Assert + $this->assertInstanceOf(Point::class, $result); + $this->assertEquals($point->getLat(), $result->getLat()); + $this->assertEquals($point->getLng(), $result->getLng()); + $this->assertEquals($point->getSrid(), $result->getSrid()); + } + /** @test */ public function it_returns_null_if_the_value_of_the_casted_column_is_null(): void { From 115849d0263db6b120e1d036c82bb90f05c47bca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Turan=20Karatu=C4=9F?= Date: Wed, 14 May 2025 17:21:46 +0300 Subject: [PATCH 2/2] docs(changelog): add changelog entry for 2.2.0 --- CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c696dc8..ee451ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,9 @@ All notable changes to `laravel-spatial` will be documented in this file +## 2.2.0 - 2025-05-15 +- Expression support added to `get()` method in `LocationCast`. + ## 2.1.0 - 2025-02-20 - Removed support for Laravel 11 due to incompatibility with the current implementation.