Skip to content

Commit c998cc0

Browse files
MatanYadaevMatan Yadaev
andauthored
Add Doctrine types (#65)
* Move DB config to phpunit.xml * Add test * Implementation * Ignore PhpStan error * add geometrycollection type * dont register if doctrine isn't available * Formatting Co-authored-by: Matan Yadaev <[email protected]>
1 parent e511d64 commit c998cc0

13 files changed

+279
-11
lines changed

composer.json

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"phayes/geophp": "^1.2"
1818
},
1919
"require-dev": {
20+
"doctrine/dbal": "^3.4",
2021
"friendsofphp/php-cs-fixer": "^3.0",
2122
"jubeki/laravel-code-style": "^1.0",
2223
"nunomaduro/larastan": "^1.0|^2.0",
@@ -48,5 +49,12 @@
4849
}
4950
},
5051
"minimum-stability": "dev",
51-
"prefer-stable": true
52+
"prefer-stable": true,
53+
"extra": {
54+
"laravel": {
55+
"providers": [
56+
"MatanYadaev\\EloquentSpatial\\EloquentSpatialServiceProvider"
57+
]
58+
}
59+
}
5260
}

phpstan.neon

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ parameters:
1212
-
1313
message: '#^Access to an undefined property Pest\\Expectation\|Pest\\Support\\Extendable\:\:\$.+\.$#'
1414
path: tests/*.php
15+
-
16+
message: '#^Call to an undefined method Pest\\Expectation\:\:.+\(\)\.$#'
17+
path: tests/*.php
1518
excludePaths:
1619
- ./src/Factory.php
1720
checkMissingIterableValueType: true

phpunit.xml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,4 +28,8 @@
2828
<logging>
2929
<junit outputFile="build/report.junit.xml"/>
3030
</logging>
31+
<php>
32+
<env name="DB_DATABASE" value="laravel_eloquent_spatial_test"/>
33+
<env name="DB_USERNAME" value="root"/>
34+
</php>
3135
</phpunit>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class GeometryCollectionType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'geometrycollection';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'geometrycollection';
22+
}
23+
}

src/Doctrine/LineStringType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class LineStringType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'linestring';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'linestring';
22+
}
23+
}

src/Doctrine/MultiLineStringType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class MultiLineStringType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'multilinestring';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'multilinestring';
22+
}
23+
}

src/Doctrine/MultiPointType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class MultiPointType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'multipoint';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'multipoint';
22+
}
23+
}

src/Doctrine/MultiPolygonType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class MultiPolygonType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'multipolygon';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'multipolygon';
22+
}
23+
}

src/Doctrine/PointType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class PointType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'point';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'point';
22+
}
23+
}

src/Doctrine/PolygonType.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial\Doctrine;
6+
7+
use Doctrine\DBAL\Platforms\AbstractPlatform;
8+
use Doctrine\DBAL\Types\Type;
9+
10+
class PolygonType extends Type
11+
{
12+
public function getSQLDeclaration(array $column, AbstractPlatform $platform): string
13+
{
14+
// @codeCoverageIgnoreStart
15+
return 'polygon';
16+
// @codeCoverageIgnoreEnd
17+
}
18+
19+
public function getName(): string
20+
{
21+
return 'polygon';
22+
}
23+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MatanYadaev\EloquentSpatial;
6+
7+
use Illuminate\Database\Connection;
8+
use Illuminate\Database\DatabaseServiceProvider;
9+
use Illuminate\Support\Facades\DB;
10+
use MatanYadaev\EloquentSpatial\Doctrine\GeometryCollectionType;
11+
use MatanYadaev\EloquentSpatial\Doctrine\LineStringType;
12+
use MatanYadaev\EloquentSpatial\Doctrine\MultiLineStringType;
13+
use MatanYadaev\EloquentSpatial\Doctrine\MultiPointType;
14+
use MatanYadaev\EloquentSpatial\Doctrine\MultiPolygonType;
15+
use MatanYadaev\EloquentSpatial\Doctrine\PointType;
16+
use MatanYadaev\EloquentSpatial\Doctrine\PolygonType;
17+
18+
class EloquentSpatialServiceProvider extends DatabaseServiceProvider
19+
{
20+
public function boot(): void
21+
{
22+
/** @var Connection $connection */
23+
$connection = DB::connection();
24+
25+
if ($connection->isDoctrineAvailable()) {
26+
$this->registerDoctrineTypes($connection);
27+
}
28+
}
29+
30+
protected function registerDoctrineTypes(Connection $connection): void
31+
{
32+
$geometries = [
33+
'point' => PointType::class,
34+
'linestring' => LineStringType::class,
35+
'multipoint' => MultiPointType::class,
36+
'polygon' => PolygonType::class,
37+
'multilinestring' => MultiLineStringType::class,
38+
'multipolygon' => MultiPolygonType::class,
39+
'geometrycollection' => GeometryCollectionType::class,
40+
'geomcollection' => GeometryCollectionType::class,
41+
];
42+
43+
foreach ($geometries as $type => $class) {
44+
DB::registerDoctrineType($class, $type, $type);
45+
$connection->registerDoctrineType($class, $type, $type);
46+
}
47+
}
48+
}

