Skip to content

Commit

Permalink
Improve casting (#39)
Browse files Browse the repository at this point in the history
* Run PHPInsights on CI

* Fix PHPStan

* Add `XDEBUG_MODE=coverage` to tests with coverage

* Improve casts

* Test `fromWkt`

* Add tests

* Fix PHPInsights

* Fix lint

* Remove `->fresh()` after model creation

* Rename tests

* Add update-chanelog action

* Remove `prefer-lowest`

* fix test

Co-authored-by: Matan Yadaev <[email protected]>
  • Loading branch information
MatanYadaev and Matan Yadaev authored Jul 8, 2022
1 parent ab2eff9 commit ffd5750
Show file tree
Hide file tree
Showing 19 changed files with 249 additions and 65 deletions.
6 changes: 3 additions & 3 deletions .github/workflows/phpinsights.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,6 @@ jobs:
- name: Install dependencies
run: composer install --prefer-dist --no-interaction

# Package is broken
# - name: Run PHPInsights
# run: ./vendor/bin/phpinsights --no-interaction --ansi --format=github-action
- name: Run PHPInsights
run: ./vendor/bin/phpinsights --no-interaction --ansi --format=github-action

3 changes: 2 additions & 1 deletion .github/workflows/phpunit.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ jobs:
matrix:
php: [8.1, 8.0]
laravel: [9.*, 8.*]
dependency-version: [prefer-lowest, prefer-stable]
# dependency-version: [prefer-lowest, prefer-stable]
dependency-version: [prefer-stable]
include:
- laravel: 8.*
testbench: ^6.23
Expand Down
28 changes: 28 additions & 0 deletions .github/workflows/update-changelog.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
name: Update Changelog

on:
release:
types: [released]

jobs:
update:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v2
with:
ref: master

- name: Update Changelog
uses: stefanzweifel/changelog-updater-action@v1
with:
latest-version: ${{ github.event.release.name }}
release-notes: ${{ github.event.release.body }}

- name: Commit updated CHANGELOG
uses: stefanzweifel/git-auto-commit-action@v4
with:
branch: master
commit_message: Update CHANGELOG
file_pattern: CHANGELOG.md
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
"php-cs-fixer": "./vendor/bin/php-cs-fixer fix --allow-risky=yes",
"phpstan": "./vendor/bin/phpstan analyse --memory-limit=2G",
"phpunit": "./vendor/bin/phpunit --colors=always",
"phpunit-coverage": "./vendor/bin/phpunit --coverage-html coverage",
"phpunit-coverage": "XDEBUG_MODE=coverage ./vendor/bin/phpunit --coverage-html coverage",
"phpinsights": "./vendor/bin/phpinsights",
"phpinsights-fix": "./vendor/bin/phpinsights fix"
},
Expand Down
1 change: 1 addition & 0 deletions phpinsights.php
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@
'exclude' => [
'src/Factory.php',
'src/Objects/GeometryCollection.php',
'src/GeometryCast.php',
],
],
],
Expand Down
30 changes: 23 additions & 7 deletions src/GeometryCast.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;
use InvalidArgumentException;
use MatanYadaev\EloquentSpatial\Objects\Geometry;

