diff --git a/.run/Test - MySQL 8.0.run.xml b/.run/Test - MySQL.run.xml similarity index 69% rename from .run/Test - MySQL 8.0.run.xml rename to .run/Test - MySQL.run.xml index 4a8f694..a49ed0d 100644 --- a/.run/Test - MySQL 8.0.run.xml +++ b/.run/Test - MySQL.run.xml @@ -1,7 +1,9 @@ - + + + diff --git a/CHANGELOG.md b/CHANGELOG.md index d52f6bb..0457e89 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,18 +2,6 @@ All notable changes to `laravel-eloquent-spatial` will be documented in this file. -## v4.2.1 - 2024-04-02 - -### What's Changed - -* `Geometry::fromArray` added optional`$srid` paramter by @ju-gow in https://github.com/MatanYadaev/laravel-eloquent-spatial/pull/118 - -### New Contributors - -* @ju-gow made their first contribution in https://github.com/MatanYadaev/laravel-eloquent-spatial/pull/118 - -**Full Changelog**: https://github.com/MatanYadaev/laravel-eloquent-spatial/compare/4.2.0...4.2.1 - ## v4.2.0 - 2024-03-13 ### What's Changed diff --git a/README.md b/README.md index e5d3415..1655894 100644 --- a/README.md +++ b/README.md @@ -152,6 +152,8 @@ For more comprehensive documentation on the API, please refer to the [API](API.m ## Extension +### Extend Geometry class with macros + You can add new methods to the `Geometry` class through macros. Here's an example of how to register a macro in your service provider's `boot` method: @@ -177,6 +179,83 @@ $londonEyePoint = new Point(51.5032973, -0.1217424); echo $londonEyePoint->getName(); // Point ``` +### Extend with custom geometry classes + +You can extend the geometry classes by creating custom geometry classes and add functionality. You can also override existing methods, although it is not recommended, as it may lead to unexpected behavior. + +1. Create a custom geometry class that extends the base geometry class. + +```php +use MatanYadaev\EloquentSpatial\Objects\Point; + +class ExtendedPoint extends Point +{ + public function toCustomArray(): array + { + return 'coordinates' => [ + 'latitude' => $this->latitude, + 'longitude' => $this->longitude + ] + } +} +``` + +2. Update the geometry class mapping in a service provider file. + +```php +use App\ValueObjects\ExtendedPoint; +use Illuminate\Support\ServiceProvider; +use MatanYadaev\EloquentSpatial\EloquentSpatial; + +class AppServiceProvider extends ServiceProvider +{ + public function boot(): void + { + EloquentSpatial::usePoint(ExtendedPoint::class); + } +} +``` + +3. Update your model to use the custom geometry class in the `$casts` property or `casts()` method. + +```php +use App\ValueObjects\ExtendedPoint; +use Illuminate\Database\Eloquent\Model; +use MatanYadaev\EloquentSpatial\Traits\HasSpatial; + +class Place extends Model +{ + use HasSpatial; + + protected $casts = [ + 'coordinates' => ExtendedPoint::class, + ]; + + // Or: + + protected function casts(): array + { + return [ + 'coordinates' => ExtendedPoint::class, + ]; + } +} +``` + +4. Use the custom geometry class in your code. + +```php +use App\Models\Location; +use App\ValueObjects\ExtendedPoint; + +$place = Place::create([ + 'name' => 'London Eye', + 'coordinates' => new ExtendedPoint(51.5032973, -0.1217424), +]); + +echo $place->coordinates->toCustomArray(); // ['longitude' => -0.1217424, 'latitude' => 51.5032973] +``` + ## Development Here are some useful commands for development: diff --git a/phpstan.neon b/phpstan.neon index d1db335..a0d0397 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -18,7 +18,8 @@ parameters: - message: '#Call to an undefined method Pest\\Expectation\<.+\>\:\:toBe(InstanceOf)?On(Postgres|Mysql)\(\)#' path: tests/*.php + - + identifier: missingType.generics level: max checkMissingIterableValueType: true - checkGenericClassInNonGenericObjectType: false diff --git a/src/EloquentSpatial.php b/src/EloquentSpatial.php new file mode 100644 index 0000000..39995ee --- /dev/null +++ b/src/EloquentSpatial.php @@ -0,0 +1,107 @@ + */ + public static string $geometryCollection = GeometryCollection::class; + + /** @var class-string */ + public static string $lineString = LineString::class; + + /** @var class-string */ + public static string $multiLineString = MultiLineString::class; + + /** @var class-string */ + public static string $multiPoint = MultiPoint::class; + + /** @var class-string */ + public static string $multiPolygon = MultiPolygon::class; + + /** @var class-string */ + public static string $point = Point::class; + + /** @var class-string */ + public static string $polygon = Polygon::class; + + /** + * @param class-string $class + */ + public static function useGeometryCollection(string $class): string + { + static::$geometryCollection = $class; + + return static::$geometryCollection; + } + + /** + * @param class-string $class + */ + public static function useLineString(string $class): string + { + static::$lineString = $class; + + return static::$lineString; + } + + /** + * @param class-string $class + */ + public static function useMultiLineString(string $class): string + { + static::$multiLineString = $class; + + return static::$multiLineString; + } + + /** + * @param class-string $class + */ + public static function useMultiPoint(string $class): string + { + static::$multiPoint = $class; + + return static::$multiPoint; + } + + /** + * @param class-string $class + */ + public static function useMultiPolygon(string $class): string + { + static::$multiPolygon = $class; + + return static::$multiPolygon; + } + + /** + * @param class-string $class + */ + public static function usePoint(string $class): string + { + static::$point = $class; + + return static::$point; + } + + /** + * @param class-string $class + */ + public static function usePolygon(string $class): string + { + static::$polygon = $class; + + return static::$polygon; + } +} diff --git a/src/Factory.php b/src/Factory.php index 49e0ef3..c0610ba 100644 --- a/src/Factory.php +++ b/src/Factory.php @@ -10,13 +10,6 @@ use InvalidArgumentException; use LineString as geoPHPLineString; use MatanYadaev\EloquentSpatial\Objects\Geometry; -use MatanYadaev\EloquentSpatial\Objects\GeometryCollection; -use MatanYadaev\EloquentSpatial\Objects\LineString; -use MatanYadaev\EloquentSpatial\Objects\MultiLineString; -use MatanYadaev\EloquentSpatial\Objects\MultiPoint; -use MatanYadaev\EloquentSpatial\Objects\MultiPolygon; -use MatanYadaev\EloquentSpatial\Objects\Point; -use MatanYadaev\EloquentSpatial\Objects\Polygon; use MultiLineString as geoPHPMultiLineString; use MultiPoint as geoPHPMultiPoint; use MultiPolygon as geoPHPMultiPolygon; @@ -48,7 +41,7 @@ protected static function createFromGeometry(geoPHPGeometry $geometry): Geometry throw new InvalidArgumentException('Invalid spatial value'); } - return new Point($geometry->coords[1], $geometry->coords[0], $srid); + return new EloquentSpatial::$point($geometry->coords[1], $geometry->coords[0], $srid); } /** @var geoPHPGeometryCollection $geometry */ @@ -58,25 +51,25 @@ protected static function createFromGeometry(geoPHPGeometry $geometry): Geometry }); if ($geometry::class === geoPHPMultiPoint::class) { - return new MultiPoint($components, $srid); + return new EloquentSpatial::$multiPoint($components, $srid); } if ($geometry::class === geoPHPLineString::class) { - return new LineString($components, $srid); + return new EloquentSpatial::$lineString($components, $srid); } if ($geometry::class === geoPHPPolygon::class) { - return new Polygon($components, $srid); + return new EloquentSpatial::$polygon($components, $srid); } if ($geometry::class === geoPHPMultiLineString::class) { - return new MultiLineString($components, $srid); + return new EloquentSpatial::$multiLineString($components, $srid); } if ($geometry::class === geoPHPMultiPolygon::class) { - return new MultiPolygon($components, $srid); + return new EloquentSpatial::$multiPolygon($components, $srid); } - return new GeometryCollection($components, $srid); + return new EloquentSpatial::$geometryCollection($components, $srid); } } diff --git a/src/GeometryCast.php b/src/GeometryCast.php index 213f4f6..fbe00c6 100644 --- a/src/GeometryCast.php +++ b/src/GeometryCast.php @@ -66,7 +66,7 @@ public function set($model, string $key, $value, array $attributes): ?Expression return $value; } - if (! ($value instanceof $this->className)) { + if (! ($value instanceof $this->className) || get_class($value) !== $this->className) { $geometryType = is_object($value) ? $value::class : gettype($value); throw new InvalidArgumentException( sprintf('Expected %s, %s given.', $this->className, $geometryType) diff --git a/src/GeometryExpression.php b/src/GeometryExpression.php index 2b4fed7..fbf2607 100644 --- a/src/GeometryExpression.php +++ b/src/GeometryExpression.php @@ -10,9 +10,7 @@ /** @codeCoverageIgnore */ class GeometryExpression { - public function __construct(readonly private string $expression) - { - } + public function __construct(readonly private string $expression) {} public function normalize(ConnectionInterface $connection): string { diff --git a/tests/HasSpatialTest.php b/tests/HasSpatialTest.php index 1a967a2..a949ae2 100644 --- a/tests/HasSpatialTest.php +++ b/tests/HasSpatialTest.php @@ -447,7 +447,7 @@ }); it('toExpressionString can handle a Expression input', function (): void { - $spatialBuilder = new TestPlace(); + $spatialBuilder = new TestPlace; $toExpressionStringMethod = (new ReflectionClass($spatialBuilder))->getMethod('toExpressionString'); $result = $toExpressionStringMethod->invoke($spatialBuilder, DB::raw('POINT(longitude, latitude)')); @@ -456,7 +456,7 @@ }); it('toExpressionString can handle a Geometry input', function (): void { - $testPlace = new TestPlace(); + $testPlace = new TestPlace; $toExpressionStringMethod = (new ReflectionClass($testPlace))->getMethod('toExpressionString'); $polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}'); @@ -469,7 +469,7 @@ }); it('toExpressionString can handle a string input', function (): void { - $spatialBuilder = new TestPlace(); + $spatialBuilder = new TestPlace; $toExpressionStringMethod = (new ReflectionClass($spatialBuilder))->getMethod('toExpressionString'); $result = $toExpressionStringMethod->invoke($spatialBuilder, 'test_places.point'); diff --git a/tests/Objects/GeometryCollectionTest.php b/tests/Objects/GeometryCollectionTest.php index 9eb0378..29bc435 100644 --- a/tests/Objects/GeometryCollectionTest.php +++ b/tests/Objects/GeometryCollectionTest.php @@ -1,12 +1,15 @@ getName())->toBe('GeometryCollection'); }); + +it('uses an extended GeometryCollection class', function (): void { + // Arrange + EloquentSpatial::useGeometryCollection(ExtendedGeometryCollection::class); + $geometryCollection = new ExtendedGeometryCollection([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + new Point(0, 180), + ], 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['geometry_collection' => $geometryCollection])->fresh(); + + // Assert + expect($testPlace->geometry_collection)->toBeInstanceOf(ExtendedGeometryCollection::class); + expect($testPlace->geometry_collection)->toEqual($geometryCollection); +}); + +it('throws exception when storing a record with regular GeometryCollection instead of the extended one', function (): void { + // Arrange + EloquentSpatial::useGeometryCollection(ExtendedGeometryCollection::class); + $geometryCollection = new GeometryCollection([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + new Point(0, 180), + ], 4326); + + // Act & Assert + expect(function () use ($geometryCollection): void { + TestExtendedPlace::factory()->create(['geometry_collection' => $geometryCollection]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended GeometryCollection instead of the regular one', function (): void { + // Arrange + EloquentSpatial::useGeometryCollection(ExtendedGeometryCollection::class); + $geometryCollection = new ExtendedGeometryCollection([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + new Point(0, 180), + ], 4326); + + // Act & Assert + expect(function () use ($geometryCollection): void { + TestPlace::factory()->create(['geometry_collection' => $geometryCollection]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/LineStringTest.php b/tests/Objects/LineStringTest.php index af40760..3a02b28 100644 --- a/tests/Objects/LineStringTest.php +++ b/tests/Objects/LineStringTest.php @@ -1,11 +1,14 @@ getName())->toBe('LineString'); }); + +it('uses an extended LineString class', function (): void { + // Arrange + EloquentSpatial::useLineString(ExtendedLineString::class); + $lineString = new ExtendedLineString([ + new Point(0, 180), + new Point(1, 179), + ], 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['line_string' => $lineString])->fresh(); + + // Assert + expect($testPlace->line_string)->toBeInstanceOf(ExtendedLineString::class); + expect($testPlace->line_string)->toEqual($lineString); +}); + +it('throws exception when storing a record with regular LineString instead of the extended one', function (): void { + // Arrange + EloquentSpatial::useLineString(ExtendedLineString::class); + $lineString = new LineString([ + new Point(0, 180), + new Point(1, 179), + ], 4326); + + // Act & Assert + expect(function () use ($lineString): void { + TestExtendedPlace::factory()->create(['line_string' => $lineString]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended LineString instead of the regular one', function (): void { + // Arrange + EloquentSpatial::useLineString(LineString::class); + $lineString = new ExtendedLineString([ + new Point(0, 180), + new Point(1, 179), + ], 4326); + + // Act & Assert + expect(function () use ($lineString): void { + TestPlace::factory()->create(['line_string' => $lineString]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/MultiLineStringTest.php b/tests/Objects/MultiLineStringTest.php index 3a8393b..93f015a 100644 --- a/tests/Objects/MultiLineStringTest.php +++ b/tests/Objects/MultiLineStringTest.php @@ -1,11 +1,14 @@ getName())->toBe('MultiLineString'); }); + +it('uses an extended MultiLineString class', function (): void { + // Arrange + EloquentSpatial::useMultiLineString(ExtendedMultiLineString::class); + $multiLineString = new ExtendedMultiLineString([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + ]), + ], 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['multi_line_string' => $multiLineString])->fresh(); + + // Assert + expect($testPlace->multi_line_string)->toBeInstanceOf(ExtendedMultiLineString::class); + expect($testPlace->multi_line_string)->toEqual($multiLineString); +}); + +it('throws exception when storing a record with regular MultiLineString instead of the extended one', function (): void { + // Arrange + EloquentSpatial::useMultiLineString(ExtendedMultiLineString::class); + $multiLineString = new MultiLineString([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + ]), + ], 4326); + + // Act & Assert + expect(function () use ($multiLineString): void { + TestExtendedPlace::factory()->create(['multi_line_string' => $multiLineString]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended MultiLineString instead of the regular one', function (): void { + // Arrange + EloquentSpatial::useMultiLineString(MultiLineString::class); + $multiLineString = new ExtendedMultiLineString([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + ]), + ], 4326); + + // Act & Assert + expect(function () use ($multiLineString): void { + TestPlace::factory()->create(['multi_line_string' => $multiLineString]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/MultiPointTest.php b/tests/Objects/MultiPointTest.php index ea8fdf5..95cfb63 100644 --- a/tests/Objects/MultiPointTest.php +++ b/tests/Objects/MultiPointTest.php @@ -1,11 +1,14 @@ getName())->toBe('MultiPoint'); }); + +it('uses an extended MultiPoint class', function (): void { + // Arrange + EloquentSpatial::useMultiPoint(ExtendedMultiPoint::class); + $multiPoint = new ExtendedMultiPoint([ + new Point(0, 180), + ], 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['multi_point' => $multiPoint])->fresh(); + + // Assert + expect($testPlace->multi_point)->toBeInstanceOf(ExtendedMultiPoint::class); + expect($testPlace->multi_point)->toEqual($multiPoint); +}); + +it('throws exception when storing a record with regular MultiPoint instead of the extended one', function (): void { + // Arrange + EloquentSpatial::useMultiPoint(ExtendedMultiPoint::class); + $multiPoint = new MultiPoint([ + new Point(0, 180), + ], 4326); + + // Act & Assert + expect(function () use ($multiPoint): void { + TestExtendedPlace::factory()->create(['multi_point' => $multiPoint]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended MultiPoint instead of the regular one', function (): void { + // Arrange + EloquentSpatial::useMultiPoint(MultiPoint::class); + $multiPoint = new ExtendedMultiPoint([ + new Point(0, 180), + ], 4326); + + // Act & Assert + expect(function () use ($multiPoint): void { + TestPlace::factory()->create(['multi_point' => $multiPoint]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/MultiPolygonTest.php b/tests/Objects/MultiPolygonTest.php index 20f3692..2f53aef 100644 --- a/tests/Objects/MultiPolygonTest.php +++ b/tests/Objects/MultiPolygonTest.php @@ -1,12 +1,15 @@ getName())->toBe('MultiPolygon'); }); + +it('uses an extended MultiPolygon class', function (): void { + // Arrange + EloquentSpatial::useMultiPolygon(ExtendedMultiPolygon::class); + $multiPolygon = new ExtendedMultiPolygon([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + ], 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['multi_polygon' => $multiPolygon])->fresh(); + + // Assert + expect($testPlace->multi_polygon)->toBeInstanceOf(ExtendedMultiPolygon::class); + expect($testPlace->multi_polygon)->toEqual($multiPolygon); +}); + +it('throws exception when storing a record with regular MultiPolygon instead of the extended one', function (): void { + // Arrange + EloquentSpatial::useMultiPolygon(ExtendedMultiPolygon::class); + $multiPolygon = new MultiPolygon([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + ], 4326); + + // Act & Assert + expect(function () use ($multiPolygon): void { + TestExtendedPlace::factory()->create(['multi_polygon' => $multiPolygon]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended MultiPolygon instead of the regular one', function (): void { + // Arrange + EloquentSpatial::useMultiPolygon(MultiPolygon::class); + $multiPolygon = new ExtendedMultiPolygon([ + new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ]), + ], 4326); + + // Act & Assert + expect(function () use ($multiPolygon): void { + TestPlace::factory()->create(['multi_polygon' => $multiPolygon]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/PointTest.php b/tests/Objects/PointTest.php index b1ad8e6..26f3934 100644 --- a/tests/Objects/PointTest.php +++ b/tests/Objects/PointTest.php @@ -1,9 +1,12 @@ getName())->toBe('Point'); }); + +it('uses an extended Point class', function (): void { + // Arrange + EloquentSpatial::usePoint(ExtendedPoint::class); + $point = new ExtendedPoint(0, 180, 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['point' => $point])->fresh(); + + // Assert + expect($testPlace->point)->toBeInstanceOf(ExtendedPoint::class); + expect($testPlace->point)->toEqual($point); +}); + +it('throws exception when storing a record with regular Point instead of the extended one', function (): void { + // Arrange + EloquentSpatial::usePoint(ExtendedPoint::class); + $point = new Point(0, 180, 4326); + + // Act & Assert + expect(function () use ($point): void { + TestExtendedPlace::factory()->create(['point' => $point]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended Point instead of the regular one', function (): void { + // Arrange + EloquentSpatial::usePoint(Point::class); + $point = new ExtendedPoint(0, 180, 4326); + + // Act & Assert + expect(function () use ($point): void { + TestPlace::factory()->create(['point' => $point]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/Objects/PolygonTest.php b/tests/Objects/PolygonTest.php index 0c49d8d..e3c55d9 100644 --- a/tests/Objects/PolygonTest.php +++ b/tests/Objects/PolygonTest.php @@ -1,11 +1,14 @@ getName())->toBe('Polygon'); }); + +it('uses an extended Polygon class', function (): void { + // Arrange + EloquentSpatial::usePolygon(ExtendedPolygon::class); + $polygon = new ExtendedPolygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ], 4326); + + // Act + /** @var TestExtendedPlace $testPlace */ + $testPlace = TestExtendedPlace::factory()->create(['polygon' => $polygon])->fresh(); + + // Assert + expect($testPlace->polygon)->toBeInstanceOf(ExtendedPolygon::class); + expect($testPlace->polygon)->toEqual($polygon); +}); + +it('throws exception when storing a record with regular Polygon instead of the extended one', function (): void { + // Arrange + EloquentSpatial::usePolygon(ExtendedPolygon::class); + $polygon = new Polygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ], 4326); + + // Act & Assert + expect(function () use ($polygon): void { + TestExtendedPlace::factory()->create(['polygon' => $polygon]); + })->toThrow(InvalidArgumentException::class); +}); + +it('throws exception when storing a record with extended Polygon instead of the regular one', function (): void { + // Arrange + EloquentSpatial::usePolygon(Polygon::class); + $polygon = new ExtendedPolygon([ + new LineString([ + new Point(0, 180), + new Point(1, 179), + new Point(2, 178), + new Point(3, 177), + new Point(0, 180), + ]), + ], 4326); + + // Act & Assert + expect(function () use ($polygon): void { + TestPlace::factory()->create(['polygon' => $polygon]); + })->toThrow(InvalidArgumentException::class); +}); diff --git a/tests/TestCase.php b/tests/TestCase.php index f031e3b..2e3b748 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -4,7 +4,15 @@ use Illuminate\Foundation\Application; use Illuminate\Support\ServiceProvider; +use MatanYadaev\EloquentSpatial\EloquentSpatial; use MatanYadaev\EloquentSpatial\EloquentSpatialServiceProvider; +use MatanYadaev\EloquentSpatial\Objects\GeometryCollection; +use MatanYadaev\EloquentSpatial\Objects\LineString; +use MatanYadaev\EloquentSpatial\Objects\MultiLineString; +use MatanYadaev\EloquentSpatial\Objects\MultiPoint; +use MatanYadaev\EloquentSpatial\Objects\MultiPolygon; +use MatanYadaev\EloquentSpatial\Objects\Point; +use MatanYadaev\EloquentSpatial\Objects\Polygon; use Orchestra\Testbench\TestCase as Orchestra; class TestCase extends Orchestra @@ -13,6 +21,8 @@ protected function setUp(): void { parent::setUp(); + $this->resetGeometryClasses(); + // @phpstan-ignore-next-line if (version_compare(Application::VERSION, '11.0.0', '>=')) { $this->loadMigrationsFrom(__DIR__.'/database/migrations-laravel->=11'); @@ -30,4 +40,15 @@ protected function getPackageProviders($app): array EloquentSpatialServiceProvider::class, ]; } + + protected function resetGeometryClasses(): void + { + EloquentSpatial::useGeometryCollection(GeometryCollection::class); + EloquentSpatial::useLineString(LineString::class); + EloquentSpatial::useMultiLineString(MultiLineString::class); + EloquentSpatial::useMultiPoint(MultiPoint::class); + EloquentSpatial::useMultiPolygon(MultiPolygon::class); + EloquentSpatial::usePoint(Point::class); + EloquentSpatial::usePolygon(Polygon::class); + } } diff --git a/tests/TestFactories/TestExtendedPlaceFactory.php b/tests/TestFactories/TestExtendedPlaceFactory.php new file mode 100644 index 0000000..ec630cc --- /dev/null +++ b/tests/TestFactories/TestExtendedPlaceFactory.php @@ -0,0 +1,25 @@ + + */ +class TestExtendedPlaceFactory extends Factory +{ + protected $model = TestExtendedPlace::class; + + /** + * @return array + */ + public function definition(): array + { + return [ + 'name' => $this->faker->streetName, + 'address' => $this->faker->address, + ]; + } +} diff --git a/tests/TestModels/TestExtendedPlace.php b/tests/TestModels/TestExtendedPlace.php new file mode 100644 index 0000000..5e0d9ba --- /dev/null +++ b/tests/TestModels/TestExtendedPlace.php @@ -0,0 +1,47 @@ + ExtendedGeometryCollection::class, + 'line_string' => ExtendedLineString::class, + 'multi_line_string' => ExtendedMultiLineString::class, + 'multi_point' => ExtendedMultiPoint::class, + 'multi_polygon' => ExtendedMultiPolygon::class, + 'point' => ExtendedPoint::class, + 'polygon' => ExtendedPolygon::class, + ]; + + protected static function newFactory(): TestExtendedPlaceFactory + { + return TestExtendedPlaceFactory::new(); + } +} diff --git a/tests/TestObjects/ExtendedGeometryCollection.php b/tests/TestObjects/ExtendedGeometryCollection.php new file mode 100644 index 0000000..ddc5412 --- /dev/null +++ b/tests/TestObjects/ExtendedGeometryCollection.php @@ -0,0 +1,7 @@ +id(); + $table->timestamps(); + $table->string('name'); + $table->string('address'); + $table->point('point')->isGeometry()->nullable(); + $table->multiPoint('multi_point')->isGeometry()->nullable(); + $table->lineString('line_string')->isGeometry()->nullable(); + $table->multiLineString('multi_line_string')->isGeometry()->nullable(); + $table->polygon('polygon')->isGeometry()->nullable(); + $table->multiPolygon('multi_polygon')->isGeometry()->nullable(); + $table->geometryCollection('geometry_collection')->isGeometry()->nullable(); + $table->point('point_with_line_string_cast')->isGeometry()->nullable(); + $table->point('point_geography')->nullable(); + $table->decimal('longitude')->nullable(); + $table->decimal('latitude')->nullable(); + }); + } + + public function down(): void + { + Schema::dropIfExists('test_extended_places'); + } +} diff --git a/tests/database/migrations-laravel->=11/0000_00_00_000000_create_test_extended_places_table.php b/tests/database/migrations-laravel->=11/0000_00_00_000000_create_test_extended_places_table.php new file mode 100644 index 0000000..8583367 --- /dev/null +++ b/tests/database/migrations-laravel->=11/0000_00_00_000000_create_test_extended_places_table.php @@ -0,0 +1,33 @@ +id(); + $table->timestamps(); + $table->string('name'); + $table->string('address'); + $table->geometry('point', 'point')->nullable(); + $table->geometry('multi_point', 'multipoint')->nullable(); + $table->geometry('line_string', 'linestring')->nullable(); + $table->geometry('multi_line_string', 'multilinestring')->nullable(); + $table->geometry('polygon', 'polygon')->nullable(); + $table->geometry('multi_polygon', 'multipolygon')->nullable(); + $table->geometry('geometry_collection', 'geometrycollection')->nullable(); + $table->geometry('point_with_line_string_cast', 'point')->nullable(); + $table->decimal('longitude')->nullable(); + $table->decimal('latitude')->nullable(); + }); + } + + public function down(): void + { + Schema::dropIfExists('test_extended_places'); + } +}