diff --git a/.gitattributes b/.gitattributes index 3196ce1..3e9a887 100644 --- a/.gitattributes +++ b/.gitattributes @@ -14,11 +14,11 @@ /.gitattributes export-ignore /.gitignore export-ignore /.php-cs-fixer.dist.php export-ignore -/.scrutinizer.yml export-ignore -/.travis.yml export-ignore +/box.json.dist export-ignore /phpcs.xml.dist export-ignore /phpstan.neon.dist export-ignore /phpunit.xml.dist export-ignore +/sonar-project.properties export-ignore # Do not count these files on github code language /tests/_files/** linguist-detectable=false diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd3a0da..f0cd750 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -10,7 +10,6 @@ on: # Actions # shivammathur/setup-php@v2 https://github.com/marketplace/actions/setup-php-action -# sudo-bot/action-scrutinizer@latest https://github.com/marketplace/actions/action-scrutinizer jobs: @@ -99,25 +98,14 @@ jobs: runs-on: "ubuntu-latest" strategy: matrix: - php-version: ['7.3', '7.4', '8.0', '8.1', '8.2', '8.3', '8.4'] + php-version: ['8.1', '8.2', '8.3', '8.4'] steps: - name: Checkout uses: actions/checkout@v4 - with: - fetch-depth: 0 # required for sudo-bot/action-scrutinizer - name: Install poppler-utils run: | sudo apt-get update -y -qq sudo apt-get install -y -qq poppler-utils - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-version }} - extensions: soap, gd - coverage: xdebug - tools: composer:v2 - env: - fail-fast: true - name: Install SAT XML resources shell: bash run: | @@ -129,6 +117,15 @@ jobs: else echo tests/_files/external-resources already exists fi + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php-version }} + extensions: soap, gd + coverage: none + tools: composer:v2 + env: + fail-fast: true - name: Get composer cache directory id: composer-cache run: echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT @@ -141,10 +138,4 @@ jobs: - name: Install project dependencies run: composer upgrade --no-interaction --no-progress --prefer-dist - name: Tests (phpunit) - run: vendor/bin/phpunit --testdox --verbose --coverage-clover=build/coverage-clover.xml - - name: Upload code coverage to scrutinizer - if: ${{ !env.ACT }} # do not run if using nektos/act - uses: sudo-bot/action-scrutinizer@latest - with: - cli-args: "--format=php-clover build/coverage-clover.xml" - continue-on-error: true + run: vendor/bin/phpunit --testdox diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 56a4531..07e5b1a 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -21,7 +21,7 @@ jobs: - name: "Setup PHP" uses: shivammathur/setup-php@v2 with: - php-version: '7.3' # use minimal version + php-version: '8.1' # use minimal version extensions: soap, gd coverage: none tools: composer:v2 diff --git a/.github/workflows/sonarqube-cloud.yml b/.github/workflows/sonarqube-cloud.yml new file mode 100644 index 0000000..beefcc7 --- /dev/null +++ b/.github/workflows/sonarqube-cloud.yml @@ -0,0 +1,67 @@ +name: "SonarQube Cloud" +on: + # secrets are not passed to workflows that are triggered by a pull request from a fork. + # see https://docs.github.com/en/actions/reference/encrypted-secrets + workflow_dispatch: + push: + branches: [ "master" ] + +# Actions +# shivammathur/setup-php@v2 https://github.com/marketplace/actions/setup-php-action +# SonarSource/sonarqube-scan-action@v6 https://github.com/marketplace/actions/official-sonarqube-scan + +jobs: + + sonarqube-cloud: + name: SonarCloud Scan and Report + runs-on: "ubuntu-latest" + steps: + - name: Check SONAR_TOKEN secret + run: | + if [ -z "${{ secrets.SONAR_TOKEN }}" ]; then + echo "::warning ::SONAR_TOKEN non set" + exit 1 + fi + - name: Checkout + uses: actions/checkout@v4 + - name: Unshallow clone to provide blame information + run: git fetch --unshallow + - name: Install poppler-utils + run: | + sudo apt-get update -y -qq + sudo apt-get install -y -qq poppler-utils + - name: Install SAT XML resources + shell: bash + run: | + rm -r -f tests/_files/external-resources + git clone --depth 1 https://github.com/phpcfdi/resources-sat-xml resources-sat-xml-cloned + mv resources-sat-xml-cloned/resources tests/_files/external-resources + rm -r -f resources-sat-xml-cloned + - name: Setup PHP + uses: shivammathur/setup-php@v2 + with: + php-version: '8.4' + extensions: soap, gd + 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 + with: + path: ${{ steps.composer-cache.outputs.dir }} + key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.json') }} + restore-keys: ${{ runner.os }}-composer- + - name: Install project dependencies + run: composer upgrade --no-interaction --no-progress --prefer-dist + - name: Create code coverage + run: vendor/bin/phpunit --testdox --coverage-xml=build/coverage --coverage-clover=build/coverage/clover.xml --log-junit=build/coverage/junit.xml + - name: Prepare SonarCloud Code Coverage Files + run: | + 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@v6 + env: + SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 3688dd7..5e93f6b 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -15,32 +15,32 @@ ->setRules([ '@PSR12' => true, '@PSR12:risky' => true, - '@PHP7x1Migration:risky' => true, - '@PHP7x3Migration' => true, + '@PHP8x1Migration' => true, + '@PHP8x0Migration:risky' => true, // basic 'statement_indentation' => false, // invalid indentation // symfony + 'array_indentation' => true, 'class_attributes_separation' => true, 'whitespace_after_comma_in_array' => true, 'no_empty_statement' => true, 'no_extra_blank_lines' => true, 'type_declaration_spaces' => true, - 'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['arrays', 'arguments']], - 'new_with_parentheses' => true, - 'no_blank_lines_after_class_opening' => true, + 'trailing_comma_in_multiline' => ['after_heredoc' => true, 'elements' => ['array_destructuring', 'arrays', 'match', 'arguments', 'parameters']], 'no_blank_lines_after_phpdoc' => true, 'object_operator_without_whitespace' => true, 'binary_operator_spaces' => true, 'phpdoc_scalar' => true, 'no_trailing_comma_in_singleline' => true, 'single_quote' => true, - 'blank_lines_before_namespace' => true, 'no_singleline_whitespace_before_semicolons' => true, 'no_unused_imports' => true, 'yoda_style' => ['equal' => true, 'identical' => true, 'less_and_greater' => null], 'standardize_not_equals' => true, 'concat_space' => ['spacing' => 'one'], 'linebreak_after_opening_tag' => true, + 'fully_qualified_strict_types' => true, + 'global_namespace_import' => ['import_classes' => true], // symfony:risky 'no_alias_functions' => true, 'self_accessor' => true, diff --git a/.scrutinizer.yml b/.scrutinizer.yml deleted file mode 100644 index 7b8c5f9..0000000 --- a/.scrutinizer.yml +++ /dev/null @@ -1,23 +0,0 @@ -filter: - excluded_paths: - - 'tests/' - - 'vendor/' - -# see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/ -build: - dependencies: - before: - - php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');" - - php composer-setup.php --install-dir=$HOME/bin --filename=composer - - php -r "unlink('composer-setup.php');" - - $HOME/bin/composer --version - override: - - composer update --no-interaction - nodes: - php: - tests: - override: - - php-scrutinizer-run --enable-security-analysis - -tools: - external_code_coverage: true diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2e7fa6b..cb0554f 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -109,7 +109,7 @@ tools/phpcbf --colors -sp tools/composer-normalize normalize --dry-run tools/php-cs-fixer fix --dry-run --verbose tools/phpcs --colors -sp -vendor/bin/phpunit --testdox --verbose --stop-on-failure +vendor/bin/phpunit --testdox --stop-on-failure tools/phpstan analyse --no-progress ``` diff --git a/README.md b/README.md index bd8735c..bc2562e 100644 --- a/README.md +++ b/README.md @@ -2,12 +2,16 @@ [![Source Code][badge-source]][source] [![Packagist PHP Version Support][badge-php-version]][php-version] +[![Discord][badge-discord]][discord] [![Latest Version][badge-release]][release] [![Software License][badge-license]][license] [![Build Status][badge-build]][build] -[![Scrutinizer][badge-quality]][quality] -[![Coverage Status][badge-coverage]][coverage] +[![Reliability][badge-reliability]][reliability] +[![Maintainability][badge-maintainability]][maintainability] +[![Code Coverage][badge-coverage]][coverage] +[![Violations][badge-violations]][violations] [![Total Downloads][badge-downloads]][downloads] +[![Docker Downloads][badge-docker]][docker] > Create a generic PDF file from a CFDI 3.3 & 4.0 @@ -116,18 +120,26 @@ and licensed for use under the MIT License (MIT). Please see [LICENSE][] for mor [source]: https://github.com/phpcfdi/cfditopdf [php-version]: https://packagist.org/packages/phpcfdi/cfditopdf +[discord]: https://discord.gg/aFGYXvX [release]: https://github.com/phpcfdi/cfditopdf/releases [license]: https://github.com/phpcfdi/cfditopdf/blob/master/LICENSE [build]: https://github.com/phpcfdi/cfditopdf/actions/workflows/build.yml?query=branch:master -[quality]: https://scrutinizer-ci.com/g/phpcfdi/cfditopdf/ -[coverage]: https://scrutinizer-ci.com/g/phpcfdi/cfditopdf/code-structure/master/code-coverage/src +[reliability]:https://sonarcloud.io/component_measures?id=phpcfdi_cfditopdf&metric=Reliability +[maintainability]: https://sonarcloud.io/component_measures?id=phpcfdi_cfditopdf&metric=Maintainability +[coverage]: https://sonarcloud.io/component_measures?id=phpcfdi_cfditopdf&metric=Coverage +[violations]: https://sonarcloud.io/project/issues?id=phpcfdi_cfditopdf&resolved=false [downloads]: https://packagist.org/packages/phpcfdi/cfditopdf - -[badge-source]: https://img.shields.io/badge/source-phpcfdi/cfditopdf-blue?style=flat-square -[badge-php-version]: https://img.shields.io/packagist/php-v/phpcfdi/cfditopdf?style=flat-square -[badge-release]: https://img.shields.io/github/release/phpcfdi/cfditopdf?style=flat-square -[badge-license]: https://img.shields.io/github/license/phpcfdi/cfditopdf?style=flat-square -[badge-build]: https://img.shields.io/github/actions/workflow/status/phpcfdi/cfditopdf/build.yml?branch=master&style=flat-square -[badge-quality]: https://img.shields.io/scrutinizer/g/phpcfdi/cfditopdf/master?style=flat-square -[badge-coverage]: https://img.shields.io/scrutinizer/coverage/g/phpcfdi/cfditopdf/master?style=flat-square -[badge-downloads]: https://img.shields.io/packagist/dt/phpcfdi/cfditopdf?style=flat-square +[docker]: https://hub.docker.com/r/phpcfdi/cfditopdf + +[badge-source]: https://img.shields.io/badge/source-phpcfdi/cfditopdf-blue?logo=github +[badge-discord]: https://img.shields.io/discord/459860554090283019?logo=discord +[badge-php-version]: https://img.shields.io/packagist/php-v/phpcfdi/cfditopdf?logo=php +[badge-release]: https://img.shields.io/github/release/phpcfdi/cfditopdf?logo=git +[badge-license]: https://img.shields.io/github/license/phpcfdi/cfditopdf?logo=open-source-initiative +[badge-build]: https://img.shields.io/github/actions/workflow/status/phpcfdi/cfditopdf/build.yml?branch=master&logo=github-actions +[badge-reliability]: https://sonarcloud.io/api/project_badges/measure?project=phpcfdi_cfditopdf&metric=reliability_rating +[badge-maintainability]: https://sonarcloud.io/api/project_badges/measure?project=phpcfdi_cfditopdf&metric=sqale_rating +[badge-coverage]: https://img.shields.io/sonar/coverage/phpcfdi_cfditopdf/master?logo=sonarqubecloud&server=https%3A%2F%2Fsonarcloud.io +[badge-violations]: https://img.shields.io/sonar/violations/phpcfdi_cfditopdf/master?format=long&logo=sonarqubecloud&server=https%3A%2F%2Fsonarcloud.io +[badge-downloads]: https://img.shields.io/packagist/dt/phpcfdi/cfditopdf?logo=packagist +[badge-docker]: https://img.shields.io/docker/pulls/phpcfdi/cfditopdf?logo=docker diff --git a/composer.json b/composer.json index b9225d7..6b74583 100644 --- a/composer.json +++ b/composer.json @@ -22,14 +22,14 @@ "source": "https://github.com/phpcfdi/cfditopdf" }, "require": { - "php": ">=7.3", - "eclipxe/cfdiutils": "^2.31 || ^3.0", + "php": ">=8.1", + "eclipxe/cfdiutils": "^3.0", "league/plates": "^3.5", "phpcfdi/cfdi-cleaner": "^1.3.3", "spipu/html2pdf": "^5.2.8" }, "require-dev": { - "phpunit/phpunit": "^9.5" + "phpunit/phpunit": "^10.5" }, "autoload": { "psr-4": { @@ -79,7 +79,7 @@ ], "dev:test": [ "@dev:check-style", - "@php vendor/bin/phpunit --testdox --verbose --stop-on-failure", + "@php vendor/bin/phpunit --testdox --stop-on-failure", "@php tools/phpstan analyse --no-progress" ] }, diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index 515bb2c..a890fab 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,10 +1,25 @@ # `phpcfdi/cfditopdf` Changelog -## Version 0.4.4 2024-11-08 +## Version 0.5.0 2025-11-10 + +This version remove the compatibility with PHP 7.3, PHP 7.4 and PHP 8.0. +PHP minimal version is 8.1. +PHPUnit now runs using version 10.5. + +In the generic template, the variables `$pagos` & `$pago` has been renamed to `$pagos10` & `$pago10`. + +Other changes: + +- Code cleaning: Thanks to *PHPStan*, *rector/rector* and *PHPStorm*. +- Removed Scrutinizer-CI integration. Thanks for everything. +- Add SonarQube Cloud integration. +- Use common PhpCfdi badges and code standards. + +## Version 0.4.4 2025-11-08 - Add Docker Hub public image. Thanks to `@dreglad` for the inspiration. -## Version 0.4.3 2024-11-08 +## Version 0.4.3 2025-11-08 - Fix compatibility with PHP 8.4. - Allow dependence of `eclipxe/cfdiutils` to match versions `^2.31` and `^3.0`. diff --git a/docs/TODO.md b/docs/TODO.md index cbf4861..5649645 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -4,17 +4,19 @@ Intro: Al completar una tarea pasarla de *Planeada* a *Finalizada*. Escribir fec ## Planeadas -- Revisar que esté solucionado para desactivar "permitir fallos" - en PHP 7.4 porque `spipu/html2pdf` tiene un bug. -- Cambiar a PHP 7.2 o mayor. -- Al cambiar de versión de PHP, actualizar los métodos que retornan void a que explícitamente lo hangan. -- Modificar `NodeInterface` para cuando `eclipxe/cfdiutils` ya lo incluya por sí mismo. - Catálogos para expresar las claves. - Impresión genérica de complementos. - Crear nuevos métodos para generar el archivo PDF. ## Finalizadas +### En versión 0.5.0 + +- Se elimina la compatibilidad con PHP 7.3, PHP 7.4 y PHP 8.0. +- Al cambiar de versión de PHP, actualizar los métodos que retornan void a que explícitamente lo hangan. +- El fallo que se presentaba en [`spipu/html2pdf`](https://github.com/spipu/html2pdf/issues/530) ya no existe. +- Modificar `NodeInterface` para cuando `eclipxe/cfdiutils` ya lo incluya por sí mismo. + ### En versión 0.3.2 o anteriores - Otros nodos de los conceptos. diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 4df4e01..dacbb1d 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,17 +1,22 @@ - + + - tests + tests - + + - src + src - + diff --git a/sonar-project.properties b/sonar-project.properties new file mode 100644 index 0000000..7558159 --- /dev/null +++ b/sonar-project.properties @@ -0,0 +1,10 @@ +sonar.organization=phpcfdi +sonar.projectKey=phpcfdi_cfditopdf +sonar.sourceEncoding=UTF-8 +sonar.language=php +sonar.sources=src +sonar.tests=tests +sonar.test.exclusions=tests/_files/**/* +sonar.working.directory=build/.scannerwork +sonar.php.tests.reportPath=build/sonar-junit.xml +sonar.php.coverage.reportPaths=build/sonar-coverage.xml \ No newline at end of file diff --git a/src/Builders/BuilderInterface.php b/src/Builders/BuilderInterface.php index 5916ba0..0472ff7 100644 --- a/src/Builders/BuilderInterface.php +++ b/src/Builders/BuilderInterface.php @@ -11,10 +11,6 @@ interface BuilderInterface /** * Transform CfdiData contents to a PDF file * and store its contents on $destination - * - * @param CfdiData $data - * @param string $destination - * @return void */ public function build(CfdiData $data, string $destination): void; } diff --git a/src/Builders/Html2PdfBuilder.php b/src/Builders/Html2PdfBuilder.php index 1fef243..f427940 100644 --- a/src/Builders/Html2PdfBuilder.php +++ b/src/Builders/Html2PdfBuilder.php @@ -12,14 +12,9 @@ class Html2PdfBuilder implements BuilderInterface { - /** @var HtmlTranslators\HtmlTranslatorInterface */ - private $htmlTranslator; + private HtmlTranslatorInterface $htmlTranslator; - /** - * Html2PdfBuilder constructor. - * - * @param HtmlTranslatorInterface|null $htmlTranslator If NULL will use a generic translator - */ + /** @param HtmlTranslatorInterface|null $htmlTranslator If NULL will use a generic translator */ public function __construct(?HtmlTranslatorInterface $htmlTranslator = null) { if (null === $htmlTranslator) { @@ -38,15 +33,11 @@ public function build(CfdiData $data, string $destination): void /** * Transforms CfdiData to Pdf string - * - * @param CfdiData $data - * @return string */ public function buildPdf(CfdiData $data): string { $html = $this->convertNodeToHtml($data); - $output = $this->convertHtmlToPdf($html); - return $output; + return $this->convertHtmlToPdf($html); } public function convertHtmlToPdf(string $html): string @@ -55,8 +46,7 @@ public function convertHtmlToPdf(string $html): string try { $html2Pdf = new Html2Pdf('P', 'Letter', 'es', true, 'UTF-8', [10, 10, 10, 10]); $html2Pdf->writeHTML($html); - $output = $html2Pdf->output('', 'S'); - return $output; + return $html2Pdf->output('', 'S'); } catch (Html2PdfException $exception) { /** @codeCoverageIgnore don't know how to invoke this exception on Html2Pdf */ throw new RuntimeException('Unable to convert CFDI', 0, $exception); diff --git a/src/Builders/HtmlTranslators/HtmlTranslatorInterface.php b/src/Builders/HtmlTranslators/HtmlTranslatorInterface.php index 2e23194..4ae0645 100644 --- a/src/Builders/HtmlTranslators/HtmlTranslatorInterface.php +++ b/src/Builders/HtmlTranslators/HtmlTranslatorInterface.php @@ -10,9 +10,6 @@ interface HtmlTranslatorInterface { /** * Transform CfdiData contents to HTML content - * - * @param CfdiData $cfdiData - * @return string */ public function translate(CfdiData $cfdiData): string; } diff --git a/src/Builders/HtmlTranslators/PlatesHtmlTranslator.php b/src/Builders/HtmlTranslators/PlatesHtmlTranslator.php index bc1dd76..239f828 100644 --- a/src/Builders/HtmlTranslators/PlatesHtmlTranslator.php +++ b/src/Builders/HtmlTranslators/PlatesHtmlTranslator.php @@ -9,22 +9,10 @@ class PlatesHtmlTranslator implements HtmlTranslatorInterface { - /** @var string */ - private $directory; - - /** @var string */ - private $template; - - /** - * PlatesHtmlTranslator constructor. - * - * @param string $directory - * @param string $template - */ - public function __construct(string $directory, string $template) - { - $this->directory = $directory; - $this->template = $template; + public function __construct( + private readonly string $directory, + private readonly string $template, + ) { } public function translate(CfdiData $cfdiData): string diff --git a/src/CfdiData.php b/src/CfdiData.php index e41977b..16dc38a 100644 --- a/src/CfdiData.php +++ b/src/CfdiData.php @@ -9,81 +9,50 @@ class CfdiData { - /** @var NodeInterface */ - private $comprobante; + private NodeInterface $emisor; - /** @var NodeInterface */ - private $emisor; + private NodeInterface $receptor; - /** @var NodeInterface */ - private $receptor; + private NodeInterface $timbreFiscalDigital; - /** @var NodeInterface */ - private $timbreFiscalDigital; - - /** @var string */ - private $qrUrl; - - /** @var string */ - private $tfdSourceString; - - /** - * CfdiData constructor. - * - * @param NodeInterface $comprobante - * @param string $qrUrl - * @param string $tfdSourceString - */ - public function __construct(NodeInterface $comprobante, string $qrUrl, string $tfdSourceString) - { - $emisor = $comprobante->searchNode('cfdi:Emisor'); + public function __construct( + private readonly NodeInterface $comprobante, + private readonly string $qrUrl, + private readonly string $tfdSourceString, + ) { + $emisor = $this->comprobante->searchNode('cfdi:Emisor'); if (null === $emisor) { throw new RuntimeException('El CFDI no contiene nodo emisor'); } - $receptor = $comprobante->searchNode('cfdi:Receptor'); + $receptor = $this->comprobante->searchNode('cfdi:Receptor'); if (null === $receptor) { throw new RuntimeException('El CFDI no contiene nodo receptor'); } - $timbreFiscalDigital = $comprobante->searchNode('cfdi:Complemento', 'tfd:TimbreFiscalDigital'); + $timbreFiscalDigital = $this->comprobante->searchNode('cfdi:Complemento', 'tfd:TimbreFiscalDigital'); if (null === $timbreFiscalDigital) { throw new RuntimeException('El CFDI no contiene complemento de timbre fiscal digital'); } - $this->comprobante = $comprobante; $this->emisor = $emisor; $this->receptor = $receptor; $this->timbreFiscalDigital = $timbreFiscalDigital; - $this->qrUrl = $qrUrl; - $this->tfdSourceString = $tfdSourceString; } - /** - * @return NodeInterface - */ public function comprobante(): NodeInterface { return $this->comprobante; } - /** - * @return NodeInterface - */ public function emisor(): NodeInterface { return $this->emisor; } - /** - * @return NodeInterface - */ public function receptor(): NodeInterface { return $this->receptor; } - /** - * @return NodeInterface - */ public function timbreFiscalDigital(): NodeInterface { return $this->timbreFiscalDigital; diff --git a/src/CfdiDataBuilder.php b/src/CfdiDataBuilder.php index ea43507..c16df3b 100644 --- a/src/CfdiDataBuilder.php +++ b/src/CfdiDataBuilder.php @@ -17,11 +17,9 @@ class CfdiDataBuilder { use CastToStringTrait; - /** @var XmlResolver */ - private $xmlResolver; + private XmlResolver $xmlResolver; - /** @var XsltBuilderInterface */ - private $xsltBuilder; + private XsltBuilderInterface $xsltBuilder; public function __construct() { @@ -51,10 +49,6 @@ public function xsltBuilder(): XsltBuilderInterface return $this->xsltBuilder; } - /** - * @param NodeInterface $comprobante - * @return CfdiData - */ public function build(NodeInterface $comprobante): CfdiData { return new CfdiData( @@ -64,10 +58,6 @@ public function build(NodeInterface $comprobante): CfdiData ); } - /** - * @param NodeInterface $comprobante - * @return string - */ public function createTfdSourceString(NodeInterface $comprobante): string { $tfd = $comprobante->searchNode('cfdi:Complemento', 'tfd:TimbreFiscalDigital'); @@ -81,10 +71,6 @@ public function createTfdSourceString(NodeInterface $comprobante): string ); } - /** - * @param NodeInterface $comprobante - * @return string - */ public function createQrUrl(NodeInterface $comprobante): string { $parameters = new RequestParameters( diff --git a/src/Converter.php b/src/Converter.php index 8e56dcc..6920712 100644 --- a/src/Converter.php +++ b/src/Converter.php @@ -11,19 +11,10 @@ class Converter { - /** @var BuilderInterface */ - private $builder; - - public function __construct(BuilderInterface $builder) + public function __construct(private readonly BuilderInterface $builder) { - $this->builder = $builder; } - /** - * @param CfdiData $cfdiData - * @param string $destination - * @return void - */ public function createPdfAs(CfdiData $cfdiData, string $destination): void { $this->builder->build($cfdiData, $destination); diff --git a/src/Internal/CastToStringTrait.php b/src/Internal/CastToStringTrait.php index 202c726..733f7f7 100644 --- a/src/Internal/CastToStringTrait.php +++ b/src/Internal/CastToStringTrait.php @@ -11,8 +11,7 @@ */ trait CastToStringTrait { - /** @param mixed $value */ - private function strval($value): string + private function strval(mixed $value): string { if (is_string($value)) { return $value; diff --git a/src/Script/ConvertOptions.php b/src/Script/ConvertOptions.php index 76142b1..fc2fcf5 100644 --- a/src/Script/ConvertOptions.php +++ b/src/Script/ConvertOptions.php @@ -8,47 +8,21 @@ class ConvertOptions { - /** @var string */ - private $resolverLocation; - - /** @var string */ - private $fontsDirectory; - - /** @var bool */ - private $doCleanInput; - - /** @var string */ - private $inputFile; - - /** @var string */ - private $outputFile; - - /** @var bool */ - private $askForHelp; - - /** @var bool */ - private $askForVersion; + private readonly string $outputFile; public function __construct( - string $resolverLocation, - string $fontsDirectory, - bool $doCleanInput, - string $inputFile, + private readonly string $resolverLocation, + private readonly string $fontsDirectory, + private readonly bool $doCleanInput, + private readonly string $inputFile, string $outputFile, - bool $askForHelp, - bool $askForVersion + private readonly bool $askForHelp, + private readonly bool $askForVersion, ) { - if ('' === $outputFile && '' !== $inputFile) { - $outputFile = (string) preg_replace('/\.xml$/', '', $inputFile) . '.pdf'; + if ('' === $outputFile && '' !== $this->inputFile) { + $outputFile = preg_replace('/\.xml$/', '', $this->inputFile) . '.pdf'; } - - $this->resolverLocation = $resolverLocation; - $this->fontsDirectory = $fontsDirectory; - $this->doCleanInput = $doCleanInput; - $this->inputFile = $inputFile; $this->outputFile = $outputFile; - $this->askForHelp = $askForHelp; - $this->askForVersion = $askForVersion; } public function askForHelp(): bool @@ -88,8 +62,6 @@ public function fontsDirectory(): string /** * @param string[] $arguments - * - * @return self */ public static function createFromArguments(array $arguments): self { @@ -118,7 +90,7 @@ public static function createFromArguments(array $arguments): self } if (in_array($argument, ['-l', '--resource-location'], true)) { $i = $i + 1; - if (! ($i < $count)) { + if ($i >= $count) { throw new RuntimeException('The resource location parameter does not contains an argument'); } $resolverLocation = $arguments[$i]; @@ -126,7 +98,7 @@ public static function createFromArguments(array $arguments): self } if (in_array($argument, ['-f', '--fonts-dir'], true)) { $i = $i + 1; - if (! ($i < $count)) { + if ($i >= $count) { throw new RuntimeException('The fonts directory parameter does not contains an argument'); } $fontsDirectory = $arguments[$i]; diff --git a/src/Script/ConvertScript.php b/src/Script/ConvertScript.php index 8b2be65..2d5febb 100644 --- a/src/Script/ConvertScript.php +++ b/src/Script/ConvertScript.php @@ -18,10 +18,6 @@ class ConvertScript { - /** - * @param ConvertOptions $options - * @return void - */ public function run(ConvertOptions $options): void { $source = $this->openSource($options->inputFile(), $options->doCleanInput()); @@ -100,7 +96,7 @@ public function defaultConverter(): Converter private function executionIsFromPhar(): bool { - return 'phar://' === substr(__FILE__, 0, 7); + return str_starts_with(__FILE__, 'phar://'); } private function extractFontsToTemporaryFolder(): string @@ -144,10 +140,6 @@ private function recursiveRemove(string $directory): void rmdir($directory); } - /** - * @param string $directory - * @return Generator - */ private function readDirectory(string $directory): Generator { $directoryIterator = new DirectoryIterator($directory); diff --git a/templates/generic.php b/templates/generic.php index 7dd02a0..1a810d9 100644 --- a/templates/generic.php +++ b/templates/generic.php @@ -1,15 +1,11 @@ comprobante(); $emisor = $cfdiData->emisor(); @@ -22,8 +18,8 @@ $informacionGlobal = $comprobante->searchNode('cfdi:InformacionGlobal'); $conceptoCounter = 0; $conceptoCount = $conceptos->count(); -if (! isset($catalogos) || ! ($catalogos instanceof \PhpCfdi\CfdiToPdf\Catalogs\CatalogsInterface)) { - $catalogos = new \PhpCfdi\CfdiToPdf\Catalogs\StaticCatalogs(); +if (! isset($catalogos) || ! ($catalogos instanceof PhpCfdi\CfdiToPdf\Catalogs\CatalogsInterface)) { + $catalogos = new PhpCfdi\CfdiToPdf\Catalogs\StaticCatalogs(); } ?>