diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index bbf4965c..72631e76 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -46,7 +46,7 @@ jobs: - name: Set up PHP uses: shivammathur/setup-php@bf6b4fbd49ca58e4608c9c89fba0b8d90bd2a39f # v2 with: - php-version: '8.4' + php-version: '8.5' extensions: ctype, json, mbstring tools: composer diff --git a/.github/workflows/integration-tests.yml b/.github/workflows/integration-tests.yml index 4e319a02..e24fea4d 100644 --- a/.github/workflows/integration-tests.yml +++ b/.github/workflows/integration-tests.yml @@ -41,9 +41,9 @@ jobs: name: "PostgreSQL ${{ matrix.postgres }} + PostGIS ${{ matrix.postgis }} + PHP ${{ matrix.php }}" strategy: - fail-fast: false + fail-fast: ${{ github.event_name == 'pull_request' }} matrix: - php: ['8.1', '8.2', '8.3', '8.4'] + php: ['8.1', '8.2', '8.3', '8.4', '8.5'] postgis: ['3.4', '3.5', '3.6'] postgres: ['16', '17', '18'] exclude: @@ -57,7 +57,7 @@ jobs: postgis: '3.5' include: # Code coverage on the latest stable combination - - php: '8.4' + - php: '8.5' postgres: '18' postgis: '3.6' calculate-code-coverage: true @@ -92,15 +92,20 @@ jobs: - name: Validate composer.json and composer.lock run: composer validate --strict + - name: Get composer cache directory + id: composer-cache-dir + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + - name: Cache Composer packages - id: composer-cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: - path: vendor - key: ${{ runner.os }}-php-${{ matrix.php }}-pg-${{ matrix.postgres }}-${{ hashFiles('**/composer.lock') }} + path: | + ${{ steps.composer-cache-dir.outputs.dir }} + vendor + key: ${{ runner.os }}-php-${{ matrix.php }}-composer-${{ hashFiles('**/composer.lock') }} restore-keys: | - ${{ runner.os }}-php-${{ matrix.php }}-pg-${{ matrix.postgres }}- - ${{ runner.os }}-php-${{ matrix.php }}- + ${{ runner.os }}-php-${{ matrix.php }}-composer- + ${{ runner.os }}-composer- - name: Install dependencies run: composer install --prefer-dist --no-interaction --no-progress @@ -112,22 +117,7 @@ jobs: - name: Verify PostgreSQL connection and setup run: | - echo "Checking PostgreSQL version:" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "SELECT version();" - - echo "\nChecking PostgreSQL configuration:" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "SHOW server_version;" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "SHOW max_connections;" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "SHOW shared_buffers;" - - echo "\nCreating test schema:" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "CREATE SCHEMA IF NOT EXISTS test;" - - echo "\nListing available PostgreSQL extensions:" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "SELECT * FROM pg_available_extensions;" - - echo "\nVerifying PostGIS installation:" - PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "SELECT PostGIS_Version();" + PGPASSWORD=postgres psql -h localhost -U postgres -d postgres_doctrine_test -c "CREATE SCHEMA IF NOT EXISTS test; SELECT PostGIS_Version();" - name: Run integration test suite run: | diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml index 1d56c7d7..73dcf4c1 100644 --- a/.github/workflows/unit-tests.yml +++ b/.github/workflows/unit-tests.yml @@ -41,16 +41,16 @@ jobs: name: "PHP ${{ matrix.php }} + Doctrine ORM ${{ matrix.doctrine-orm }} + Doctrine Lexer ${{ matrix.doctrine-lexer }}" strategy: - fail-fast: false + fail-fast: ${{ github.event_name == 'pull_request' }} matrix: - php: ['8.1', '8.2', '8.3', '8.4'] + php: ['8.1', '8.2', '8.3', '8.4', '8.5'] doctrine-lexer: ['2.1', '3.0', 'latest'] doctrine-orm: ['2.14', '2.18', '3.0', 'latest'] include: - php: '8.1' doctrine-orm: '2.14' doctrine-lexer: '1.2' - - php: '8.4' # Run coverage report only based on the latest dependencies + - php: '8.5' # Run coverage report only based on the latest dependencies doctrine-lexer: 'latest' doctrine-orm: 'latest' calculate-code-coverage: true @@ -71,11 +71,16 @@ jobs: extensions: ctype, json, mbstring tools: composer + - name: Get composer cache directory + id: composer-cache-dir + run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT + - name: Cache Composer packages - id: composer-cache uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830 # v4 with: - path: vendor + path: | + ${{ steps.composer-cache-dir.outputs.dir }} + vendor key: ${{ runner.os }}-php-${{ matrix.php }}-orm-${{ matrix.doctrine-orm }}-lexer-${{ matrix.doctrine-lexer }}-${{ hashFiles('**/composer.lock') }} restore-keys: | ${{ runner.os }}-php-${{ matrix.php }}-orm-${{ matrix.doctrine-orm }}-lexer-${{ matrix.doctrine-lexer }}- diff --git a/ci/php-cs-fixer/config.php b/ci/php-cs-fixer/config.php index 59dc9edf..ddbe3247 100644 --- a/ci/php-cs-fixer/config.php +++ b/ci/php-cs-fixer/config.php @@ -18,7 +18,7 @@ ->setRules( [ '@PSR2' => true, - '@PHP71Migration' => true, + '@PHP7x1Migration' => true, '@DoctrineAnnotation' => true, '@PhpCsFixer' => true, 'align_multiline_comment' => false, diff --git a/composer.json b/composer.json index a7d5a4e3..8792d975 100644 --- a/composer.json +++ b/composer.json @@ -37,7 +37,7 @@ }, "require": { - "php": "^8.1", + "php": "^8.1 <8.6", "ext-ctype": "*", "ext-json": "*", "ext-mbstring": "*", @@ -57,7 +57,7 @@ "symfony/cache": "^6.4||^7.0" }, "suggest": { - "php": "^8.3", + "php": "^8.4", "doctrine/orm": "~2.14||~3.0" }, diff --git a/docs/CONTRIBUTING.md b/docs/CONTRIBUTING.md index f301a692..8d64f2b3 100644 --- a/docs/CONTRIBUTING.md +++ b/docs/CONTRIBUTING.md @@ -128,8 +128,8 @@ Using local-only plaintext secrets here is acceptable. For example, this file: - Install [Harlequin](https://harlequin.sh/) database TUI. -- Set PHP version to 8.4. -- Change PostgreSQL related environment variables. +- Set PHP version to 8.5. +- Change PostgreSQL-related environment variables. ```nix # devenv.local.nix @@ -139,7 +139,7 @@ For example, this file: packages = with pkgs; [ harlequin ]; # https://devenv.sh/languages/ - languages.php.version = "8.4"; + languages.php.version = "8.5"; # https://devenv.sh/basics/ env = { diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php index e8eef5e0..fa4779cf 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/BaseIntegerArray.php @@ -44,8 +44,7 @@ private function throwIfInvalidArrayItemForDatabase(mixed $item): void throw InvalidIntegerArrayItemForDatabaseException::doesNotMatchRegex($item); } - $doesNotFitIntoPHPInteger = $stringValue !== (string) (int) $stringValue; - if ($doesNotFitIntoPHPInteger) { + if (!$this->fitsInPHPInteger($stringValue)) { throw InvalidIntegerArrayItemForDatabaseException::isOutOfRange($item); } @@ -75,8 +74,7 @@ public function transformArrayItemForPHP(mixed $item): ?int throw InvalidIntegerArrayItemForPHPException::forValueThatIsNotAValidPHPInteger($item, static::TYPE_NAME); } - $doesNotFitIntoPHPInteger = $stringValue !== (string) (int) $stringValue; - if ($doesNotFitIntoPHPInteger) { + if (!$this->fitsInPHPInteger($stringValue)) { throw InvalidIntegerArrayItemForPHPException::forValueOutOfRangeInPHP($item, static::TYPE_NAME); } @@ -88,4 +86,9 @@ public function transformArrayItemForPHP(mixed $item): ?int return $integerValue; } + + private function fitsInPHPInteger(string $value): bool + { + return \filter_var($value, \FILTER_VALIDATE_INT) !== false; + } } diff --git a/src/MartinGeorgiev/Doctrine/DBAL/Types/SpatialDataArray.php b/src/MartinGeorgiev/Doctrine/DBAL/Types/SpatialDataArray.php index da8bf615..9b0275d3 100644 --- a/src/MartinGeorgiev/Doctrine/DBAL/Types/SpatialDataArray.php +++ b/src/MartinGeorgiev/Doctrine/DBAL/Types/SpatialDataArray.php @@ -200,7 +200,7 @@ private function parseUnquotedWktArray(string $content): array $wktItems[] = $currentWktItem; } - return \array_map('trim', $wktItems); + return \array_map(trim(...), $wktItems); } public function isValidArrayItemForDatabase(mixed $item): bool diff --git a/src/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformer.php b/src/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformer.php index caa540e5..9aa4831b 100644 --- a/src/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformer.php +++ b/src/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformer.php @@ -30,7 +30,7 @@ public static function transformToPostgresTextArray(array $phpArray): string return self::POSTGRESQL_EMPTY_ARRAY; } - if (\array_filter($phpArray, 'is_array')) { + if (\array_filter($phpArray, is_array(...))) { throw InvalidArrayFormatException::multiDimensionalArrayNotSupported(); } diff --git a/tests/Unit/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformerTest.php b/tests/Unit/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformerTest.php index d3371d12..6ad90acb 100644 --- a/tests/Unit/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformerTest.php +++ b/tests/Unit/MartinGeorgiev/Utils/PHPArrayToPostgresValueTransformerTest.php @@ -260,6 +260,5 @@ public function can_transform_array_with_gd_resource(): void $resource = \imagecreatetruecolor(1, 1); $result = PHPArrayToPostgresValueTransformer::transformToPostgresTextArray([$resource]); $this->assertStringContainsString('GdImage', $result); - \imagedestroy($resource); } }