From a4ebe1b1cf39a95ab3d9c3f3aac42916c60c68c4 Mon Sep 17 00:00:00 2001 From: Constantine Nathanson <35217733+const-cloudinary@users.noreply.github.com> Date: Wed, 15 Jan 2025 00:50:47 +0200 Subject: [PATCH] Fix types --- phpstan.neon | 2 + src/Transformation/CommonTransformation.php | 4 +- .../CommonTransformationInterface.php | 8 +- .../Delivery/TransformationDeliveryTrait.php | 4 +- .../Dimensions/DimensionsQualifierTrait.php | 5 +- .../Qualifier/QualifiersAction.php | 2 +- src/Transformation/Video/Transcode/Fps.php | 2 +- src/Utils/ArrayUtils.php | 113 ++++++++++-------- src/Utils/ClassUtils.php | 4 +- src/Utils/JsonUtils.php | 8 +- src/Utils/StringUtils.php | 46 ++++--- src/Utils/TransformationUtils.php | 15 +-- 12 files changed, 118 insertions(+), 95 deletions(-) diff --git a/phpstan.neon b/phpstan.neon index e89ee99..50a343f 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -4,3 +4,5 @@ parameters: - src ignoreErrors: - '#Unsafe usage of new static\(\)#' + #- '#Method .+ has parameter \$[a-zA-Z0-9_]+ with no value type specified in iterable type array#' + #- '#Method .+ return type has no value type specified in iterable type array#' diff --git a/src/Transformation/CommonTransformation.php b/src/Transformation/CommonTransformation.php index c78a450..146904e 100644 --- a/src/Transformation/CommonTransformation.php +++ b/src/Transformation/CommonTransformation.php @@ -94,10 +94,10 @@ public function addAction(mixed $action): static * * Appended transformation is nested. * - * @param CommonTransformation|string|null $transformation The transformation to add. + * @param mixed $transformation The transformation to add. * */ - public function addTransformation(CommonTransformation|string|null $transformation): static + public function addTransformation(mixed $transformation): static { $this->actions[] = ClassUtils::forceInstance($transformation, CommonTransformation::class); diff --git a/src/Transformation/CommonTransformationInterface.php b/src/Transformation/CommonTransformationInterface.php index 28458f6..2fee995 100644 --- a/src/Transformation/CommonTransformationInterface.php +++ b/src/Transformation/CommonTransformationInterface.php @@ -22,22 +22,22 @@ interface CommonTransformationInterface extends ComponentInterface * * (Formerly known as fetch format). * - * @param string|Format $format The format in which to deliver the asset. + * @param Format|string|null $format The format in which to deliver the asset. * * * @see Format */ - public function format(Format|string $format): static; + public function format(Format|string|null $format): static; /** * Controls compression quality. * * Reducing the quality is a trade-off between visual quality and file size. * - * @param Quality|int|float|string $quality The quality value. (Range 1 to 100) + * @param Quality|int|float|string|null $quality The quality value. (Range 1 to 100) * */ - public function quality(Quality|int|float|string $quality): static; + public function quality(Quality|int|float|string|null $quality): static; /** * Applies a filter or an effect on an asset. diff --git a/src/Transformation/Delivery/TransformationDeliveryTrait.php b/src/Transformation/Delivery/TransformationDeliveryTrait.php index cd7dbdb..fbbdfaa 100644 --- a/src/Transformation/Delivery/TransformationDeliveryTrait.php +++ b/src/Transformation/Delivery/TransformationDeliveryTrait.php @@ -40,7 +40,7 @@ public function delivery($delivery): static * * */ - public function format(Format|string $format): static + public function format(Format|string|null $format): static { return $this->addAction(ClassUtils::verifyInstance($format, Format::class)); } @@ -53,7 +53,7 @@ public function format(Format|string $format): static * * */ - public function quality(Quality|int|float|string $quality): static + public function quality(Quality|int|float|string|null $quality): static { return $this->addAction(ClassUtils::verifyInstance($quality, Quality::class)); } diff --git a/src/Transformation/Qualifier/Dimensions/DimensionsQualifierTrait.php b/src/Transformation/Qualifier/Dimensions/DimensionsQualifierTrait.php index 5a7c1a7..1500d1e 100644 --- a/src/Transformation/Qualifier/Dimensions/DimensionsQualifierTrait.php +++ b/src/Transformation/Qualifier/Dimensions/DimensionsQualifierTrait.php @@ -10,6 +10,7 @@ namespace Cloudinary\Transformation; +use Cloudinary\ClassUtils; use Cloudinary\Transformation\Qualifier\Dimensions\Dpr; use Cloudinary\Transformation\Qualifier\Dimensions\Height; use Cloudinary\Transformation\Qualifier\Dimensions\Width; @@ -70,8 +71,8 @@ public static function aspectRatio(...$aspectRatio): AspectRatio * * @see Dpr */ - public static function dpr(float $dpr): Dpr + public static function dpr(int|float|string|Dpr $dpr): Dpr { - return new Dpr($dpr); + return ClassUtils::verifyInstance($dpr, Dpr::class); } } diff --git a/src/Transformation/Qualifier/QualifiersAction.php b/src/Transformation/Qualifier/QualifiersAction.php index 1fbc1c6..bcebe70 100644 --- a/src/Transformation/Qualifier/QualifiersAction.php +++ b/src/Transformation/Qualifier/QualifiersAction.php @@ -75,7 +75,7 @@ class QualifiersAction extends BaseAction 'video_codec' => null, ]; - protected const QUALIFIERS = self::COMPLEX_QUALIFIERS + self::SIMPLE_QUALIFIERS; + public const QUALIFIERS = self::COMPLEX_QUALIFIERS + self::SIMPLE_QUALIFIERS; /** * Add qualifiers to the action. diff --git a/src/Transformation/Video/Transcode/Fps.php b/src/Transformation/Video/Transcode/Fps.php index cb327ac..8b424f2 100644 --- a/src/Transformation/Video/Transcode/Fps.php +++ b/src/Transformation/Video/Transcode/Fps.php @@ -21,7 +21,7 @@ * href=https://cloudinary.com/documentation/video_transformation_reference#video_settings * target="_blank">Video settings * - * @property MinMaxRange value + * @property MinMaxRange $value * * @api */ diff --git a/src/Utils/ArrayUtils.php b/src/Utils/ArrayUtils.php index 4a99037..0b075a0 100644 --- a/src/Utils/ArrayUtils.php +++ b/src/Utils/ArrayUtils.php @@ -22,12 +22,12 @@ class ArrayUtils /** * Applies the callback to the elements of the given associative array * - * @param callable $callback The callback function - * @param array $array An array to run through the callback function. + * @param callable $callback The callback function + * @param ArrayObject|array $array An array to run through the callback function. * * @return array Resulting array */ - public static function mapAssoc(callable $callback, array $array): array + public static function mapAssoc(callable $callback, ArrayObject|array $array): array { $r = []; foreach ($array as $key => $value) { @@ -128,29 +128,32 @@ static function ($k, $v) use ($inner, $innerIsSafe) { * @see implode */ public static function implodeFiltered( - string $glue, - array $pieces, - string $filterCallback = __NAMESPACE__ . '\ArrayUtils::safeFilterFunc', + array|string $glue, + array|null $pieces, + callable|null $filterCallback = null, int $flag = 0 ): string { + $filterCallback ??= fn($value) => ArrayUtils::safeFilterFunc($value); + return self::safeImplode($glue, self::safeFilter($pieces, $filterCallback, $flag)); } /** * Safe version of implode. * - * In addition fixes serialisation of float values. - * + * In addition, fixes serialisation of float values. * */ - public static function safeImplode($glue, array $pieces): string + public static function safeImplode(array|string $glue, array|null $pieces): string { - array_walk( - $pieces, - static function (&$value) { - $value = TransformationUtils::floatToString($value); - } - ); + if (! is_null($pieces)) { + array_walk( + $pieces, + static function (&$value) { + $value = TransformationUtils::floatToString($value); + } + ); + } return implode($glue, $pieces); } @@ -158,10 +161,13 @@ static function (&$value) { /** * Implodes array values with escaping the glue character. * - * */ - public static function escapedImplode(string $glue, array $pieces): string + public static function escapedImplode(string|array $glue, array|null $pieces): string { + if (is_null($pieces)) { + return ''; + } + return implode( $glue, array_map( @@ -206,18 +212,17 @@ protected static function safeFilterFunc(mixed $value): bool|int * * Uses "strlen" filter function by default, which treats non-null values (e.g. 0, false, etc) as non-empty. * - * @param callback|string $callback - * - * * @see array_filter * @see strlen */ public static function safeFilter( - array $input, - callable|string $callback = __NAMESPACE__ . '\ArrayUtils::safeFilterFunc', + ?array $input, + callable|null $callback = null, int $flag = 0 - ): array { - return array_filter($input, $callback, $flag); + ): ?array { + $callback ??= fn($value) => ArrayUtils::safeFilterFunc($value); + + return is_null($input) ? $input : array_filter($input, $callback, $flag); } /** @@ -226,7 +231,7 @@ public static function safeFilter( * In case some of the missing/extra keys, the keys are sorted using alphabetic order. Ordered keys come first. * * @param ?array $array The associate array to order. - * @param array $orderArray The desired order of the keys. + * @param array $orderArray The desired order of the keys. * */ public static function sortByArray(?array $array, array $orderArray = []): ?array @@ -256,15 +261,16 @@ public static function implodeUrl(array $urlParts): string /** * Commonly used util for building transformation URL * - * @param array $qualifiers - * * @return string The resulting string * * @internal */ - public static function implodeActionQualifiers(...$qualifiers): string + public static function implodeActionQualifiers(mixed ...$qualifiers): string { - $serializedQualifiers = array_map('strval', $qualifiers); + $serializedQualifiers = []; + foreach ($qualifiers as $item) { + $serializedQualifiers[] = (string)$item; + } sort($serializedQualifiers); @@ -288,13 +294,13 @@ public static function implodeQualifierValues(...$qualifierValues): string /** * Gets a key from an array if exists, otherwise returns default. * - * @param ArrayObject|array $array The data array. - * @param int|array|string $key The key. Can be a simple key(string|int), an index array that allows accessing + * @param mixed $array The data array. + * @param int|array|string $key The key. Can be a simple key(string|int), an index array that allows accessing * nested values - * @param mixed|null $default The default value for the case when the key is not found. + * @param mixed|null $default The default value for the case when the key is not found. * */ - public static function get(ArrayObject|array $array, int|array|string $key, mixed $default = null): mixed + public static function get(mixed $array, int|array|string $key, mixed $default = null): mixed { if (is_array($key)) { $currLevel = &$array; @@ -323,13 +329,12 @@ public static function get(ArrayObject|array $array, int|array|string $key, mixe /** * Pops a key from an array if exists, otherwise returns default * - * @param array $array Data array - * @param int|array|string $key key can be a simple key(string|int) or an array that allows accessing nested - * values - * @param mixed|null $default Default value for the case when key is not found + * @param array $array Data array + * @param int|string $key A simple key(string|int) + * @param mixed|null $default Default value for the case when key is not found * */ - public static function pop(array &$array, int|array|string $key, mixed $default = null): mixed + public static function pop(array &$array, int|string $key, mixed $default = null): mixed { $val = self::get($array, $key, $default); unset($array[$key]); @@ -341,7 +346,7 @@ public static function pop(array &$array, int|array|string $key, mixed $default * Returns a subset of associative array whitelisted by an array of keys * * @param ?array $array Source array (associative or not) - * @param array $keys Simple array of keys to keep + * @param array $keys Simple array of keys to keep * * @return ?array Resulting array */ @@ -363,7 +368,7 @@ public static function whitelist(?array $array, array $keys): ?array * Returns a subset of associative array with excluded keys specified by an array of keys * * @param ?array $array Source array (associative or not) - * @param array $blacklistedKeys Simple array of keys to be excluded + * @param array $blacklistedKeys Simple array of keys to be excluded * * @return ?array Resulting array */ @@ -500,10 +505,11 @@ public static function addNonEmpty(array &$arr, int|string|null $key, mixed $val /** * Adds key-value pair to the associative array where value is taken from source array using the same key. * - * @param array & $resultingArr The target array. - * @param mixed $key The key to add - * @param array $sourceArray The source array - * @param mixed|null $defaultValue Fallback value, in case the key does not exist or is empty + * @param array & $resultingArr The target array. + * @param mixed $key The key to add + * @param array|ArrayObject $sourceArray The source array + * @param mixed|null $defaultValue Fallback value, in case the key does not exist or is + * empty * * @return array The resulting array * @@ -512,7 +518,7 @@ public static function addNonEmpty(array &$arr, int|string|null $key, mixed $val public static function addNonEmptyFromOther( array &$resultingArr, mixed $key, - array $sourceArray, + array|ArrayObject $sourceArray, mixed $defaultValue = null ): array { return self::addNonEmpty($resultingArr, $key, self::get($sourceArray, $key, $defaultValue)); @@ -533,7 +539,12 @@ public static function mergeNonEmpty(...$arrays): array $result = []; foreach ($arrays as $array) { - $result = array_merge($result, self::safeFilter($array)); + if (! empty($array)) { + $filtered = self::safeFilter($array); + if ($filtered) { + $result = array_merge($result, $filtered); + } + } } return $result; @@ -621,11 +632,11 @@ public static function convertToAssoc(array $array): array /** * Helper function for making a recursive array copy while cloning objects on the way. * - * @param array $array Source array + * @param mixed $array Source array * - * @return array Recursive copy of the source array + * @return mixed Recursive copy of the source array */ - public static function deepCopy(array $array): array + public static function deepCopy(mixed $array): mixed { if (! is_array($array)) { return $array; @@ -647,10 +658,8 @@ public static function deepCopy(array $array): array /** * Indicates whether all parameters are non-empty - * - * */ - public static function all(...$params): bool + public static function all(array ...$params): bool { foreach ($params as $param) { if (empty($param)) { diff --git a/src/Utils/ClassUtils.php b/src/Utils/ClassUtils.php index 6a34dee..20c00aa 100644 --- a/src/Utils/ClassUtils.php +++ b/src/Utils/ClassUtils.php @@ -51,8 +51,8 @@ public static function getBaseName(string $className): string /** * Gets class constants. * - * @param object|string $instance The instance object. - * @param array $exclusions The list of constants to exclude. + * @param object|class-string $instance The instance object. + * @param array $exclusions The list of constants to exclude. * * @return array of class constants */ diff --git a/src/Utils/JsonUtils.php b/src/Utils/JsonUtils.php index 2c1c074..bdfcfdf 100644 --- a/src/Utils/JsonUtils.php +++ b/src/Utils/JsonUtils.php @@ -23,10 +23,10 @@ class JsonUtils /** * Determines whether the input is a valid JSON string. * - * @param string $string The input string. + * @param mixed $string The input string. * */ - public static function isJsonString(string $string): bool + public static function isJsonString(mixed $string): bool { return is_string($string) && is_array(json_decode($string, true)) //TODO: improve performance @@ -52,7 +52,7 @@ public static function decode(mixed $json, bool $assoc = true, int $depth = 512, return $json; } - $result = json_decode($json, $assoc, $depth, $options); + $result = json_decode($json, $assoc, max(1, $depth), $options); if (json_last_error() !== JSON_ERROR_NONE) { throw new InvalidArgumentException('JsonException : ' . json_last_error_msg()); @@ -76,7 +76,7 @@ public static function decode(mixed $json, bool $assoc = true, int $depth = 512, */ public static function encode(mixed $value, int $options = 0, int $depth = 512): bool|string { - $result = json_encode($value, $options, $depth); + $result = json_encode($value, $options, max(1, $depth)); if (json_last_error() !== JSON_ERROR_NONE) { throw new InvalidArgumentException('JsonException : ' . json_last_error_msg()); diff --git a/src/Utils/StringUtils.php b/src/Utils/StringUtils.php index bdc1527..63e211c 100644 --- a/src/Utils/StringUtils.php +++ b/src/Utils/StringUtils.php @@ -28,7 +28,13 @@ class StringUtils */ public static function camelCaseToSnakeCase(string $input, string $separator = '_'): string { - return strtolower(preg_replace('/(? mis; color_space -> cs; * - * @param string $input The input string. - * @param array $exclusions The list of words to omit from acronym. Useful for internal names. - * @param string $delimiter The delimiter between words. + * @param string $input The input string. + * @param array $exclusions The list of words to omit from acronym. Useful for internal names. + * @param non-empty-string $delimiter The delimiter between words. * */ public static function toAcronym(string $input, array $exclusions = [], string $delimiter = '_'): string { $acronym = ''; - - foreach (ArrayUtils::safeFilter(ArrayUtils::blacklist(explode($delimiter, $input), $exclusions)) as $word) { - $acronym .= $word[0]; + $parts = ArrayUtils::safeFilter(ArrayUtils::blacklist(explode($delimiter, $input), $exclusions)); + if (! empty($parts)) { + foreach ($parts as $word) { + $acronym .= $word[0]; + } } return $acronym; @@ -112,7 +120,7 @@ public static function ensureWrappedWith(string $string, string $char): string * Determines whether $haystack contains $needle. * * @param ?string $haystack The string to search in. - * @param string $needle The string to search for. + * @param string $needle The string to search for. * */ public static function contains(?string $haystack, string $needle): bool @@ -128,13 +136,13 @@ public static function contains(?string $haystack, string $needle): bool * Truncates prefix from the string. * * @param ?string $string The input string. - * @param string $prefix Prefix to truncate. + * @param string $prefix Prefix to truncate. * * @return ?string The resulting string. */ public static function truncatePrefix(?string $string, string $prefix): ?string { - if (self::startsWith($string, $prefix)) { + if (is_string($string) && self::startsWith($string, $prefix)) { return substr($string, strlen($prefix)); } @@ -152,16 +160,19 @@ public static function truncatePrefix(?string $string, string $prefix): ?string * @param int $maxLength Maximum string length. * */ - public static function truncateMiddle(string $string, int $maxLength = self::MAX_STRING_LENGTH, string $glue = '...'): string - { + public static function truncateMiddle( + string $string, + int $maxLength = self::MAX_STRING_LENGTH, + string $glue = '...' + ): string { // Early exit if no truncation necessary if (strlen($string) <= $maxLength) { return $string; } - $numRightChars = ceil($maxLength / 2); + $numRightChars = (int)ceil($maxLength / 2); - $numLeftChars = floor($maxLength / 2); + $numLeftChars = (int)floor($maxLength / 2); $glue = substr($glue, 0, $numLeftChars); // Pathological case, when glue is longer than a half $numLeftChars -= strlen($glue); @@ -216,9 +227,8 @@ public static function encodeDot(string $string): array|string|null * @param string $string The input string. * @param array|string $unsafeChars The list of the characters to escape. * - * @return string|string[]|null */ - public static function escapeUnsafeChars(string $string, array|string $unsafeChars): array|string|null + public static function escapeUnsafeChars(string $string, array|string $unsafeChars): string|null { if (empty($unsafeChars)) { return $string; @@ -250,13 +260,13 @@ public static function base64UrlEncode(mixed $data): string /** * Wrapper around parse_str, returns query parameters. * - * @param string $query The query string. + * @param ?string $query The query string. * * @return array Query parameters. * * @see parse_str */ - public static function parseQueryString(string $query): array + public static function parseQueryString(?string $query): array { $params = []; if (! empty($query)) { diff --git a/src/Utils/TransformationUtils.php b/src/Utils/TransformationUtils.php index 04734a0..fec5cc8 100644 --- a/src/Utils/TransformationUtils.php +++ b/src/Utils/TransformationUtils.php @@ -20,9 +20,6 @@ class TransformationUtils { /** * Converts a float value to the string representation. - * - * - * @return mixed|string */ public static function floatToString(mixed $value): mixed { @@ -33,7 +30,7 @@ public static function floatToString(mixed $value): mixed // Ensure that trailing decimal(.0) part is not cropped when float is provided. // e.g. float 1.0 should be returned as "1.0" and not "1" as it happens by default. if ($value - (int)$value === 0.0) { - return sprintf("%.1f", $value); + return sprintf('%.1f', $value); } $locale = localeconv(); @@ -48,18 +45,22 @@ public static function floatToString(mixed $value): mixed * @param mixed $value Candidate to convert. If not boolean, returned as is * */ - public static function boolToIntString(mixed $value): ?string + public static function boolToIntString(mixed $value): mixed { return self::boolToString($value, '1', '0'); } + /** * Helper method for converting boolean to any representation as string. * * @param mixed $value Candidate to convert. If not boolean, returned as is * */ - public static function boolToString(mixed $value, $trueString = 'true', $falseString = 'false'): ?string - { + public static function boolToString( + mixed $value, + ?string $trueString = 'true', + ?string $falseString = 'false' + ): mixed { return is_bool($value) ? ($value ? $trueString : $falseString) : $value; }