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