Expand All @@ -26,29 +27,35 @@ public function __construct(string $className)
/**
* @param Model $model
* @param string $key
* @param string|null $wkb
* @param string|Expression|null $wkbOrWKt
* @param array<string, mixed> $attributes
* @return Geometry|null
*/
public function get($model, string $key, $wkb, array $attributes): ?Geometry
public function get($model, string $key, $wkbOrWKt, array $attributes): ?Geometry
{
if (! $wkb) {
if (! $wkbOrWKt) {
return null;
}

return $this->className::fromWkb($wkb);
if ($wkbOrWKt instanceof Expression) {
$wkt = $this->extractWktFromExpression($wkbOrWKt);

return $this->className::fromWkt($wkt);
}

return $this->className::fromWkb($wkbOrWKt);
}

/**
* @param Model $model
* @param string $key
* @param Geometry|mixed|null $geometry
* @param array<string, mixed> $attributes
* @return Expression|string|null
* @return Expression|null
*
* @throws InvalidArgumentException
*/
public function set($model, string $key, $geometry, array $attributes): Expression|string|null
public function set($model, string $key, $geometry, array $attributes): Expression|null
{
if (! $geometry) {
return null;
Expand All @@ -61,6 +68,15 @@ public function set($model, string $key, $geometry, array $attributes): Expressi
);
}

return $geometry->toWkt();
$wkt = $geometry->toWkt(withFunction: true);

return DB::raw("ST_GeomFromText('{$wkt}')");
}

private function extractWktFromExpression(Expression $expression): string
{
preg_match('/ST_GeomFromText\(\'(.+)\'\)/', (string) $expression, $match);

return $match[1];
}
}
22 changes: 20 additions & 2 deletions src/Objects/Geometry.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Database\Query\Expression;
use InvalidArgumentException;
use JsonException;
use JsonSerializable;
Expand All @@ -17,7 +16,7 @@

abstract class Geometry implements Castable, Arrayable, Jsonable, JsonSerializable
{
abstract public function toWkt(): Expression;
abstract public function toWkt(bool $withFunction): string;

/**
* @param int $options
Expand Down Expand Up @@ -49,6 +48,25 @@ public static function fromWkb(string $wkb): static
return $geometry;
}

/**
* @param string $wkt
* @return static
*
* @throws InvalidArgumentException
*/
public static function fromWkt(string $wkt): static
{
$geometry = Factory::parse($wkt, false);

if (! ($geometry instanceof static)) {
throw new InvalidArgumentException(
sprintf('Expected %s, %s given.', static::class, $geometry::class)
);
}

return $geometry;
}

/**
* @param string $geoJson
* @return static
Expand Down
27 changes: 16 additions & 11 deletions src/Objects/GeometryCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
namespace MatanYadaev\EloquentSpatial\Objects;

use ArrayAccess;
use Illuminate\Database\Query\Expression;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
use InvalidArgumentException;

/**
* @template TGeometry of Geometry
*
* @implements ArrayAccess<int, TGeometry>
*/
class GeometryCollection extends Geometry implements ArrayAccess
Expand Down Expand Up @@ -42,9 +41,17 @@ public function __construct(Collection|array $geometries)
$this->validateGeometriesCount();
}

public function toWkt(): Expression
/**
* @param bool $withFunction
* @return string
*
* @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
*/
public function toWkt(bool $withFunction): string
{
return new Expression("GEOMETRYCOLLECTION({$this->toCollectionWkt()})");
$wkt = $this->toCollectionWkt(withFunction: true);

return "GEOMETRYCOLLECTION({$wkt})";
}

