diff --git a/.gitattributes b/.gitattributes index 1285aca..9d84905 100644 --- a/.gitattributes +++ b/.gitattributes @@ -8,6 +8,7 @@ # Do not put this files on a distribution package /.github/ export-ignore +/.phive/ export-ignore /build/ export-ignore /tests/ export-ignore /.gitattributes export-ignore diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index daf8faf..eb55556 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -18,28 +18,28 @@ jobs: runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.5' coverage: none tools: composer-normalize env: fail-fast: true - name: Composer normalize - run: composer-normalize + run: composer-normalize --dry-run phpcs: - name: Code style (phpcs) + name: Coding standards (phpcs) runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.5' coverage: none tools: cs2pr, phpcs env: @@ -48,15 +48,15 @@ jobs: run: phpcs -q --report=checkstyle | cs2pr php-cs-fixer: - name: Code style (php-cs-fixer) + name: Coding standards (php-cs-fixer) runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.3' + php-version: '8.5' coverage: none tools: cs2pr, php-cs-fixer env: @@ -69,11 +69,11 @@ jobs: runs-on: "ubuntu-latest" steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.5' coverage: none tools: composer:v2, phpstan env: @@ -82,7 +82,7 @@ jobs: id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -92,15 +92,15 @@ jobs: - name: PHPStan run: phpstan analyse --no-progress --verbose - tests: + phpunit: name: Tests on PHP ${{ matrix.php-version }} runs-on: "ubuntu-latest" strategy: matrix: - php-version: ['8.1', '8.2', '8.3', '8.4'] + php-version: ['8.1', '8.2', '8.3', '8.4', '8.5'] steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Setup PHP uses: shivammathur/setup-php@v2 with: @@ -113,7 +113,7 @@ jobs: id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} diff --git a/.github/workflows/sonarqube-cloud.yml b/.github/workflows/sonarqube-cloud.yml index 5f098d8..142d99c 100644 --- a/.github/workflows/sonarqube-cloud.yml +++ b/.github/workflows/sonarqube-cloud.yml @@ -6,7 +6,7 @@ on: # Actions # shivammathur/setup-php@v2 https://github.com/marketplace/actions/setup-php-action -# SonarSource/sonarqube-scan-action@v5 https://github.com/marketplace/actions/official-sonarqube-scan +# SonarSource/sonarqube-scan-action@v8 https://github.com/marketplace/actions/official-sonarqube-scan jobs: @@ -21,20 +21,20 @@ jobs: exit 1 fi - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v7 - name: Unshallow clone to provide blame information run: git fetch --unshallow - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '8.4' + php-version: '8.5' coverage: xdebug tools: composer:v2 - name: Get composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - name: Cache dependencies - uses: actions/cache@v4 + uses: actions/cache@v6 with: path: ${{ steps.composer-cache.outputs.dir }} key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} @@ -48,6 +48,6 @@ jobs: sed 's#'$GITHUB_WORKSPACE'#/github/workspace#g' build/coverage/junit.xml > build/sonar-junit.xml sed 's#'$GITHUB_WORKSPACE'#/github/workspace#g' build/coverage/clover.xml > build/sonar-coverage.xml - name: SonarCloud Scan - uses: SonarSource/sonarqube-scan-action@v5 + uses: SonarSource/sonarqube-scan-action@v8 env: SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.phive/phars.xml b/.phive/phars.xml index ff3bfe0..d6398d7 100644 --- a/.phive/phars.xml +++ b/.phive/phars.xml @@ -1,8 +1,8 @@ - - - - - + + + + + diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 856ebb3..eecfabf 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -15,8 +15,8 @@ ->setRules([ '@PSR12' => true, '@PSR12:risky' => true, - '@PHP81Migration' => true, - '@PHP80Migration:risky' => true, + '@PHP8x1Migration' => true, + '@PHP8x0Migration:risky' => true, // symfony 'array_indentation' => true, 'class_attributes_separation' => true, diff --git a/LICENSE b/LICENSE index 5b8acbe..4278bd5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2019 - 2025 PhpCfdi https://www.phpcfdi.com/ +Copyright (c) 2019 - 2026 PhpCfdi https://www.phpcfdi.com/ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/composer.json b/composer.json index d6f209e..a29ac75 100644 --- a/composer.json +++ b/composer.json @@ -26,7 +26,7 @@ "php": ">=8.1", "ext-mbstring": "*", "ext-openssl": "*", - "eclipxe/enum": "^0.2.7" + "eclipxe/enum": "^0.2.8" }, "require-dev": { "ext-json": "*", @@ -66,7 +66,7 @@ "dev:fix-style": [ "@php tools/composer-normalize normalize", "@php tools/php-cs-fixer fix --verbose", - "@php tools/phpcbf --colors -sp" + "@php tools/phpcbf --colors -sp || true" ], "dev:test": [ "@php vendor/bin/phpunit --testdox --stop-on-failure", diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 48061d3..c57e9d5 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -9,15 +9,36 @@ Usamos [Versionado Semántico 2.0.0](SEMVER.md) por lo que puedes usar esta libr Pueden aparecer cambios no liberados que se integran a la rama principal, pero no ameritan una nueva liberación de versión, aunque sí su incorporación en la rama principal de trabajo. Generalmente, se tratan de cambios en el desarrollo. -### Mantenimiento 2025-09-25 +## Listado de cambios + +### Versión 1.3.1 2026-10-23 + +- Se actualiza el año de la licencia a 2026. +- Se actualizó la dependencia `eclipxe/enum` a 0.2.8. +- Se garantiza la compatibilidad con PHP 8.5. +- Se excluye el directorio `.phive` del paquete Git. +- Se usa el tipo `OpenSSLAsymmetricKey` disponible desde PHP 8.0. +- Se solucionan pequeñas incidencias reportadas por la inspección de PHPStorm. + +En el entorno de desarrollo: + +- Se actualiza el código para corregir un falso positivo de PHPStan. +- Se actualizan las reglas deprecadas de `php-cs-fixer`. +- En los flujos de trabajo de GitHub: + - Se corrige el trabajo `composer-normalize` para que falle cuando es necesario. + - Se actualizan las versiones de las acciones. + - Se agrega PHP 8.5 a la matriz de pruebas. + - Se ejecutan los trabajos en PHP 8.5. + - Se renombra el trabajo `tests` a `phpunit`. +- Se actualizan las herramientas de desarrollo. + +#### Mantenimiento 2025-09-25 - Se actualizan las herramientas `phpcs` y `phpcbf` a la versión 4.0.0. - Se elimina la regla `Generic.Functions.CallTimePassByReference`. - Se moderniza la integración con SonarQube-Cloud. - Se actualiza `sonarqube-scan-action` a la versión 6. -## Listado de cambios - ### Versión 1.3.0 2025-04-12 - Se mejoran las declaraciones de tipos. diff --git a/src/Certificate.php b/src/Certificate.php index d1ea9b6..eec5e54 100644 --- a/src/Certificate.php +++ b/src/Certificate.php @@ -45,7 +45,8 @@ public function __construct(string $contents) $pem = static::convertDerToPem($contents); } - $parsed = openssl_x509_parse($pem, true); + /** @noinspection PhpRedundantOptionalArgumentInspection */ + $parsed = openssl_x509_parse($pem, short_names: true); if (false === $parsed) { throw new UnexpectedValueException('Cannot parse X509 certificate from contents'); } @@ -89,7 +90,9 @@ public function pem(): string public function pemAsOneLine(): string { - return implode('', preg_grep('/^((?!-).)*$/', explode(PHP_EOL, $this->pem())) ?: []); + /** @phpstan-var string[]|false $lines */ + $lines = preg_grep('/^((?!-).)*$/', explode(PHP_EOL, $this->pem())); + return implode('', $lines ?: []); } /** @@ -128,7 +131,7 @@ public function subject(): array public function subjectData(string $key): string { - return strval($this->subject()[$key] ?? ''); + return $this->subject()[$key] ?? ''; } public function hash(): string @@ -144,7 +147,7 @@ public function issuer(): array public function issuerData(string $string): string { - return strval($this->issuer()[$string] ?? ''); + return $this->issuer()[$string] ?? ''; } public function version(): string diff --git a/src/Internal/DataArrayTrait.php b/src/Internal/DataArrayTrait.php index b1a3e81..b6e450a 100644 --- a/src/Internal/DataArrayTrait.php +++ b/src/Internal/DataArrayTrait.php @@ -10,19 +10,16 @@ trait DataArrayTrait { /** @var array content of openssl_x509_parse or openssl_pkey_get_details */ - protected $dataArray; + protected array $dataArray; /** - * @param string|int|float|bool $default - * @return string|int|float|bool + * @param scalar $default + * @return scalar */ protected function extractScalar(string $key, $default) { $value = $this->dataArray[$key] ?? $default; - if (is_scalar($value)) { - return $value; - } - return $default; + return is_scalar($value) ? $value : $default; } protected function extractString(string $key): string diff --git a/src/Internal/LocalFileOpenTrait.php b/src/Internal/LocalFileOpenTrait.php index 0fb5d8c..3dbe159 100644 --- a/src/Internal/LocalFileOpenTrait.php +++ b/src/Internal/LocalFileOpenTrait.php @@ -31,7 +31,7 @@ private static function localFileOpen(string $filename): string } /** @noinspection PhpUsageOfSilenceOperatorInspection */ - $contents = @file_get_contents($path, false) ?: ''; + $contents = @file_get_contents($path) ?: ''; if ('' === $contents) { throw new RuntimeException('File content is empty'); } diff --git a/src/Internal/OpenSslKeyTypeEnum.php b/src/Internal/OpenSslKeyTypeEnum.php index e836332..6e43777 100644 --- a/src/Internal/OpenSslKeyTypeEnum.php +++ b/src/Internal/OpenSslKeyTypeEnum.php @@ -27,6 +27,7 @@ final class OpenSslKeyTypeEnum extends Enum * * @return array * @noinspection PhpMissingParentCallCommonInspection + * @noinspection PhpUnused */ protected static function overrideIndices(): array { diff --git a/src/PrivateKey.php b/src/PrivateKey.php index cae550c..54d47c4 100644 --- a/src/PrivateKey.php +++ b/src/PrivateKey.php @@ -111,12 +111,14 @@ function ($privateKey) use ($data, $algorithm): string { /** * This method id created to wrap and mock openssl_sign - * - * @param OpenSSLAsymmetricKey $privateKey * @internal */ - protected function openSslSign(string $data, ?string &$signature, $privateKey, int $algorithm): bool - { + protected function openSslSign( + string $data, + string|null &$signature, + OpenSSLAsymmetricKey $privateKey, + int $algorithm, + ): bool { return openssl_sign($data, $signature, $privateKey, $algorithm); // @phpstan-ignore parameterByRef.type } diff --git a/src/PublicKey.php b/src/PublicKey.php index 73226f8..865c5b1 100644 --- a/src/PublicKey.php +++ b/src/PublicKey.php @@ -33,8 +33,6 @@ public static function openFile(string $filename): self /** * Verify the signature of some data * - * - * * @throws RuntimeException when openssl report an error on verify */ public function verify(string $data, string $signature, int $algorithm = OPENSSL_ALGO_SHA256): bool @@ -52,12 +50,15 @@ function ($publicKey) use ($data, $signature, $algorithm): bool { } /** - * This method id created to wrap and mock openssl_verify - * - * @param OpenSSLAsymmetricKey $publicKey + * This method is created to wrap and mock openssl_verify + * @internal */ - protected function openSslVerify(string $data, string $signature, $publicKey, int $algorithm): int - { + protected function openSslVerify( + string $data, + string $signature, + OpenSSLAsymmetricKey $publicKey, + int $algorithm, + ): int { $verify = openssl_verify($data, $signature, $publicKey, $algorithm); if (false === $verify) { return -1; // @codeCoverageIgnore