Skip to content

Commit 53c0142

Browse files
committed
feat(LocationCast): add expression support to get method
1 parent 25c513e commit 53c0142

File tree

2 files changed

+45
-7
lines changed

2 files changed

+45
-7
lines changed

src/Casts/LocationCast.php

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ public function get($model, string $key, $value, array $attributes): ?Point
1919
return null;
2020
}
2121

22-
$coordinates = explode(',', $value);
22+
$coordinates = $this->getCoordinates($model, $value);
2323

2424
if (count($coordinates) > 1) {
2525
$location = explode(',', str_replace(['POINT(', ')', ' '], ['', '', ','], $coordinates[0]));
@@ -51,4 +51,22 @@ public function serialize($model, string $key, $value, array $attributes): array
5151
{
5252
return $value->toArray();
5353
}
54+
55+
private function getCoordinates($model, $value): array
56+
{
57+
if ($value instanceof Expression) {
58+
preg_match(
59+
pattern: "/ST_GeomFromText\(\s*'([^']+)'\s*(?:,\s*(\d+))?\s*(?:,\s*'([^']+)')?\s*\)/",
60+
subject: (string) $value->getValue($model->getConnection()->getQueryGrammar()),
61+
matches: $matches,
62+
);
63+
64+
return [
65+
$matches[1],
66+
(int) ($matches[2] ?? 0),
67+
];
68+
}
69+
70+
return explode(',', $value);
71+
}
5472
}

tests/LocationCastTest.php

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,17 @@
22

33
namespace TarfinLabs\LaravelSpatial\Tests;
44

5+
use Illuminate\Database\Query\Expression;
56
use InvalidArgumentException;
67
use Illuminate\Support\Facades\DB;
8+
use PHPUnit\Framework\Attributes\Test;
79
use TarfinLabs\LaravelSpatial\Casts\LocationCast;
810
use TarfinLabs\LaravelSpatial\Tests\TestModels\Address;
911
use TarfinLabs\LaravelSpatial\Types\Point;
1012

1113
class LocationCastTest extends TestCase
1214
{
13-
/** @test */
15+
#[Test]
1416
public function it_throws_an_exception_if_casted_attribute_set_to_a_non_point_value(): void
1517
{
1618
// 1. Arrange
@@ -23,7 +25,7 @@ public function it_throws_an_exception_if_casted_attribute_set_to_a_non_point_va
2325
$address->location = 'dummy';
2426
}
2527

26-
/** @test */
28+
#[Test]
2729
public function it_can_set_the_casted_attribute_to_a_point(): void
2830
{
2931
// 1. Arrange
@@ -39,7 +41,7 @@ public function it_can_set_the_casted_attribute_to_a_point(): void
3941
$this->assertEquals(DB::raw("ST_GeomFromText('{$point->toWkt()}', 4326, 'axis-order=long-lat')"), $response);
4042
}
4143

42-
/** @test */
44+
#[Test]
4345
public function it_can_set_the_casted_attribute_to_a_point_with_srid(): void
4446
{
4547
// 1. Arrange
@@ -55,7 +57,7 @@ public function it_can_set_the_casted_attribute_to_a_point_with_srid(): void
5557
$this->assertEquals(DB::raw("ST_GeomFromText('{$point->toWkt()}', {$point->getSrid()}, 'axis-order=long-lat')"), $response);
5658
}
5759

58-
/** @test */
60+
#[Test]
5961
public function it_can_get_a_casted_attribute(): void
6062
{
6163
// 1. Arrange
@@ -73,7 +75,25 @@ public function it_can_get_a_casted_attribute(): void
7375
$this->assertEquals($point->getSrid(), $address->location->getSrid());
7476
}
7577

76-
/** @test */
78+
#[Test]
79+
public function it_can_get_a_casted_attribute_using_expression(): void
80+
{
81+
// 1. Arrange
82+
$address = new Address();
83+
$point = new Point(27.1234, 39.1234);
84+
85+
// 2. Act
86+
$cast = new LocationCast();
87+
$result = $cast->get($address, 'location', new Expression($point->toGeomFromText()), $address->getAttributes());
88+
89+
// 3. Assert
90+
$this->assertInstanceOf(Point::class, $result);
91+
$this->assertEquals($point->getLat(), $result->getLat());
92+
$this->assertEquals($point->getLng(), $result->getLng());
93+
$this->assertEquals($point->getSrid(), $result->getSrid());
94+
}
95+
96+
#[Test]
7797
public function it_returns_null_if_the_value_of_the_casted_column_is_null(): void
7898
{
7999
// 1. Arrange
@@ -86,7 +106,7 @@ public function it_returns_null_if_the_value_of_the_casted_column_is_null(): voi
86106
$this->assertNull($address->location);
87107
}
88108

89-
/** @test */
109+
#[Test]
90110
public function it_can_serialize_a_casted_attribute(): void
91111
{
92112
// 1. Arrange

0 commit comments

Comments
 (0)