diff --git a/Makefile b/Makefile index cda4fe0..5e4df1d 100644 --- a/Makefile +++ b/Makefile @@ -12,7 +12,7 @@ csf: vendor/bin/phpcbf --standard=ruleset.xml --extensions=php,phpt --tab-width=4 --ignore=temp -sp src tests phpstan: - vendor/bin/phpstan analyse -l 1 -c phpstan.neon --memory-limit=512M src + vendor/bin/phpstan analyse -l 2 -c phpstan.neon --memory-limit=512M src tests: vendor/bin/tester -s -p php --colors 1 -C tests diff --git a/phpstan.neon b/phpstan.neon index 4fc3dfb..67dfdea 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,17 +1,15 @@ parameters: ignoreErrors: - - # object to array + - # DataApiObject uses dynamic property access for toArray() serialization + # This is a core PHP pattern for DTOs that serialize via reflection message: '~^Variable property access on \$this\(Tp\\DataApi\\DataApiObject\)\.$~' path: %currentWorkingDirectory%/src/DataApi/DataApiObject.php - - # offsetGet, offsetSet + - # ArrayAccess implementation requires dynamic method dispatch to getters/setters message: '~^Variable method call on \$this\(Tp\\DataApi\\DataApiObject\)\.$~' path: %currentWorkingDirectory%/src/DataApi/DataApiObject.php - - # setProperty, getProperty + - # ReturnedPayment hydrates from request args using config-driven property names message: '~^Variable property access on \$this\(Tp\\ReturnedPayment\)\.$~' path: %currentWorkingDirectory%/src/ReturnedPayment.php - - # generic formaters - message: '~^Variable static method call on Tp\\DataApi\\ValueFormatter\.$~' - path: %currentWorkingDirectory%/src/DataApi/ValueFormatter.php - - # remote API call + - # SoapClient requires dynamic method dispatch for SOAP operations message: '~^Variable method call on SoapClient\.$~' path: %currentWorkingDirectory%/src/Helper/DataApi.php diff --git a/src/DataApi/DataApiObject.php b/src/DataApi/DataApiObject.php index 1069746..25b7836 100644 --- a/src/DataApi/DataApiObject.php +++ b/src/DataApi/DataApiObject.php @@ -5,6 +5,7 @@ use ArrayAccess; use ReflectionClass; use ReflectionMethod; +use ReflectionNamedType; use ReflectionProperty; use ReturnTypeWillChange; use Tp\Utils; @@ -49,7 +50,7 @@ static function (ReflectionProperty $property): bool { return self::filterDataProperties($property); } ); - $sortedDataProperties = static::sortDataProperties($dataProperties); + $sortedDataProperties = self::sortDataProperties($dataProperties); $propertyNames = []; foreach ($sortedDataProperties as $property) { @@ -149,7 +150,7 @@ public function offsetSet($offset, $value): void $reflectionMethod = new ReflectionMethod($this, $setterName); $parameterType = $reflectionMethod->getParameters()[0]->getType(); - assert($parameterType !== null); + assert($parameterType instanceof ReflectionNamedType); switch ($parameterType->getName()) { case 'int': diff --git a/src/DataApi/Processors/Processor.php b/src/DataApi/Processors/Processor.php index 41fb02a..b9d6071 100644 --- a/src/DataApi/Processors/Processor.php +++ b/src/DataApi/Processors/Processor.php @@ -7,13 +7,6 @@ abstract class Processor { - public static function process(array $input): array - { - $instance = new static(); /* @phpstan-ignore-line */ - // Start with an empty path []. - return $instance->processHash($input, []); - } - /** * @param string[]|int[] $currentPath */ diff --git a/src/DataApi/ValueFormatter.php b/src/DataApi/ValueFormatter.php index 94a3a82..172d6b6 100644 --- a/src/DataApi/ValueFormatter.php +++ b/src/DataApi/ValueFormatter.php @@ -18,25 +18,23 @@ class ValueFormatter public static function format(string $type, $value) { if (substr($type, -2) === '[]') { - return static::formatList(substr($type, 0, -2), $value); + return self::formatList(substr($type, 0, -2), $value); } - $isNull = $value === null; - if ($isNull) { + if ($value === null) { return null; } - $method = 'format' . ucfirst($type); - if (method_exists(self::class, $method)) { - return static::$method($value); - } - - if (class_exists($type) && $value instanceof $type) { - return $value; - } - - $message = 'Unknown type ' . $type . '.'; - throw new InvalidArgumentException($message); + return match ($type) { + 'int' => self::formatInt($value), + 'float' => self::formatFloat($value), + 'bool' => self::formatBool($value), + 'string' => self::formatString($value), + 'dateTime' => self::formatDateTime($value), + default => class_exists($type) && $value instanceof $type + ? $value + : throw new InvalidArgumentException('Unknown type ' . $type . '.'), + }; } public static function formatInt(?int $value): ?int diff --git a/src/Payment.php b/src/Payment.php index c405ca0..bd89d7d 100644 --- a/src/Payment.php +++ b/src/Payment.php @@ -358,7 +358,7 @@ public function getArgs(): array 'email' => $customerData->getEmail(), ]); - if ($customerDataArr) { + if ($customerDataArr !== []) { $input['customerData'] = Escaper::jsonEncode($customerDataArr); } } diff --git a/src/Utils.php b/src/Utils.php index 14b24c7..6fe6b9f 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -50,7 +50,7 @@ public static function isList(array $array): bool { $count = count($array); - $range = $count + $range = $count > 0 ? range(0, $count - 1) : [];