Skip to content

Commit

Permalink
Specify return types (#56)
Browse files Browse the repository at this point in the history
* Return types of test methods specified
* Quality-tools after merge
* PHP Stan level 0
* Restore compatibility with ORM ^2.19
* Architecture updated
* PHP-Stan level 2
* PHP-Stan level 3
* PHP-Stan level 4
* Fixing UnsupportedPlatform test
* PHP-Stan level 5
* PHP-Stan level 6
* Fixing platform test on orm:^2.19
* PHP-Stan level 7
* PHP-Stan level 8
* PHP-Stan level 9
  • Loading branch information
Alexandre-T authored May 10, 2024
1 parent ae06da2 commit 2314c55
Show file tree
Hide file tree
Showing 167 changed files with 2,737 additions and 2,175 deletions.
43 changes: 29 additions & 14 deletions lib/LongitudeOne/Spatial/DBAL/Platform/AbstractPlatform.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,14 @@

namespace LongitudeOne\Spatial\DBAL\Platform;

use LongitudeOne\Geo\WKB\Exception\ExceptionInterface;
use LongitudeOne\Geo\WKB\Parser as BinaryParser;
use LongitudeOne\Geo\WKT\Parser as StringParser;
use LongitudeOne\Spatial\DBAL\Types\AbstractSpatialType;
use LongitudeOne\Spatial\DBAL\Types\DoctrineSpatialTypeInterface;
use LongitudeOne\Spatial\DBAL\Types\GeographyType;
use LongitudeOne\Spatial\Exception\InvalidValueException;
use LongitudeOne\Spatial\Exception\MissingArgumentException;
use LongitudeOne\Spatial\PHP\Types\Geometry\GeometryInterface;
use LongitudeOne\Spatial\PHP\Types\SpatialInterface;

/**
Expand Down Expand Up @@ -82,15 +83,23 @@ protected static function checkType(array $column, ?AbstractSpatialType $type):
/**
* Convert binary data to a php value.
*
* @param AbstractSpatialType $type The abstract spatial type
* @param string $sqlExpr the SQL expression
* @param DoctrineSpatialTypeInterface $type The abstract spatial type
* @param resource|string $sqlExpr the SQL expression
*
* @return GeometryInterface
* @return SpatialInterface
*
* @throws InvalidValueException when the provided type is not supported
* @throws ExceptionInterface|InvalidValueException when the provided type is not supported
*/
public function convertBinaryToPhpValue(AbstractSpatialType $type, $sqlExpr)
public function convertBinaryToPhpValue(DoctrineSpatialTypeInterface $type, $sqlExpr)
{
if (is_resource($sqlExpr)) {
$sqlExpr = stream_get_contents($sqlExpr);
}

if (false === $sqlExpr) {
throw new InvalidValueException('Invalid resource value.');
}

$parser = new BinaryParser($sqlExpr);

return $this->newObjectFromValue($type, $parser->parse());
Expand All @@ -102,7 +111,7 @@ public function convertBinaryToPhpValue(AbstractSpatialType $type, $sqlExpr)
* @param AbstractSpatialType $type The abstract spatial type
* @param string $sqlExpr the SQL expression
*
* @return GeometryInterface
* @return SpatialInterface
*
* @throws InvalidValueException when the provided type is not supported
*/
Expand Down Expand Up @@ -152,14 +161,12 @@ public function getMappedDatabaseTypes(AbstractSpatialType $type)
/**
* Create spatial object from parsed value.
*
* @param AbstractSpatialType $type The type spatial type
* @param array $value The value of the spatial object
*
* @return GeometryInterface
* @param DoctrineSpatialTypeInterface $type The type spatial type
* @param array{type: string, srid?: ?int, value:mixed} $value The value of the spatial object
*
* @throws InvalidValueException when the provided type is not supported
*/
private function newObjectFromValue(AbstractSpatialType $type, $value)
private function newObjectFromValue(DoctrineSpatialTypeInterface $type, $value): SpatialInterface
{
$typeFamily = $type->getTypeFamily();
$typeName = mb_strtoupper($value['type']);
Expand All @@ -170,8 +177,16 @@ private function newObjectFromValue(AbstractSpatialType $type, $value)
throw new InvalidValueException(sprintf('Unsupported %s type "%s".', $typeFamily, $typeName));
}

$class = sprintf('LongitudeOne\Spatial\PHP\Types\%s\%s', $typeFamily, constant($constName));
/** @var string $constValue */
$constValue = constant($constName);

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

if (isset($value['srid'])) {
return new $class($value['value'], $value['srid']);
}

return new $class($value['value'], $value['srid']);
return new $class($value['value']);
}
}
6 changes: 2 additions & 4 deletions lib/LongitudeOne/Spatial/DBAL/Platform/MySql.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,13 @@ public function convertToPhpValueSql(AbstractSpatialType $type, $sqlExpr)
/**
* Gets the SQL declaration snippet for a field of this type.
*
* @param array $column array SHOULD contain 'type' as key
* @param array<string, mixed> $column array SHOULD contain 'type' as key
* @param ?AbstractSpatialType $type type is now provided
* @param ?int $srid the srid SHOULD be forwarded when known
*
* @return string
*
* @throws MissingArgumentException when $column doesn't contain 'type' and AbstractSpatialType is null
*/
public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = null, ?int $srid = null)
public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = null, ?int $srid = null): string
{
$type = parent::checkType($column, $type);

Expand Down
10 changes: 4 additions & 6 deletions lib/LongitudeOne/Spatial/DBAL/Platform/PlatformInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ interface PlatformInterface
/**
* Convert Binary to php value.
*
* @param AbstractSpatialType $type Spatial type
* @param string $sqlExpr Sql expression
* @param AbstractSpatialType $type Spatial type
* @param null|resource|string $sqlExpr Sql expression
*
* @return GeometryInterface
*/
Expand Down Expand Up @@ -90,13 +90,11 @@ public function getMappedDatabaseTypes(AbstractSpatialType $type);
/**
* Gets the SQL declaration snippet for a field of this type.
*
* @param array $column array SHOULD contain 'type' as key
* @param array<string, mixed> $column array SHOULD contain 'type' as key
* @param ?AbstractSpatialType $type type is now provided
* @param ?int $srid the srid SHOULD be forwarded when known
*
* @return string
*
* @throws MissingArgumentException when $column doesn't contain 'type' and AbstractSpatialType is null
*/
public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = null, ?int $srid = null);
public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = null, ?int $srid = null): string;
}
40 changes: 10 additions & 30 deletions lib/LongitudeOne/Spatial/DBAL/Platform/PostgreSql.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
use LongitudeOne\Spatial\DBAL\Types\GeographyType;
use LongitudeOne\Spatial\Exception\InvalidValueException;
use LongitudeOne\Spatial\Exception\MissingArgumentException;
use LongitudeOne\Spatial\PHP\Types\Geometry\GeometryInterface;
use LongitudeOne\Spatial\PHP\Types\SpatialInterface;

