• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

longitude-one / doctrine-spatial / 16351073931

17 Jul 2025 04:50PM UTC coverage: 95.775% (+0.2%) from 95.599%
16351073931

push

github

Alexandre-T
Fix/issue 123 and upgrade quality tools (#132)

* Add platform specification for PostGIS and MySQL services in docker-compose.yaml
* Fix README to use correct container name for PHP 8.3
* Fix installation commands in README to use 'composer install' instead of 'composer update'
* Update dependencies for PHP Code Sniffer, PHP CS Fixer, PHP Mess Detector, and PHPStan

- PHP Code Sniffer updated from version 3.11.2 to 3.13.2
- PHP CS Fixer updated from version v3.68.1 to v3.84.0
- PHP Mess Detector updated Symfony components to versions 6.4.22 and 6.4.23
- PHPStan updated from version 1.12.15 to 1.12.27 and phpstan-symfony from 1.4.13 to 1.4.15
- Various Symfony components updated to their latest versions, including deprecation contracts and polyfills
* Order of a few methods have changed because of phpcsfixer upgrades

1428 of 1491 relevant lines covered (95.77%)

35.01 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

79.07
/lib/LongitudeOne/Spatial/DBAL/Platform/AbstractPlatform.php
1
<?php
2
/**
3
 * This file is part of the doctrine spatial extension.
4
 *
5
 * PHP 8.1 | 8.2 | 8.3
6
 * Doctrine ORM 2.19 | 3.1
7
 *
8
 * Copyright Alexandre Tranchant <alexandre.tranchant@gmail.com> 2017-2025
9
 * Copyright Longitude One 2020-2025
10
 * Copyright 2015 Derek J. Lambert
11
 *
12
 * For the full copyright and license information, please view the LICENSE
13
 * file that was distributed with this source code.
14
 *
15
 */
16

17
declare(strict_types=1);
18

19
namespace LongitudeOne\Spatial\DBAL\Platform;
20

21
use LongitudeOne\Geo\WKB\Exception\ExceptionInterface;
22
use LongitudeOne\Geo\WKB\Parser as BinaryParser;
23
use LongitudeOne\Geo\WKT\Parser as StringParser;
24
use LongitudeOne\Spatial\DBAL\Types\AbstractSpatialType;
25
use LongitudeOne\Spatial\DBAL\Types\DoctrineSpatialTypeInterface;
26
use LongitudeOne\Spatial\DBAL\Types\GeographyType;
27
use LongitudeOne\Spatial\Exception\InvalidValueException;
28
use LongitudeOne\Spatial\Exception\MissingArgumentException;
29
use LongitudeOne\Spatial\Exception\UnsupportedTypeException;
30
use LongitudeOne\Spatial\PHP\Types\PointInterface;
31
use LongitudeOne\Spatial\PHP\Types\SpatialInterface;
32

33
/**
34
 * Abstract spatial platform.
35
 *
36
 * @author  Derek J. Lambert <dlambert@dereklambert.com>
37
 * @author  Alexandre Tranchant <alexandre-tranchant@gmail.com>
38
 * @license https://dlambert.mit-license.org MIT
39
 */
40
abstract class AbstractPlatform implements PlatformInterface
41
{
42
    /**
43
     * Check both arguments and return srid when possible.
44
     *
45
     * @param array<string, mixed> $column array MAY contain 'srid' key
46
     * @param ?int                 $srid   srid MAY be provided
47
     *
48
     * @throws InvalidValueException when SRID is not null nor an integer
49
     */
50
    protected static function checkSrid(array $column, ?int $srid): ?int
10✔
51
    {
52
        $srid ??= $column['srid'] ?? null;
10✔
53

54
        if (null !== $srid && !is_int($srid)) {
10✔
55
            $message = sprintf(
1✔
56
                'SRID SHALL be an integer, but a %s is provided',
1✔
57
                gettype($srid)
1✔
58
            );
1✔
59

60
            throw new InvalidValueException($message);
1✔
61
        }
62

63
        return $srid;
10✔
64
    }
65

66
    /**
67
     * Check both argument and return AbstractSpatialType when possible.
68
     *
69
     * @param array<string, mixed> $column array SHOULD contain 'type' key
70
     * @param ?AbstractSpatialType $type   type is now provided
71
     *
72
     * @throws MissingArgumentException when $column doesn't contain 'type' and AbstractSpatialType is null
73
     */
74
    protected static function checkType(array $column, ?AbstractSpatialType $type): AbstractSpatialType
21✔
75
    {
76
        $type ??= $column['type'] ?? null;
21✔
77

78
        if (!$type instanceof AbstractSpatialType) {
21✔
79
            throw new MissingArgumentException('Arguments aren\'t well defined. Please provide a type.');
1✔
80
        }
81

82
        return $type;
21✔
83
    }
84

85
    /**
86
     * Convert binary data to a php value.
87
     *
88
     * @param DoctrineSpatialTypeInterface $type    The abstract spatial type
89
     * @param resource|string              $sqlExpr the SQL expression
90
     *
91
     * @throws ExceptionInterface|InvalidValueException when the provided type is not supported
92
     */
93
    public function convertBinaryToPhpValue(DoctrineSpatialTypeInterface $type, $sqlExpr): SpatialInterface
138✔
94
    {
95
        if (is_resource($sqlExpr)) {
138✔
96
            $sqlExpr = stream_get_contents($sqlExpr);
98✔
97
        }
98

99
        if (false === $sqlExpr) {
138✔
100
            throw new InvalidValueException('Invalid resource value.');
×
101
        }
102

103
        $parser = new BinaryParser($sqlExpr);
138✔
104

105
        return $this->newObjectFromValue($type, $parser->parse());
138✔
106
    }
107

108
    /**
109
     * Convert string data to a php value.
110
     *
111
     * @param AbstractSpatialType $type    The abstract spatial type
112
     * @param string              $sqlExpr the SQL expression
113
     *
114
     * @throws InvalidValueException    when this extension does not support the provided type
115
     * @throws UnsupportedTypeException when the provided type is not supported by the current platform
116
     */
117
    public function convertStringToPhpValue(AbstractSpatialType $type, $sqlExpr): SpatialInterface
8✔
118
    {
119
        $parser = new StringParser($sqlExpr);
8✔
120

121
        return $this->newObjectFromValue($type, $parser->parse());
8✔
122
    }
123

124
    /**
125
     * Get an array of database types that map to this Doctrine type.
126
     *
127
     * @param AbstractSpatialType $type the spatial type
128
     *
129
     * @return string[]
130
     *
131
     * @throws UnsupportedTypeException when the provided type is not supported
132
     */
133
    public function getMappedDatabaseTypes(AbstractSpatialType $type): array
×
134
    {
135
        if (!$type->supportsPlatform($this)) {
×
136
            throw new UnsupportedTypeException(sprintf('Platform %s does not currently supported the type %s.', $this::class, $type::class));
×
137
        }
138

139
        $sqlType = mb_strtolower($type->getSQLType());
×
140

141
        if ($type instanceof GeographyType && 'geography' !== $sqlType) {
×
142
            $sqlType = sprintf('geography(%s)', $sqlType);
×
143
        }
144

145
        return [$sqlType];
×
146
    }
147

148
    /**
149
     * Create a spatial object from parsed value.
150
     *
151
     * @param DoctrineSpatialTypeInterface                  $type  The type spatial type
152
     * @param array{type: string, srid?: ?int, value:mixed} $value The value of the spatial object
153
     *
154
     * @throws InvalidValueException when the provided type is not supported
155
     */
156
    private function newObjectFromValue(DoctrineSpatialTypeInterface $type, array $value): SpatialInterface
146✔
157
    {
158
        $typeFamily = $type->getTypeFamily();
146✔
159
        $typeName = mb_strtoupper($value['type']);
146✔
160

161
        $constName = sprintf('%s::%s', SpatialInterface::class, $typeName);
146✔
162

163
        if (!defined($constName)) {
146✔
164
            throw new InvalidValueException(sprintf('Unsupported %s type "%s".', $typeFamily, $typeName));
×
165
        }
166

167
        /** @var string $constValue */
168
        $constValue = constant($constName);
146✔
169

170
        /** @var class-string<SpatialInterface> $class */
171
        $class = sprintf('LongitudeOne\Spatial\PHP\Types\%s\%s', $typeFamily, $constValue);
146✔
172

173
        if (is_a($class, PointInterface::class, true)) {
146✔
174
            if (is_array($value['value']) && isset($value['value'][0], $value['value'][1])) {
43✔
175
                return new $class($value['value'][0], $value['value'][1], $value['srid'] ?? null);
43✔
176
            }
177
        }
178

179
        return new $class($value['value'], $value['srid'] ?? null);
107✔
180
    }
181
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc