Skip to content

Commit d52c020

Browse files
committed
Initial commit
0 parents  commit d52c020

32 files changed

+1575
-0
lines changed

.gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.idea/
2+
vendor/
3+
composer.lock
4+
db/

Dockerfile

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
FROM php:7.0-cli
2+
3+
RUN pecl install xdebug-2.5.1 \
4+
&& docker-php-ext-install pdo_mysql \
5+
&& docker-php-ext-enable xdebug pdo_mysql

LICENSE

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
MIT License
2+
3+
Original work Copyright (c) 2015 Peter Haza
4+
Modified work Copyright (c) 2017 Joseph Estefane
5+
6+
Permission is hereby granted, free of charge, to any person obtaining a copy
7+
of this software and associated documentation files (the "Software"), to deal
8+
in the Software without restriction, including without limitation the rights
9+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
copies of the Software, and to permit persons to whom the Software is
11+
furnished to do so, subject to the following conditions:
12+
13+
The above copyright notice and this permission notice shall be included in all
14+
copies or substantial portions of the Software.
15+
16+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22+
SOFTWARE.

README.md

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Laravel MySQL Spatial extension
2+
3+
Heavily inspired from the [Laravel postgis extension](https://github.com/njbarrett/laravel-postgis) package.

composer.json

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
{
2+
"name": "grimzy/laravel-mysql-spatial",
3+
"description": "MySQL spatial data types extension for Laravel.",
4+
"type": "library",
5+
"license": "MIT",
6+
"authors": [
7+
{
8+
"name": "Joseph Estefane",
9+
"email": "[email protected]"
10+
}
11+
],
12+
"require": {
13+
"php": ">=5.5",
14+
"illuminate/database": "^5.2",
15+
"geo-io/wkb-parser": "^1.0",
16+
"jmikola/geojson": "^1.0"
17+
},
18+
"require-dev": {
19+
"phpunit/phpunit": "^5.7",
20+
"laravel/laravel": "^5.2"
21+
},
22+
"autoload": {
23+
"psr-4": {
24+
"Grimzy\\LaravelSpatial\\": "src/"
25+
}
26+
},
27+
"autoload-dev" : {
28+
"psr-4": {
29+
"Grimzy\\LaravelSpatial\\Tests\\" : "tests/"
30+
}
31+
},
32+
"extra": {
33+
"branch-alias": {
34+
"dev-master": "1.0.x-dev"
35+
}
36+
}
37+
}

phpunit.xml.dist

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<phpunit backupGlobals="false"
3+
backupStaticAttributes="false"
4+
bootstrap="./vendor/autoload.php"
5+
colors="true"
6+
convertErrorsToExceptions="true"
7+
convertNoticesToExceptions="true"
8+
convertWarningsToExceptions="true"
9+
processIsolation="false"
10+
stopOnFailure="false">
11+
<testsuites>
12+
<testsuite name="Feature Tests">
13+
<directory suffix="Test.php">./tests</directory>
14+
</testsuite>
15+
</testsuites>
16+
<php>
17+
<env name="APP_ENV" value="testing"/>
18+
<env name="APP_DEBUG" value="true"/>
19+
<env name="APP_KEY" value="V4EYYl0MjI4Bin9GkFPUE3cpAARPCF27"/>
20+
<env name="CACHE_DRIVER" value="array"/>
21+
<env name="SESSION_DRIVER" value="array"/>
22+
<env name="QUEUE_DRIVER" value="sync"/>
23+
</php>
24+
</phpunit>

src/Connectors/ConnectionFactory.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial\Connectors;
3+
4+
use Grimzy\LaravelSpatial\MysqlConnection;
5+
use PDO;
6+
7+
class ConnectionFactory extends \Illuminate\Database\Connectors\ConnectionFactory
8+
{
9+
/**
10+
* @param string $driver
11+
* @param \Closure|PDO $connection
12+
* @param string $database
13+
* @param string $prefix
14+
* @param array $config
15+
*
16+
* @return MysqlConnection
17+
*/
18+
protected function createConnection($driver, $connection, $database, $prefix = '', array $config = [])
19+
{
20+
if ($this->container->bound($key = "db.connection.{$driver}")) {
21+
return $this->container->make($key, [$connection, $database, $prefix, $config]);
22+
}
23+
24+
if ($driver === 'mysql') {
25+
return new MysqlConnection($connection, $database, $prefix, $config);
26+
}
27+
28+
return parent::createConnection($driver, $connection, $database, $prefix, $config);
29+
}
30+
}

src/Eloquent/Builder.php

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial\Eloquent;
3+
4+
use Grimzy\LaravelSpatial\Types\GeometryInterface;
5+
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
6+
7+
class Builder extends EloquentBuilder
8+
{
9+
public function update(array $values)
10+
{
11+
foreach ($values as $key => &$value) {
12+
if ($value instanceof GeometryInterface) {
13+
$value = $this->asWKT($value);
14+
}
15+
}
16+
17+
return parent::update($values);
18+
}
19+
20+
// protected function getSpatialFields()
21+
// {
22+
// return $this->getModel()->getSpatialFields();
23+
// }
24+
25+
26+
protected function asWKT(GeometryInterface $geometry)
27+
{
28+
return $this->getQuery()->raw("ST_GeomFromText('" . $geometry->toWKT() . "')");
29+
}
30+
}

src/Eloquent/SpatialTrait.php

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial\Eloquent;
3+
4+
use Grimzy\LaravelSpatial\Exceptions\SpatialFieldsNotDefinedException;
5+
use Grimzy\LaravelSpatial\Types\Geometry;
6+
use Grimzy\LaravelSpatial\Types\GeometryInterface;
7+
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
8+
9+
trait SpatialTrait
10+
{
11+
/*
12+
* The attributes that are spatial representations.
13+
* To use this Trait, add the following array to the model class
14+
*
15+
* @var array
16+
*
17+
* protected $spatialFields = [];
18+
*/
19+
20+
public $geometries = [];
21+
22+
/**
23+
* Create a new Eloquent query builder for the model.
24+
*
25+
* @param \Illuminate\Database\Query\Builder $query
26+
*
27+
* @return \Grimzy\LaravelSpatial\Eloquent\Builder
28+
*/
29+
public function newEloquentBuilder($query)
30+
{
31+
return new Builder($query);
32+
}
33+
34+
protected function performInsert(EloquentBuilder $query, array $options = [])
35+
{
36+
foreach ($this->attributes as $key => $value) {
37+
if ($value instanceof GeometryInterface) {
38+
$this->geometries[$key] = $value; //Preserve the geometry objects prior to the insert
39+
$this->attributes[$key] = $this->getConnection()->raw(sprintf("ST_GeomFromText('%s')", $value->toWKT()));
40+
}
41+
}
42+
43+
$insert = parent::performInsert($query, $options);
44+
45+
foreach ($this->geometries as $key => $value) {
46+
$this->attributes[$key] = $value; //Retrieve the geometry objects so they can be used in the model
47+
}
48+
49+
return $insert; //Return the result of the parent insert
50+
}
51+
52+
public function setRawAttributes(array $attributes, $sync = false)
53+
{
54+
$spatial_fields = $this->getSpatialFields();
55+
56+
foreach ($attributes as $attribute => &$value) {
57+
if (in_array($attribute, $spatial_fields) && is_string($value) && strlen($value) >= 15) {
58+
$value = Geometry::fromWKB($value);
59+
}
60+
}
61+
62+
parent::setRawAttributes($attributes, $sync);
63+
}
64+
65+
public function getSpatialFields()
66+
{
67+
if (property_exists($this, 'spatialFields')) {
68+
return $this->spatialFields;
69+
} else {
70+
throw new SpatialFieldsNotDefinedException(__CLASS__ . ' has to define $spatialFields');
71+
}
72+
73+
}
74+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial\Exceptions;
3+
4+
class SpatialFieldsNotDefinedException extends \RuntimeException
5+
{
6+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial\Exceptions;
3+
4+
class UnknownWKTTypeException extends \RuntimeException
5+
{
6+
}

src/MysqlConnection.php

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial;
3+
4+
class MysqlConnection extends \Illuminate\Database\MysqlConnection
5+
{
6+
// public function __construct($pdo, $database = '', $tablePrefix = '', array $config = [])
7+
// {
8+
// parent::__construct($pdo, $database, $tablePrefix, $config);
9+
//
10+
// // Prevent geography type fields from throwing a 'type not found' error.
11+
// $this->getDoctrineSchemaManager()->getDatabasePlatform()->registerDoctrineTypeMapping('geography', 'string');
12+
// }
13+
14+
/**
15+
* Get the default schema grammar instance.
16+
*
17+
* @return \Illuminate\Database\Grammar
18+
*/
19+
protected function getDefaultSchemaGrammar()
20+
{
21+
return $this->withTablePrefix(new Schema\Grammars\MySqlGrammar());
22+
}
23+
24+
25+
public function getSchemaBuilder()
26+
{
27+
if (is_null($this->schemaGrammar)) {
28+
$this->useDefaultSchemaGrammar();
29+
}
30+
31+
return new Schema\Builder($this);
32+
}
33+
}

src/Schema/Blueprint.php

+93
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
namespace Grimzy\LaravelSpatial\Schema;
3+
4+
class Blueprint extends \Illuminate\Database\Schema\Blueprint
5+
{
6+
/**
7+
* Add a geometry column on the table
8+
*
9+
* @param string $column
10+
* @return \Illuminate\Support\Fluent
11+
*/
12+
public function geometry($column)
13+
{
14+
return $this->addColumn('geometry', $column);
15+
}
16+
17+
/**
18+
* Add a point column on the table
19+
*
20+
* @param $column
21+
* @return \Illuminate\Support\Fluent
22+
*/
23+
public function point($column)
24+
{
25+
return $this->addColumn('point', $column);
26+
}
27+
28+
/**
29+
* Add a linestring column on the table
30+
*
31+
* @param $column
32+
* @return \Illuminate\Support\Fluent
33+
*/
34+
public function linestring($column)
35+
{
36+
return $this->addColumn('linestring', $column);
37+
}
38+
39+
/**
40+
* Add a polygon column on the table
41+
*
42+
* @param $column
43+
* @return \Illuminate\Support\Fluent
44+
*/
45+
public function polygon($column)
46+
{
47+
return $this->addColumn('polygon', $column);
48+
}
49+
50+
/**
51+
* Add a multipoint column on the table
52+
*
53+
* @param $column
54+
* @return \Illuminate\Support\Fluent
55+
*/
56+
public function multipoint($column)
57+
{
58+
return $this->addColumn('multipoint', $column);
59+
}
60+
61+
/**
62+
* Add a multilinestring column on the table
63+
*
64+
* @param $column
65+
* @return \Illuminate\Support\Fluent
66+
*/
67+
public function multilinestring($column)
68+
{
69+
return $this->addColumn('multilinestring', $column);
70+
}
71+
72+
/**
73+
* Add a multipolygon column on the table
74+
*
75+
* @param $column
76+
* @return \Illuminate\Support\Fluent
77+
*/
78+
public function multipolygon($column)
79+
{
80+
return $this->addColumn('multipolygon', $column);
81+
}
82+
83+
/**
84+
* Add a geometrycollection column on the table
85+
*
86+
* @param $column
87+
* @return \Illuminate\Support\Fluent
88+
*/
89+
public function geometrycollection($column)
90+
{
91+
return $this->addColumn('geometrycollection', $column);
92+
}
93+
}

0 commit comments

Comments
 (0)