From 009d4fa2d214759a451ac02d4ff61832290ff1e7 Mon Sep 17 00:00:00 2001 From: Aliaksei Sanikovich Date: Sun, 29 Sep 2024 23:40:00 +0200 Subject: [PATCH 1/6] v2.0.2: supports Laravel 11+ and PHP 8.2+ --- .github/workflows/pest.yml | 6 +++--- .github/workflows/phpstan.yml | 2 +- README.md | 2 +- composer.json | 12 ++++++------ phpstan.neon | 2 +- src/Eloquent/HasSpatial.php | 2 +- tests/Geometry/GeometryCollectionTest.php | 1 - tests/Geometry/LineStringTest.php | 1 - tests/Geometry/MultiLineStringTest.php | 1 - tests/Geometry/MultiPointTest.php | 1 - tests/Geometry/MultiPolygonTest.php | 1 - tests/Geometry/PointTest.php | 1 - tests/Geometry/PolygonTest.php | 1 - 13 files changed, 13 insertions(+), 20 deletions(-) diff --git a/.github/workflows/pest.yml b/.github/workflows/pest.yml index 84e08f1..3856f8a 100644 --- a/.github/workflows/pest.yml +++ b/.github/workflows/pest.yml @@ -11,12 +11,12 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.2, 8.1 ] - laravel: [ 10.* ] + php: [ 8.1, 8.2, 8.3 ] + laravel: [ 10.*, 11.* ] db: [ 'mysql:8.0', 'mysql:5.7', 'mariadb:10.9' ] dependency-version: [ prefer-stable ] include: - - laravel: 10.* + - laravel: ${{ matrix.laravel }} testbench: ^8.0 services: diff --git a/.github/workflows/phpstan.yml b/.github/workflows/phpstan.yml index 7244bcb..bfea8cb 100644 --- a/.github/workflows/phpstan.yml +++ b/.github/workflows/phpstan.yml @@ -11,7 +11,7 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.2, 8.1 ] + php: [ 8.1, 8.2, 8.3 ] steps: - name: Checkout code diff --git a/README.md b/README.md index c16b71b..ccb7bff 100644 --- a/README.md +++ b/README.md @@ -10,7 +10,7 @@ **This Laravel package allows you to easily work with spatial data types and functions.** -* v2 supports Laravel 10+ and PHP 8.1+ +* v2 supports Laravel 10,11 and PHP 8.1+ * v1 supports Laravel 8,9 and PHP 8.1+ This package supports MySQL v8 or v5.7, and MariaDB v10. diff --git a/composer.json b/composer.json index f325df6..83dbd67 100644 --- a/composer.json +++ b/composer.json @@ -13,16 +13,16 @@ "php": "^8.1", "ext-json": "*", "ext-pdo": "*", - "laravel/framework": "^10.0", + "laravel/framework": "^10.0|^11.0", "phayes/geophp": "^1.2" }, "require-dev": { - "doctrine/dbal": "^3.0", + "doctrine/dbal": "^3.0|^4.1", "laravel/pint": "^1.5", - "nunomaduro/larastan": "^1.0|^2.4", - "orchestra/testbench": "^8.0", - "pestphp/pest": "^1.0|^2.6", - "pestphp/pest-plugin-laravel": "^1.0|^2.0" + "larastan/larastan": "^1.0|^2.4", + "orchestra/testbench": "^8.0|^9.4", + "pestphp/pest": "^1.0|^2.6|^3.0", + "pestphp/pest-plugin-laravel": "^1.0|^2.0|^3.0" }, "autoload": { "psr-4": { diff --git a/phpstan.neon b/phpstan.neon index e1ef02e..26fac8c 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,5 @@ includes: - - ./vendor/nunomaduro/larastan/extension.neon + - ./vendor/larastan/larastan/extension.neon parameters: paths: - src diff --git a/src/Eloquent/HasSpatial.php b/src/Eloquent/HasSpatial.php index 9ba9870..689ba48 100644 --- a/src/Eloquent/HasSpatial.php +++ b/src/Eloquent/HasSpatial.php @@ -4,7 +4,7 @@ use ASanikovich\LaravelSpatial\Geometry\Geometry; use Illuminate\Database\Eloquent\Builder; -use Illuminate\Database\Query\Expression; +use Illuminate\Contracts\Database\Query\Expression; /** * @method static withDistance(Expression|Geometry|string $column, Expression|Geometry|string $geometryOrColumn, string $alias = 'distance') diff --git a/tests/Geometry/GeometryCollectionTest.php b/tests/Geometry/GeometryCollectionTest.php index a8872d8..c8aa5ee 100644 --- a/tests/Geometry/GeometryCollectionTest.php +++ b/tests/Geometry/GeometryCollectionTest.php @@ -373,7 +373,6 @@ it('adds a macro toGeometryCollection', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); diff --git a/tests/Geometry/LineStringTest.php b/tests/Geometry/LineStringTest.php index 2c2c4f4..74094fa 100644 --- a/tests/Geometry/LineStringTest.php +++ b/tests/Geometry/LineStringTest.php @@ -167,7 +167,6 @@ it('adds a macro toLineString', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); diff --git a/tests/Geometry/MultiLineStringTest.php b/tests/Geometry/MultiLineStringTest.php index cff772d..9e922c3 100644 --- a/tests/Geometry/MultiLineStringTest.php +++ b/tests/Geometry/MultiLineStringTest.php @@ -189,7 +189,6 @@ it('adds a macro toMultiLineString', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); diff --git a/tests/Geometry/MultiPointTest.php b/tests/Geometry/MultiPointTest.php index eeb9b9e..73a58b4 100644 --- a/tests/Geometry/MultiPointTest.php +++ b/tests/Geometry/MultiPointTest.php @@ -152,7 +152,6 @@ it('adds a macro toMultiPoint', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); diff --git a/tests/Geometry/MultiPolygonTest.php b/tests/Geometry/MultiPolygonTest.php index 601e981..4da4e38 100644 --- a/tests/Geometry/MultiPolygonTest.php +++ b/tests/Geometry/MultiPolygonTest.php @@ -251,7 +251,6 @@ it('adds a macro toMultiPolygon', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); diff --git a/tests/Geometry/PointTest.php b/tests/Geometry/PointTest.php index d36307f..b38b8a1 100644 --- a/tests/Geometry/PointTest.php +++ b/tests/Geometry/PointTest.php @@ -108,7 +108,6 @@ it('adds a macro toPoint', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); diff --git a/tests/Geometry/PolygonTest.php b/tests/Geometry/PolygonTest.php index 65cd2f7..d7d90d9 100644 --- a/tests/Geometry/PolygonTest.php +++ b/tests/Geometry/PolygonTest.php @@ -223,7 +223,6 @@ it('adds a macro toPolygon', function (): void { Geometry::macro('getName', function (): string { /** @var Geometry $this */ - // @phpstan-ignore-next-line return class_basename($this); }); From 0b9149b7812047596875da64cb22afb6b6b8487a Mon Sep 17 00:00:00 2001 From: Aliaksei Sanikovich Date: Sun, 29 Sep 2024 23:55:23 +0200 Subject: [PATCH 2/6] pint --- src/Eloquent/GeometryCast.php | 2 +- src/Eloquent/HasSpatial.php | 2 +- src/Exceptions/LaravelSpatialException.php | 4 +--- src/Exceptions/LaravelSpatialJsonException.php | 4 +--- src/Geometry/Geometry.php | 4 ++-- tests/Custom/CustomPoint.php | 4 +--- tests/Custom/CustomPointConfig.php | 4 +--- tests/Custom/CustomPointInvalid.php | 4 +--- tests/Eloquent/HasSpatialTest.php | 6 +++--- tests/Pest.php | 2 +- 10 files changed, 13 insertions(+), 23 deletions(-) diff --git a/src/Eloquent/GeometryCast.php b/src/Eloquent/GeometryCast.php index feab693..a04e148 100644 --- a/src/Eloquent/GeometryCast.php +++ b/src/Eloquent/GeometryCast.php @@ -50,7 +50,7 @@ public function get(Model $model, string $key, mixed $value, array $attributes): * * @throws LaravelSpatialException */ - public function set(Model $model, string $key, mixed $value, array $attributes): Expression|null + public function set(Model $model, string $key, mixed $value, array $attributes): ?Expression { if (! $value) { return null; diff --git a/src/Eloquent/HasSpatial.php b/src/Eloquent/HasSpatial.php index 689ba48..09c6236 100644 --- a/src/Eloquent/HasSpatial.php +++ b/src/Eloquent/HasSpatial.php @@ -3,8 +3,8 @@ namespace ASanikovich\LaravelSpatial\Eloquent; use ASanikovich\LaravelSpatial\Geometry\Geometry; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Contracts\Database\Query\Expression; +use Illuminate\Database\Eloquent\Builder; /** * @method static withDistance(Expression|Geometry|string $column, Expression|Geometry|string $geometryOrColumn, string $alias = 'distance') diff --git a/src/Exceptions/LaravelSpatialException.php b/src/Exceptions/LaravelSpatialException.php index b6f7d4e..afeac1b 100644 --- a/src/Exceptions/LaravelSpatialException.php +++ b/src/Exceptions/LaravelSpatialException.php @@ -6,6 +6,4 @@ use DomainException; -class LaravelSpatialException extends DomainException -{ -} +class LaravelSpatialException extends DomainException {} diff --git a/src/Exceptions/LaravelSpatialJsonException.php b/src/Exceptions/LaravelSpatialJsonException.php index 642f39a..fb7ecfe 100644 --- a/src/Exceptions/LaravelSpatialJsonException.php +++ b/src/Exceptions/LaravelSpatialJsonException.php @@ -4,6 +4,4 @@ namespace ASanikovich\LaravelSpatial\Exceptions; -class LaravelSpatialJsonException extends LaravelSpatialException -{ -} +class LaravelSpatialJsonException extends LaravelSpatialException {} diff --git a/src/Geometry/Geometry.php b/src/Geometry/Geometry.php index 31d353f..f86018e 100644 --- a/src/Geometry/Geometry.php +++ b/src/Geometry/Geometry.php @@ -23,7 +23,7 @@ use Throwable; use WKB as geoPHPWkb; -abstract class Geometry implements Castable, Arrayable, Jsonable, JsonSerializable, Stringable +abstract class Geometry implements Arrayable, Castable, Jsonable, JsonSerializable, Stringable { use Macroable; @@ -189,7 +189,7 @@ public function toSqlExpression(ConnectionInterface $connection): Expression { $wkt = $this->toWkt(); - if (! (new Connection())->isSupportAxisOrder($connection)) { + if (! (new Connection)->isSupportAxisOrder($connection)) { // @codeCoverageIgnoreStart return DB::raw(sprintf("ST_GeomFromText('%s', %d)", $wkt, $this->srid)); // @codeCoverageIgnoreEnd diff --git a/tests/Custom/CustomPoint.php b/tests/Custom/CustomPoint.php index da48e78..a65a218 100644 --- a/tests/Custom/CustomPoint.php +++ b/tests/Custom/CustomPoint.php @@ -6,6 +6,4 @@ use ASanikovich\LaravelSpatial\Geometry\Point; -class CustomPoint extends Point -{ -} +class CustomPoint extends Point {} diff --git a/tests/Custom/CustomPointConfig.php b/tests/Custom/CustomPointConfig.php index ea71286..853775e 100644 --- a/tests/Custom/CustomPointConfig.php +++ b/tests/Custom/CustomPointConfig.php @@ -6,6 +6,4 @@ use ASanikovich\LaravelSpatial\Geometry\Point; -class CustomPointConfig extends Point -{ -} +class CustomPointConfig extends Point {} diff --git a/tests/Custom/CustomPointInvalid.php b/tests/Custom/CustomPointInvalid.php index 770eb98..c3a19dd 100644 --- a/tests/Custom/CustomPointInvalid.php +++ b/tests/Custom/CustomPointInvalid.php @@ -4,6 +4,4 @@ namespace ASanikovich\LaravelSpatial\Tests\Custom; -class CustomPointInvalid -{ -} +class CustomPointInvalid {} diff --git a/tests/Eloquent/HasSpatialTest.php b/tests/Eloquent/HasSpatialTest.php index 060a0ef..706107c 100644 --- a/tests/Eloquent/HasSpatialTest.php +++ b/tests/Eloquent/HasSpatialTest.php @@ -382,7 +382,7 @@ }); it('toSpatialExpressionString can handle a Expression input', function (): void { - $model = new TestPlace(); + $model = new TestPlace; $method = (new ReflectionClass(TestPlace::class))->getMethod('toSpatialExpressionString'); $result = $method->invoke($model, $model->newQuery(), DB::raw('POINT(longitude, latitude)')); @@ -391,7 +391,7 @@ }); it('toSpatialExpressionString can handle a Geometry input', function (): void { - $model = new TestPlace(); + $model = new TestPlace; $method = (new ReflectionClass(TestPlace::class))->getMethod('toSpatialExpressionString'); $polygon = Polygon::fromJson('{"type":"Polygon","coordinates":[[[-1,-1],[1,-1],[1,1],[-1,1],[-1,-1]]]}'); @@ -404,7 +404,7 @@ }); it('toSpatialExpressionString can handle a string input', function (): void { - $model = new TestPlace(); + $model = new TestPlace; $method = (new ReflectionClass(TestPlace::class))->getMethod('toSpatialExpressionString'); $result = $method->invoke($model, $model->newQuery(), 'test_places.point'); diff --git a/tests/Pest.php b/tests/Pest.php index 79449ec..d8d2d75 100644 --- a/tests/Pest.php +++ b/tests/Pest.php @@ -9,7 +9,7 @@ function isSupportAxisOrder(): bool { - return (new Connection())->isSupportAxisOrder(DB::connection()); + return (new Connection)->isSupportAxisOrder(DB::connection()); } /** From bcd47da0d3d4263b32d04522473c910816d2094a Mon Sep 17 00:00:00 2001 From: Aliaksei Sanikovich Date: Sun, 29 Sep 2024 23:59:14 +0200 Subject: [PATCH 3/6] fix --- src/Eloquent/GeometryCast.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Eloquent/GeometryCast.php b/src/Eloquent/GeometryCast.php index a04e148..0431042 100644 --- a/src/Eloquent/GeometryCast.php +++ b/src/Eloquent/GeometryCast.php @@ -79,7 +79,7 @@ private function extractWktFromExpression(Expression $expression, Connection $co preg_match('/ST_GeomFromText\(\'(.+)\', .+(, .+)?\)/', (string) $expressionValue, $match); - return $match[1]; + return $match[1] ?? ''; } private function extractSridFromExpression(Expression $expression, Connection $connection): int @@ -88,6 +88,6 @@ private function extractSridFromExpression(Expression $expression, Connection $c preg_match('/ST_GeomFromText\(\'.+\', (.+)(, .+)?\)/', (string) $expressionValue, $match); - return (int) $match[1]; + return (int) ($match[1] ?? 0); } } From ea59b200d87023000204e314d0515ace4880e1bb Mon Sep 17 00:00:00 2001 From: Aliaksei Sanikovich Date: Mon, 30 Sep 2024 00:01:31 +0200 Subject: [PATCH 4/6] fix --- .github/workflows/pest.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/pest.yml b/.github/workflows/pest.yml index 3856f8a..aa38d4e 100644 --- a/.github/workflows/pest.yml +++ b/.github/workflows/pest.yml @@ -16,8 +16,7 @@ jobs: db: [ 'mysql:8.0', 'mysql:5.7', 'mariadb:10.9' ] dependency-version: [ prefer-stable ] include: - - laravel: ${{ matrix.laravel }} - testbench: ^8.0 + - testbench: ^8.0 services: db: From 2f12381370737c0671bdf338f69d7189bfd44320 Mon Sep 17 00:00:00 2001 From: Aliaksei Sanikovich Date: Mon, 30 Sep 2024 00:08:56 +0200 Subject: [PATCH 5/6] pest --- .github/workflows/pest.yml | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/.github/workflows/pest.yml b/.github/workflows/pest.yml index aa38d4e..8590c2c 100644 --- a/.github/workflows/pest.yml +++ b/.github/workflows/pest.yml @@ -11,12 +11,15 @@ jobs: strategy: fail-fast: false matrix: - php: [ 8.1, 8.2, 8.3 ] - laravel: [ 10.*, 11.* ] + php: [ 8.1, 8.2 ] + laravel: [ 10.* ] db: [ 'mysql:8.0', 'mysql:5.7', 'mariadb:10.9' ] dependency-version: [ prefer-stable ] include: - - testbench: ^8.0 + - php: 8.2 + laravel: 11.* + - php: 8.3 + laravel: 11.* services: db: @@ -40,7 +43,7 @@ jobs: - name: Install dependencies run: | - composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench:${{ matrix.testbench }}" --no-interaction --no-update + composer require "laravel/framework:${{ matrix.laravel }}" "orchestra/testbench" --no-interaction --no-update composer update --${{ matrix.dependency-version }} --prefer-dist --no-interaction - name: Execute tests From abbea2e6dd539dafe69314a3327f57ebec5f6d61 Mon Sep 17 00:00:00 2001 From: Aliaksei Sanikovich Date: Mon, 30 Sep 2024 00:20:25 +0200 Subject: [PATCH 6/6] l11 --- src/LaravelSpatialServiceProvider.php | 38 ++++++++++++++++----------- 1 file changed, 22 insertions(+), 16 deletions(-) diff --git a/src/LaravelSpatialServiceProvider.php b/src/LaravelSpatialServiceProvider.php index 684c3e9..7bccb2f 100644 --- a/src/LaravelSpatialServiceProvider.php +++ b/src/LaravelSpatialServiceProvider.php @@ -8,7 +8,7 @@ use ASanikovich\LaravelSpatial\Exceptions\LaravelSpatialException; use Doctrine\DBAL\Types\Type; use Illuminate\Database\DatabaseServiceProvider; -use Illuminate\Support\Facades\DB; +use RuntimeException; use Throwable; final class LaravelSpatialServiceProvider extends DatabaseServiceProvider @@ -28,9 +28,7 @@ public function boot(): void $this->validateConfig(); - if (DB::connection()->isDoctrineAvailable()) { - $this->registerDoctrineTypes(); - } + $this->registerDoctrineTypes(); } /** @@ -45,18 +43,6 @@ private function registerDoctrineTypes(): void $this->registerDoctrineType(GeometryType::GEOMETRY_COLLECTION->getDoctrineClassName(), 'geomcollection'); } - /** - * @param class-string $class - * - * @throws Throwable - */ - private function registerDoctrineType(string $class, string $type): void - { - DB::registerDoctrineType($class, $type, $type); - - DB::connection()->registerDoctrineType($class, $type, $type); - } - /** * @throws LaravelSpatialException */ @@ -85,4 +71,24 @@ private function validateConfig(): void } } } + + private function isDoctrineAvailable(): bool + { + return class_exists('Doctrine\DBAL\Connection'); + } + + private function registerDoctrineType(Type|string $class, string $name): void + { + if (! $this->isDoctrineAvailable()) { + throw new RuntimeException( + 'Registering a custom Doctrine type requires Doctrine DBAL (doctrine/dbal).' + ); + } + + if (! Type::hasType($name)) { + /** @var Type $type */ + $type = is_string($class) ? new $class : $class; + Type::getTypeRegistry()->register($name, $type); + } + } }