• 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

82.35
/lib/LongitudeOne/Spatial/DBAL/Types/AbstractSpatialType.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\Types;
20

21
use Doctrine\DBAL\Platforms\AbstractPlatform;
22
use Doctrine\DBAL\Platforms\MariaDBPlatform;
23
use Doctrine\DBAL\Platforms\MySQLPlatform;
24
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
25
use Doctrine\DBAL\Types\Exception\TypeNotRegistered;
26
use Doctrine\DBAL\Types\Type;
27
use LongitudeOne\Spatial\DBAL\Platform\MariaDB;
28
use LongitudeOne\Spatial\DBAL\Platform\MySql;
29
use LongitudeOne\Spatial\DBAL\Platform\PlatformInterface;
30
use LongitudeOne\Spatial\DBAL\Platform\PostgreSql;
31
use LongitudeOne\Spatial\Exception\InvalidValueException;
32
use LongitudeOne\Spatial\Exception\UnsupportedPlatformException;
33
use LongitudeOne\Spatial\PHP\Types\SpatialInterface;
34

35
/**
36
 * Abstract Doctrine GEOMETRY type.
37
 *
38
 * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
39
 */
40
abstract class AbstractSpatialType extends Type implements DoctrineSpatialTypeInterface
41
{
42
    // phpcs:disable Generic.NamingConventions.CamelCapsFunctionName.ScopeNotCamelCaps
43

44
    /**
45
     * Does working with this column require SQL conversion functions?
46
     *
47
     * This is a metadata function required, for example, in the ORM.
48
     * Usage of {@link convertToDatabaseValueSql} and
49
     * {@link convertToPhpValueSql} works for any type and mostly
50
     * does nothing. This method can additionally be used for optimization.
51
     *
52
     * Spatial types require conversion.
53
     *
54
     * @return bool
55
     */
56
    public function canRequireSQLConversion()
×
57
    {
58
        return true;
×
59
    }
60

61
    // phpcs:enable
62

63
    /**
64
     * Converts a value from its PHP representation to its database representation of this type.
65
     *
66
     * @param mixed            $value    the value to convert
67
     * @param AbstractPlatform $platform the database platform
68
     *
69
     * @throws InvalidValueException        when value is not an instance of Geometry Interface
70
     * @throws UnsupportedPlatformException when platform is unsupported
71
     */
72
    public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
209✔
73
    {
74
        if (null === $value) {
209✔
75
            return null;
8✔
76
        }
77

78
        if (!$value instanceof SpatialInterface) {
201✔
79
            throw new InvalidValueException('Spatial column values must implement SpatialInterface');
1✔
80
        }
81

82
        return $this->getSpatialPlatform($platform)->convertToDatabaseValue($this, $value);
200✔
83
    }
84

85
    /**
86
     * Modifies the SQL expression (identifier, parameter) to convert to a database value.
87
     *
88
     * @param string           $sqlExpr  the SQL expression
89
     * @param AbstractPlatform $platform the database platform
90
     *
91
     * @throws UnsupportedPlatformException when platform is unsupported
92
     */
93
    public function convertToDatabaseValueSql($sqlExpr, AbstractPlatform $platform): string
209✔
94
    {
95
        return $this->getSpatialPlatform($platform)->convertToDatabaseValueSql($this, $sqlExpr);
209✔
96
    }
97

98
    // phpcs:disable Generic.NamingConventions.CamelCapsFunctionName.ScopeNotCamelCaps
99

100
    /**
101
     * Converts a value from its database representation to its PHP representation of this type.
102
     *
103
     * @param null|resource|string $value    value to convert to PHP
104
     * @param AbstractPlatform     $platform platform database
105
     *
106
     * @throws UnsupportedPlatformException when platform is unsupported
107
     */
108
    public function convertToPHPValue($value, AbstractPlatform $platform): ?SpatialInterface
147✔
109
    {
110
        if (null === $value) {
147✔
111
            return null;
1✔
112
        }
113

114
        if (!is_resource($value) && ctype_alpha($value[0])) {
146✔
115
            return $this->getSpatialPlatform($platform)->convertStringToPhpValue($this, $value);
8✔
116
        }
117

118
        return $this->getSpatialPlatform($platform)->convertBinaryToPhpValue($this, $value);
138✔
119
    }
120

121
    // phpcs:enable
122

123
    /**
124
     * Modifies the SQL expression (identifier, parameter) to convert to a PHP value.
125
     *
126
     * @param string           $sqlExpr  SQL expression
127
     * @param AbstractPlatform $platform platform database
128
     *
129
     * @throws UnsupportedPlatformException when platform is unsupported
130
     */
131
    public function convertToPhpValueSql($sqlExpr, $platform): string
148✔
132
    {
133
        return $this->getSpatialPlatform($platform)->convertToPhpValueSql($this, $sqlExpr);
148✔
134
    }
135

136
    /**
137
     * Get an array of database types that map to this Doctrine type.
138
     *
139
     * @param AbstractPlatform $platform platform database
140
     *
141
     * @throws UnsupportedPlatformException when platform is unsupported
142
     */
143
    public function getMappedDatabaseTypes(AbstractPlatform $platform): array
1✔
144
    {
145
        return $this->getSpatialPlatform($platform)->getMappedDatabaseTypes($this);
1✔
146
    }
147

148
    /**
149
     * Gets the name of this type.
150
     *
151
     * @return class-string<DoctrineSpatialTypeInterface>
152
     *
153
     * @throws TypeNotRegistered When type is not registered in the map
154
     */
155
    public function getName()
8✔
156
    {
157
        /** @var class-string<DoctrineSpatialTypeInterface>|false $className */
158
        $className = array_search($this::class, self::getTypesMap(), true);
8✔
159

160
        if (false === $className) {
8✔
161
            throw new TypeNotRegistered(sprintf('Type "%s" is not currently registered.', $this::class));
×
162
        }
163

164
        return $className;
8✔
165
    }
166

167
    /**
168
     * Gets the SQL declaration snippet for a field of this type.
169
     *
170
     * @param array<string,mixed> $column   the field declaration
171
     * @param AbstractPlatform    $platform database platform
172
     *
173
     * @throws UnsupportedPlatformException when platform is unsupported
174
     */
175
    public function getSqlDeclaration(array $column, AbstractPlatform $platform): string
21✔
176
    {
177
        if (!key_exists('srid', $column) || !is_int($column['srid']) || $column['srid'] < 0) {
21✔
178
            $column['srid'] = null;
20✔
179
        }
180

181
        return $this->getSpatialPlatform($platform)->getSqlDeclaration($column, $this, $column['srid'] ?? null);
21✔
182
    }
183

184
    // phpcs:disable Generic.NamingConventions.CamelCapsFunctionName.ScopeNotCamelCaps
185

186
    /**
187
     * Gets the SQL name of this type.
188
     *
189
     * @return string
190
     */
191
    public function getSQLType()
27✔
192
    {
193
        $class = get_class($this);
27✔
194
        $start = mb_strrpos($class, '\\') + 1;
27✔
195
        $len = mb_strlen($class) - $start - 4;
27✔
196

197
        return mb_substr($class, mb_strrpos($class, '\\') + 1, $len);
27✔
198
    }
199

200
    // phpcs:enable
201

202
    /**
203
     * @return (SpatialInterface::GEOGRAPHY|SpatialInterface::GEOMETRY)
204
     */
205
    public function getTypeFamily(): string
151✔
206
    {
207
        return $this instanceof GeographyType ? SpatialInterface::GEOGRAPHY : SpatialInterface::GEOMETRY;
151✔
208
    }
209

210
    // phpcs:disable Generic.NamingConventions.CamelCapsFunctionName.ScopeNotCamelCaps
211

212
    /**
213
     * If this Doctrine Type maps to an already mapped database type,
214
     * reverse schema engineering can't take them apart. You need to mark
215
     * one of those types as commented, which will have Doctrine use an SQL
216
     * comment to typehint the actual Doctrine Type.
217
     *
218
     * @param AbstractPlatform $platform database platform
219
     *
220
     * @return bool
221
     */
222
    public function requiresSQLCommentHint(AbstractPlatform $platform)
×
223
    {
224
        // TODO onSchemaColumnDefinition event listener?
225
        return $platform instanceof AbstractPlatform;
×
226
    }
227

228
    /**
229
     * Is this type supported by the specified database platform?
230
     *
231
     * @param PlatformInterface $platform the spatial platform
232
     */
233
    public function supportsPlatform(PlatformInterface $platform): bool
201✔
234
    {
235
        return in_array($platform::class, $this->getSupportedPlatforms(), true);
201✔
236
    }
237

238
    // phpcs:enable
239

240
    /**
241
     * Return the spatial platform when it is accepted.
242
     *
243
     * @param AbstractPlatform $platform the database platform
244
     *
245
     * @throws UnsupportedPlatformException when platform is unknown by the library
246
     */
247
    private function getSpatialPlatform(AbstractPlatform $platform): PlatformInterface
214✔
248
    {
249
        if ($platform instanceof MariaDBPlatform) {
214✔
250
            return new MariaDB();
102✔
251
        }
252

253
        if ($platform instanceof MySQLPlatform) {
190✔
254
            return new MySql();
115✔
255
        }
256

257
        if ($platform instanceof PostgreSQLPlatform) {
167✔
258
            return new PostgreSql();
167✔
259
        }
260

261
        throw new UnsupportedPlatformException(sprintf(
×
262
            'DBAL platform "%s" is not currently supported.',
×
263
            $platform::class
×
264
        ));
×
265
    }
266

267
    /**
268
     * Return an array of all platform supporting the current type.
269
     *
270
     * @return class-string<PlatformInterface>[]
271
     */
272
    abstract protected function getSupportedPlatforms(): array;
273
}
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