tests/DoctrineTypesTest.php

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?php
2+
3+
use Illuminate\Support\Facades\DB;
4+
use MatanYadaev\EloquentSpatial\Doctrine\GeometryCollectionType;
5+
use MatanYadaev\EloquentSpatial\Doctrine\LineStringType;
6+
use MatanYadaev\EloquentSpatial\Doctrine\MultiLineStringType;
7+
use MatanYadaev\EloquentSpatial\Doctrine\MultiPointType;
8+
use MatanYadaev\EloquentSpatial\Doctrine\MultiPolygonType;
9+
use MatanYadaev\EloquentSpatial\Doctrine\PointType;
10+
use MatanYadaev\EloquentSpatial\Doctrine\PolygonType;
11+
12+
it('uses custom Doctrine types for spatial columns', function (): void {
13+
$doctrineSchemaManager = DB::connection()->getDoctrineSchemaManager();
14+
15+
$columns = $doctrineSchemaManager->listTableColumns('test_places');
16+
17+
expect($columns['point']->getType())
18+
->toBeInstanceOf(PointType::class)
19+
->getName()->toBe('point');
20+
21+
expect($columns['line_string']->getType())
22+
->toBeInstanceOf(LineStringType::class)
23+
->getName()->toBe('linestring');
24+
25+
expect($columns['multi_point']->getType())
26+
->toBeInstanceOf(MultiPointType::class)
27+
->getName()->toBe('multipoint');
28+
29+
expect($columns['polygon']->getType())
30+
->toBeInstanceOf(PolygonType::class)
31+
->getName()->toBe('polygon');
32+
33+
expect($columns['multi_line_string']->getType())
34+
->toBeInstanceOf(MultiLineStringType::class)
35+
->getName()->toBe('multilinestring');
36+
37+
expect($columns['multi_polygon']->getType())
38+
->toBeInstanceOf(MultiPolygonType::class)
39+
->getName()->toBe('multipolygon');
40+
41+
expect($columns['geometry_collection']->getType())
42+
->toBeInstanceOf(GeometryCollectionType::class)
43+
->getName()->toBe('geometrycollection');
44+
});

tests/TestCase.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,8 @@
22

33
namespace MatanYadaev\EloquentSpatial\Tests;
44

5-
use Illuminate\Support\Facades\Config;
5+
use Illuminate\Support\ServiceProvider;
6+
use MatanYadaev\EloquentSpatial\EloquentSpatialServiceProvider;
67
use Orchestra\Testbench\TestCase as Orchestra;
78

89
class TestCase extends Orchestra
@@ -14,15 +15,14 @@ protected function setUp(): void
1415
$this->loadMigrationsFrom(__DIR__.'/database/migrations');
1516
}
1617

17-
public function getEnvironmentSetUp($app): void
18+
/**
19+
* @param $app
20+
* @return class-string<ServiceProvider>[]
21+
*/
22+
protected function getPackageProviders($app): array
1823
{
19-
Config::set('database.default', 'mysql');
20-
Config::set('database.connections.mysql', [
21-
'driver' => 'mysql',
22-
'host' => '127.0.0.1',
23-
'port' => env('DB_PORT', 3306),
24-
'database' => 'laravel_eloquent_spatial_test',
25-
'username' => 'root',
26-
]);
24+
return [
25+
EloquentSpatialServiceProvider::class,
26+
];
2727
}
2828
}

0 commit comments

Comments
 (0)