/**
Expand All @@ -36,27 +35,6 @@ class PostgreSql extends AbstractPlatform
{
public const DEFAULT_SRID = 4326;

/**
* Convert Binary to php value.
*
* @param AbstractSpatialType $type Spatial type
* @param string $sqlExpr Sql expression
*
* @return GeometryInterface
*
* @throws InvalidValueException when SQL expression is not a resource
*/
public function convertBinaryToPhpValue(AbstractSpatialType $type, $sqlExpr)
{
if (!is_resource($sqlExpr)) {
throw new InvalidValueException(sprintf('Invalid resource value "%s"', $sqlExpr));
}

$sqlExpr = stream_get_contents($sqlExpr);

return parent::convertBinaryToPhpValue($type, $sqlExpr);
}

/**
* Convert to database value.
*
Expand All @@ -68,13 +46,17 @@ public function convertBinaryToPhpValue(AbstractSpatialType $type, $sqlExpr)
public function convertToDatabaseValue(AbstractSpatialType $type, SpatialInterface $value)
{
$sridSQL = null;
$srid = null;

if ($type instanceof GeographyType && null === $value->getSrid()) {
$value->setSrid(self::DEFAULT_SRID);
}

$srid = $value->getSrid();
if (null !== $srid || $type instanceof GeographyType) {
if (method_exists($value, 'getSrid')) {
$srid = $value->getSrid();
}

if (null !== $srid) {
$sridSQL = sprintf('SRID=%d;', $srid);
}

Expand Down Expand Up @@ -118,16 +100,14 @@ public function convertToPhpValueSql(AbstractSpatialType $type, $sqlExpr)
/**
* Gets the SQL declaration snippet for a field of this type.
*
* @param array $column array SHOULD contain 'type' as key
* @param array<string,mixed> $column array SHOULD contain 'type' as key
* @param ?AbstractSpatialType $type type is now provided
* @param ?int $srid the srid SHOULD be forwarded when known
*
* @return string
*
* @throws MissingArgumentException when $column doesn't contain 'type' and AbstractSpatialType is null
* @throws InvalidValueException when SRID is not null nor an integer
*/
public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = null, ?int $srid = null)
public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = null, ?int $srid = null): string
{
$type = parent::checkType($column, $type);
$srid = parent::checkSrid($column, $srid);
Expand All @@ -138,8 +118,8 @@ public function getSqlDeclaration(array $column, ?AbstractSpatialType $type = nu
return $sqlType;
}

if (null === $srid && key_exists('srid', $column) && null !== $column['srid']) {
$srid = (int) $column['srid'];
if (null === $srid && key_exists('srid', $column) && is_int($column['srid'])) {
$srid = $column['srid'];
}

if (!empty($srid)) {
Expand Down
37 changes: 24 additions & 13 deletions lib/LongitudeOne/Spatial/DBAL/Types/AbstractSpatialType.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,14 @@

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Platforms\MySqlPlatform;
use Doctrine\DBAL\Platforms\PostgreSqlPlatform;
use Doctrine\DBAL\Platforms\PostgreSQLPlatform;
use Doctrine\DBAL\Types\Exception\TypeNotRegistered;
use Doctrine\DBAL\Types\Type;
use LongitudeOne\Spatial\DBAL\Platform\MySql;
use LongitudeOne\Spatial\DBAL\Platform\PlatformInterface;
use LongitudeOne\Spatial\DBAL\Platform\PostgreSql;
use LongitudeOne\Spatial\Exception\InvalidValueException;
use LongitudeOne\Spatial\Exception\UnsupportedPlatformException;
use LongitudeOne\Spatial\PHP\Types\Geography\GeographyInterface;
use LongitudeOne\Spatial\PHP\Types\Geometry\GeometryInterface;
use LongitudeOne\Spatial\PHP\Types\SpatialInterface;

Expand Down Expand Up @@ -63,12 +63,10 @@ public function canRequireSQLConversion()
* @param mixed $value the value to convert
* @param AbstractPlatform $platform the database platform
*
* @return null|string
*
* @throws InvalidValueException when value is not an instance of Geometry Interface
* @throws UnsupportedPlatformException when platform is unsupported
*/
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): mixed
public function convertToDatabaseValue(mixed $value, AbstractPlatform $platform): ?string
{
if (null === $value) {
return null;
Expand Down Expand Up @@ -149,23 +147,36 @@ public function getMappedDatabaseTypes(AbstractPlatform $platform): array
/**
* Gets the name of this type.
*
* @return string
* @return class-string<DoctrineSpatialTypeInterface>
*
* @throws TypeNotRegistered When type is not registered in the map
*/
public function getName()
{
return array_search(get_class($this), self::getTypesMap(), true);
/** @var class-string<DoctrineSpatialTypeInterface>|false $className */
$className = array_search($this::class, self::getTypesMap(), true);

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

return $className;
}

/**
* Gets the SQL declaration snippet for a field of this type.
*
* @param array $column the field declaration
* @param AbstractPlatform $platform database platform
* @param array<string,mixed> $column the field declaration
* @param AbstractPlatform $platform database platform
*
* @throws UnsupportedPlatformException when platform is unsupported
*/
public function getSqlDeclaration(array $column, AbstractPlatform $platform): string
{
if (!is_int($column['srid']) || $column['srid'] < 0) {
$column['srid'] = null;
}

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

Expand All @@ -188,11 +199,11 @@ public function getSQLType()
// phpcs:enable

/**
* @return string
* @return (SpatialInterface::GEOGRAPHY|SpatialInterface::GEOMETRY)
*/
public function getTypeFamily()
public function getTypeFamily(): string
{
return $this instanceof GeographyType ? GeographyInterface::GEOGRAPHY : GeometryInterface::GEOMETRY;
return $this instanceof GeographyType ? SpatialInterface::GEOGRAPHY : SpatialInterface::GEOMETRY;
}

// phpcs:disable Generic.NamingConventions.CamelCapsFunctionName.ScopeNotCamelCaps
Expand Down Expand Up @@ -230,7 +241,7 @@ private function getSpatialPlatform(AbstractPlatform $platform)
return new MySql();
}

if ($platform instanceof PostgreSqlPlatform) {
if ($platform instanceof PostgreSQLPlatform) {
return new PostgreSql();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,10 @@

interface DoctrineSpatialTypeInterface
{
/**
* Return (SpatialInterface::GEOGRAPHY|SpatialInterface::GEOMETRY) the family of the type.
*
* @return ('Geography'|'Geometry')
*/
public function getTypeFamily(): string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
use Doctrine\ORM\Query\QueryException;
use Doctrine\ORM\Query\SqlWalker;
use Doctrine\ORM\Query\TokenType;
use LongitudeOne\Spatial\Exception\InvalidValueException;
use LongitudeOne\Spatial\Exception\UnsupportedPlatformException;

/**
Expand Down Expand Up @@ -54,7 +55,7 @@ abstract class AbstractSpatialDQLFunction extends FunctionNode
/**
* @var Node[]
*/
private $geometryExpression = [];
private array $geometryExpression = [];

/**
* Get the SQL.
Expand Down Expand Up @@ -95,7 +96,7 @@ public function parse(Parser $parser): void

while (count($this->geometryExpression) < $this->getMinParameter()
|| ((count($this->geometryExpression) < $this->getMaxParameter())
&& TokenType::T_CLOSE_PARENTHESIS != $lexer->lookahead->type)
&& TokenType::T_CLOSE_PARENTHESIS != $lexer->lookahead?->type)
) {
$parser->match(TokenType::T_COMMA);

Expand All @@ -108,12 +109,18 @@ public function parse(Parser $parser): void
/**
* Geometry expressions fluent adder.
*
* @param Node $expression the node expression to add to the array of geometry expression
* @param Node|string $expression the node expression to add to the array of geometry expression
*
* @since 2.0 This function replace the protected property geomExpr which is now private.
*
* @throws InvalidValueException when expression is a string
*/
final protected function addGeometryExpression(Node $expression): self
protected function addGeometryExpression(Node|string $expression): self
{
if (is_string($expression)) {
throw new InvalidValueException('Expression must be a node.');
}

$this->geometryExpression[] = $expression;

return $this;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,13 +62,13 @@ public function parse(Parser $parser): void
$this->addGeometryExpression($parser->ArithmeticFactor());

// 2nd signature
if (TokenType::T_COMMA === $lexer->lookahead->type) {
if (TokenType::T_COMMA === $lexer->lookahead?->type) {
$parser->match(TokenType::T_COMMA);
$this->addGeometryExpression($parser->ArithmeticFactor());
}

// 3rd signature
if (TokenType::T_COMMA === $lexer->lookahead->type) {
if (TokenType::T_COMMA === $lexer->lookahead?->type) {
$parser->match(TokenType::T_COMMA);
$this->addGeometryExpression($parser->ArithmeticFactor());

Expand Down
Loading

0 comments on commit 2314c55

Please sign in to comment.