diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index f511158..2a2c864 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -17,6 +17,8 @@ jobs: - '8.2' - '8.3' - '8.4' + - '8.5' + - '8.6' dependency-versions: - 'lowest' - 'default' diff --git a/.gitignore b/.gitignore index 1eadc51..d35a0ae 100644 --- a/.gitignore +++ b/.gitignore @@ -4,4 +4,5 @@ Thumbs.db thumbs.db /composer.lock +/patches.lock.json .phpunit.result.cache diff --git a/CHANGELOG.md b/CHANGELOG.md index 20e56e2..651ed60 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,7 @@ ### Unreleased +* Support PHP 8.5 & 8.6 + ### v2.5.1 (2025-09-17) * Fix MysqlSession to immediately return false (without database check) if session ID does not match the pattern of IDs diff --git a/composer.json b/composer.json index 9cf80e3..9a5f962 100644 --- a/composer.json +++ b/composer.json @@ -16,16 +16,17 @@ ], "require": { "ext-json": "*", - "ext-mbstring": "~8.2.0 || ~8.3.0 || ~8.4.0", - "ext-pdo": "~8.2.0 || ~8.3.0 || ~8.4.0", - "ext-sodium": "~8.2.0 || ~8.3.0 || ~8.4.0", - "php": "~8.2.0 || ~8.3.0 || ~8.4.0", + "ext-mbstring": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0", + "ext-pdo": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0", + "ext-sodium": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0", + "php": "~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0 || ~8.6.0", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "require-dev": { "mikey179/vfsstream": "^1.6.12", "phpunit/phpunit": "^11.5", - "ergebnis/phpunit-slow-test-detector": "^2.15" + "ergebnis/phpunit-slow-test-detector": "^2.15", + "cweagans/composer-patches": "~2.0" }, "support": { "source": "https://github.com/ingenerator/php-utils", @@ -42,6 +43,12 @@ } }, "config": { - "preferred-install": "dist" + "preferred-install": "dist", + "allow-plugins": { + "cweagans/composer-patches": true + } + }, + "extra": { + "composer-exit-on-patch-failure": true } } diff --git a/patches.json b/patches.json new file mode 100644 index 0000000..6dcd679 --- /dev/null +++ b/patches.json @@ -0,0 +1,7 @@ +{ + "patches": { + "mikey179/vfsstream": { + "Replace deprecated in 8.6 spl_object_hash with spl_object_id": "patches/fix-spl-object-hash.txt" + } + } +} \ No newline at end of file diff --git a/patches/fix-spl-object-hash.txt b/patches/fix-spl-object-hash.txt new file mode 100644 index 0000000..d7f52a2 --- /dev/null +++ b/patches/fix-spl-object-hash.txt @@ -0,0 +1,13 @@ +diff --git a/src/main/php/org/bovigo/vfs/vfsStreamFile.php b/src/main/php/org/bovigo/vfs/vfsStreamFile.php +index 406252a..3deb270 100644 +--- a/src/main/php/org/bovigo/vfs/vfsStreamFile.php ++++ b/src/main/php/org/bovigo/vfs/vfsStreamFile.php +@@ -371,7 +371,7 @@ class vfsStreamFile extends vfsStreamAbstractContent + $resource = $data['wrapper_data']; + } + +- return spl_object_hash($resource); ++ return (string) spl_object_id($resource); + } + + /** diff --git a/src/DateTime/InvalidUserDateTime.php b/src/DateTime/InvalidUserDateTime.php index 74ddff1..3fd0d31 100644 --- a/src/DateTime/InvalidUserDateTime.php +++ b/src/DateTime/InvalidUserDateTime.php @@ -7,6 +7,9 @@ namespace Ingenerator\PHPUtils\DateTime; +use DateInterval; +use DateTimeZone; + /** * Holds a user-entered invalid date string that could not be parsed, to allow overall entity * validation to catch it and legacy forms to re-display it. @@ -45,7 +48,7 @@ public static function getLastErrors(): array|false throw new \BadMethodCallException('Invalid call to '.__METHOD__); } - public static function __set_state(array $array): \DateTimeImmutable + public static function __set_state(array $array): static { throw new \BadMethodCallException('Invalid call to '.__METHOD__); } @@ -60,7 +63,7 @@ public function __toString() return $this->input_string; } - public function add($interval): \DateTimeImmutable + public function add(DateInterval $interval): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' @@ -78,49 +81,49 @@ public function add($interval): \DateTimeImmutable * @return static * Returns the {@link http://www.php.net/manual/en/class.datetimeimmutable.php DateTimeImmutable} object for method chaining or FALSE on failure. */ - public function modify($modify): \DateTimeImmutable + public function modify(string $modify): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' ); } - public function setDate($year, $month, $day): \DateTimeImmutable + public function setDate(int $year, int $month, int $day): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' ); } - public function setISODate($year, $week, $day = 1): \DateTimeImmutable + public function setISODate(int $year, int $week, int $day = 1): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' ); } - public function setTime($hour, $minute, $second = 0, $microseconds = 0): \DateTimeImmutable + public function setTime(int $hour, int $minute, int $second = 0, $microseconds = 0): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' ); } - public function setTimestamp($unixtimestamp): \DateTimeImmutable + public function setTimestamp(int $unixtimestamp): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' ); } - public function setTimezone($timezone): \DateTimeImmutable + public function setTimezone(DateTimeZone $timezone): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' ); } - public function sub($interval): \DateTimeImmutable + public function sub(DateInterval $interval): static { throw new \RuntimeException( 'Cannot '.__METHOD__.' on invalid user date/time `'.$this->input_string.'`' diff --git a/src/Logging/LoggingFailureException.php b/src/Logging/LoggingFailureException.php index c78cd4e..2f0be65 100644 --- a/src/Logging/LoggingFailureException.php +++ b/src/Logging/LoggingFailureException.php @@ -14,7 +14,7 @@ class LoggingFailureException extends \RuntimeException public function __construct(?string $log_destination, Throwable $failure) { - return parent::__construct( + parent::__construct( sprintf( 'Could not write to log at `%s` - [%s] %s', $log_destination, diff --git a/src/Repository/AbstractArrayRepository.php b/src/Repository/AbstractArrayRepository.php index aa59d08..a1c3c9d 100644 --- a/src/Repository/AbstractArrayRepository.php +++ b/src/Repository/AbstractArrayRepository.php @@ -136,7 +136,7 @@ protected function formatSaveLog($entity) return \sprintf( "%s (object %s) with data:\n%s\n", \get_class($entity), - \spl_object_hash($entity), + \spl_object_id($entity), JSON::encode($this->entityToArray($entity)) ); } @@ -153,7 +153,7 @@ protected function formatSaveLog($entity) */ protected function entityToArray($entity, & $seen_objects = []) { - $entity_hash = \spl_object_hash($entity); + $entity_hash = \spl_object_id($entity); if (isset($seen_objects[$entity_hash])) { return '**RECURSION**'; } else { @@ -168,7 +168,7 @@ function ($e) { $entity ); $obj_identity = function ($a) { - return \get_class($a).'#'.\spl_object_hash($a); + return \get_class($a).'#'.\spl_object_id($a); }; $result = []; foreach ($all_props($entity) as $key => $var) {