/**
Expand Down Expand Up @@ -145,7 +152,7 @@ protected function validateGeometriesCount(): void
*/
protected function validateGeometriesType(): void
{
$this->geometries->each(function (mixed $geometry, $a): void {
$this->geometries->each(function (mixed $geometry): void {
/** @var mixed $geometry */
if (! is_object($geometry) || ! ($geometry instanceof $this->collectionOf)) {
throw new InvalidArgumentException(
Expand All @@ -155,14 +162,12 @@ protected function validateGeometriesType(): void
});
}

protected function toCollectionWkt(): Expression
protected function toCollectionWkt(bool $withFunction): string
{
$wkt = $this->geometries
->map(static function (Geometry $geometry): string {
return (string) $geometry->toWkt();
return $this->geometries
->map(static function (Geometry $geometry) use ($withFunction): string {
return (string) $geometry->toWkt($withFunction);
})
->join(',');

return DB::raw($wkt);
}
}
13 changes: 8 additions & 5 deletions src/Objects/LineString.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,18 @@

namespace MatanYadaev\EloquentSpatial\Objects;

use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;

class LineString extends PointCollection
{
protected int $minimumGeometries = 2;

public function toWkt(): Expression
public function toWkt(bool $withFunction): string
{
return DB::raw("LINESTRING({$this->toCollectionWkt()})");
$wkt = $this->toCollectionWkt(withFunction: false);

if ($withFunction) {
return "LINESTRING(${wkt})";
}

return "(${wkt})";
}
}
16 changes: 11 additions & 5 deletions src/Objects/MultiLineString.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@

namespace MatanYadaev\EloquentSpatial\Objects;

use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;

/**
* @method array<LineString> getGeometries()
* @method LineString offsetGet(mixed $offset)
*
* @extends GeometryCollection<LineString>
*/
class MultiLineString extends GeometryCollection
Expand All @@ -18,8 +16,16 @@ class MultiLineString extends GeometryCollection

protected int $minimumGeometries = 1;

public function toWkt(): Expression
/**
* @param bool $withFunction
* @return string
*
* @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
*/
public function toWkt(bool $withFunction): string
{
return DB::raw("MULTILINESTRING({$this->toCollectionWkt()})");
$wkt = $this->toCollectionWkt(withFunction: false);

return "MULTILINESTRING({$wkt})";
}
}
15 changes: 10 additions & 5 deletions src/Objects/MultiPoint.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,20 @@

namespace MatanYadaev\EloquentSpatial\Objects;

use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;

class MultiPoint extends PointCollection
{
protected int $minimumGeometries = 1;

public function toWkt(): Expression
/**
* @param bool $withFunction
* @return string
*
* @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
*/
public function toWkt(bool $withFunction): string
{
return DB::raw("MULTIPOINT({$this->toCollectionWkt()})");
$wkt = $this->toCollectionWkt(withFunction: false);

return "MULTIPOINT({$wkt})";
}
}
16 changes: 11 additions & 5 deletions src/Objects/MultiPolygon.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@

namespace MatanYadaev\EloquentSpatial\Objects;

use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;

/**
* @method array<Polygon> getGeometries()
* @method Polygon offsetGet(mixed $offset)
*
* @extends GeometryCollection<Polygon>
*/
class MultiPolygon extends GeometryCollection
Expand All @@ -18,8 +16,16 @@ class MultiPolygon extends GeometryCollection

protected int $minimumGeometries = 1;

public function toWkt(): Expression
/**
* @param bool $withFunction
* @return string
*
* @phpcsSuppress SlevomatCodingStandard.Functions.UnusedParameter
*/
public function toWkt(bool $withFunction): string
{
return DB::raw("MULTIPOLYGON({$this->toCollectionWkt()})");
$wkt = $this->toCollectionWkt(withFunction: false);

return "MULTIPOLYGON({$wkt})";
}
}
13 changes: 8 additions & 5 deletions src/Objects/Point.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,6 @@

namespace MatanYadaev\EloquentSpatial\Objects;

use Illuminate\Database\Query\Expression;
use Illuminate\Support\Facades\DB;

class Point extends Geometry
{
public float $latitude;
Expand All @@ -19,9 +16,15 @@ public function __construct(float $latitude, float $longitude)
$this->longitude = $longitude;
}

public function toWkt(): Expression
public function toWkt(bool $withFunction): string
{
return DB::raw("POINT({$this->longitude}, {$this->latitude})");
$wkt = "{$this->longitude} {$this->latitude}";

if ($withFunction) {
return "POINT({$wkt})";
}

return $wkt;
}

/**
Expand Down
1 change: 1 addition & 0 deletions src/Objects/PointCollection.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
/**
* @method array<Point> getGeometries()
* @method Point offsetGet(mixed $offset)
*
* @extends GeometryCollection<Point>
*/
abstract class PointCollection extends GeometryCollection
Expand Down
Loading

0 comments on commit ffd5750

Please sign in to comment.