From 07b72ceeb94322e2d51e7f5ff2999ecdebefddd2 Mon Sep 17 00:00:00 2001 From: Eric Sizemore Date: Fri, 7 Feb 2025 17:09:19 -0500 Subject: [PATCH] chore: bring repo more in line with my other repos --- .gitattributes | 31 +- .github/ISSUE_TEMPLATE/1-bug_report.yml | 58 ++ .github/ISSUE_TEMPLATE/2-feature_request.yml | 23 + .github/ISSUE_TEMPLATE/config.yml | 5 + .github/pull_request_template.md | 28 + .github/workflows/analysis.yml | 47 -- .github/workflows/continuous-integration.yml | 108 +++ .github/workflows/psalm.yml | 23 - .github/workflows/tests.yml | 61 -- .gitignore | 10 +- .php-cs-fixer.dist.php | 2 +- CHANGELOG.md | 47 +- CODE_OF_CONDUCT.md | 133 +++ CONTRIBUTING.md | 126 +++ LICENSE.md | 4 +- README.md | 162 ++-- backward-compatibility.md | 120 +++ composer.json | 57 +- composer.lock | 796 +++++++++++++++++- phpstan-baseline.neon | 33 +- psalm-baseline.xml | 23 + psalm.xml | 4 + rector.php | 41 + src/Api.php | 60 +- src/Country/Collection.php | 2 + .../NumverifyApiFailureException.php | 1 + src/PhoneNumber/Factory.php | 24 + src/PhoneNumber/InvalidPhoneNumber.php | 13 +- src/PhoneNumber/PhoneNumberInterface.php | 1 + src/PhoneNumber/ValidPhoneNumber.php | 63 +- tests/ApiCountryTest.php | 6 +- tests/ApiPhoneNumberTest.php | 2 +- tests/ApiTest.php | 12 +- tests/Country/CollectionTest.php | 6 +- tests/Country/CountryTest.php | 4 +- .../NumverifyApiFailureExceptionTest.php | 5 +- .../NumverifyApiResponseExceptionTest.php | 2 +- tests/PhoneNumber/InvalidPhoneNumberTest.php | 5 +- tests/PhoneNumber/ValidPhoneNumberTest.php | 7 +- 39 files changed, 1754 insertions(+), 401 deletions(-) create mode 100644 .github/ISSUE_TEMPLATE/1-bug_report.yml create mode 100644 .github/ISSUE_TEMPLATE/2-feature_request.yml create mode 100644 .github/ISSUE_TEMPLATE/config.yml create mode 100644 .github/pull_request_template.md delete mode 100644 .github/workflows/analysis.yml create mode 100644 .github/workflows/continuous-integration.yml delete mode 100644 .github/workflows/psalm.yml delete mode 100644 .github/workflows/tests.yml create mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.md create mode 100644 backward-compatibility.md create mode 100644 psalm-baseline.xml create mode 100644 rector.php diff --git a/.gitattributes b/.gitattributes index afaf767..28077e0 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,15 +1,24 @@ # Set the default behavior, in case people don't have core.autocrlf set. * text eol=lf +*.php text diff=php +*.md text diff=markdown # Ignore all test and documentation with "export-ignore". -/.github export-ignore -/.gitattributes export-ignore -/.gitignore export-ignore -/.scrutinizer.yml export-ignore -/.php-cs-fixer.dist.php export-ignore -/tests export-ignore -/composer.lock export-ignore -/phpstan.neon export-ignore -/phpunit.xml export-ignore -/renovate.json export-ignore -/psalm.xml export-ignore \ No newline at end of file +/.github export-ignore +/tests export-ignore +/.gitattributes export-ignore +/.gitignore export-ignore +/.php-cs-fixer.dist.php export-ignore +/.scrutinizer.yml export-ignore +/backward-compatibility.md export-ignore +/CHANGELOG.md export-ignore +/CODE_OF_CONDUCT.md export-ignore +/composer.lock export-ignore +/CONTRIBUTING.md export-ignore +/phpstan.neon export-ignore +/phpstan-baseline.neon export-ignore +/phpunit.xml export-ignore +/psalm.xml export-ignore +/psalm-baseline.xml export-ignore +/rector.php export-ignore +/renovate.json export-ignore diff --git a/.github/ISSUE_TEMPLATE/1-bug_report.yml b/.github/ISSUE_TEMPLATE/1-bug_report.yml new file mode 100644 index 0000000..06f4568 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/1-bug_report.yml @@ -0,0 +1,58 @@ +name: Bug Report +description: Existing feature does not behave as expected. +labels: [ "bug", "unverified" ] +body: + - type: markdown + attributes: + value: | + Before reporting a bug, make sure Numverify is up-to-date and the problem is/was not reported already. + - type: textarea + id: problem-description + attributes: + label: Problem description + description: Please describe the problem you have encountered + validations: + required: true + - type: textarea + id: minimal-reproducer + attributes: + label: Minimal Reproducer + description: | + Please provide a minimal code snippet that should be run to reproduce the problem. + + If relevant, provide the expected output, the actual output and/or the error that occurred, if any. + + Please use markdown syntax for each code snippet. + validations: + required: true + - type: input + id: version + attributes: + label: Library Version + description: Which version of Numverify is being run? (in X.Y.Z format) + validations: + required: true + - type: input + id: php-version + attributes: + label: PHP version + description: Which PHP version is Numverify being run on? + validations: + required: true + - type: dropdown + id: run-method + attributes: + label: How do you run Numverify? + multiple: false + options: + - Composer package + - Manual installation + validations: + required: true + - type: checkboxes + id: terms + attributes: + label: Contribution Checks + options: + - label: I have verified whether this problem has already been reported. + required: false diff --git a/.github/ISSUE_TEMPLATE/2-feature_request.yml b/.github/ISSUE_TEMPLATE/2-feature_request.yml new file mode 100644 index 0000000..ec5cc76 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/2-feature_request.yml @@ -0,0 +1,23 @@ +name: Feature Request +description: I have a suggestion for a new feature (and possibly want to implement it). +labels: [ "enhancement", "unverified" ] +body: + - type: markdown + attributes: + value: | + > [!IMPORTANT] + > Before requesting a new feature, make sure your version of Numverify is up-to-date. + - type: textarea + id: feature-request + attributes: + label: Feature Request + description: Please describe the feature you would like to see implemented. + validations: + required: true + - type: checkboxes + id: terms + attributes: + label: Contribution Checks + options: + - label: I have verified whether this feature request was already discussed. + required: false diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000..2221ecb --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,5 @@ +blank_issues_enabled: false +contact_links: + - name: Support question? + url: https://github.com/ericsizemore/numverify-api-client-php/discussions/categories/q-a + about: If you have any questions about configuring or using Numverify, please open a new Q&A discussion. diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md new file mode 100644 index 0000000..a673fbc --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,28 @@ +# Pull Request + + +## Proposed Changes + + +## Readiness Checklist + +### Author/Contributor + +- [ ] You have read [CONTRIBUTING](https://github.com/ericsizemore/numverify-api-client-php/blob/master/CONTRIBUTING.md). +- [ ] If documentation is needed for this change, has that been included in this pull request? +- [ ] run `composer run-script phpunit` and ensure you have test coverage for the lines you are introducing. +- [ ] run `composer run-script phpstan` and fix any issues that you have introduced. +- [ ] run `composer run-script psalm` and fix any issues that you have introduced. +- [ ] run `composer run-script phpcs:check` and fix any issues that you have introduced. + +### Reviewer + +- [ ] Label as either `fix`, `documentation`, or `enhancement`. +- [ ] Additionally label as `verified` or `unverified`. diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml deleted file mode 100644 index ce3d962..0000000 --- a/.github/workflows/analysis.yml +++ /dev/null @@ -1,47 +0,0 @@ -name: PHPStan - -on: - workflow_dispatch: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -# Is it overkill to run PHPStan using different PHP versions? Probably :) -jobs: - phpstan: - name: PHPStan Static Analysis ${{ matrix.php }} - runs-on: ubuntu-latest - strategy: - matrix: - php: [ '8.2', '8.3' ] - steps: - - uses: actions/checkout@v4 - - - name: Install PHP ${{ matrix.php }} - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php }} - extensions: mbstring - tools: composer:v2 - - - name: Validate composer.json and composer.lock - run: composer validate --strict - - - name: Cache Composer packages - id: composer-cache - run: | - echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v4 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - run: composer install --prefer-dist --no-progress - - - name: Run PHPStan - run: composer run-script phpstan diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 0000000..2ac19a5 --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,108 @@ +name: "Continuous Integration" + +on: + workflow_dispatch: + push: + branches: [ master ] + pull_request: + branches: [ master ] + +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + COMPOSER_ROOT_VERSION: "3.99.99" + +jobs: + phpstan: + name: "PHPStan Static Analysis ${{ matrix.php }}" + runs-on: ubuntu-latest + strategy: + matrix: + php: [ '8.2', '8.3', '8.4' ] + steps: + - uses: actions/checkout@v4 + + - name: "Install PHP ${{ matrix.php }}" + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php }} + extensions: mbstring + + - name: "Validate composer.json and composer.lock" + run: composer validate --strict + + - name: "Setup Composer, install dependencies" + uses: ramsey/composer-install@v3 + with: + composer-options: "--prefer-dist --optimize-autoloader" + require-lock-file: "true" + + - name: "Run PHPStan" + run: composer run-script phpstan + + psalm: + name: "Psalm" + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: "Psalm Analysis" + uses: docker://vimeo/psalm-github-actions:latest + with: + args: --shepherd + composer_require_dev: true + security_analysis: true + report_file: results.sarif + + - name: "Upload Security Analysis results to GitHub" + uses: github/codeql-action/upload-sarif@v3 + with: + sarif_file: results.sarif + + unit-test: + name: "Run Unit Tests ${{ matrix.php }}" + runs-on: ubuntu-latest + strategy: + matrix: + php: [ '8.2', '8.3', '8.4' ] + steps: + - uses: actions/checkout@v4 + with: + fetch-depth: 10 + + - name: "Install PHP ${{ matrix.php }}" + uses: shivammathur/setup-php@master + with: + php-version: ${{ matrix.php }} + extensions: mbstring, + coverage: xdebug + + - name: "Validate composer.json and composer.lock" + run: composer validate --strict + + - name: "Setup Composer, install dependencies" + uses: ramsey/composer-install@v3 + with: + composer-options: "--prefer-dist --optimize-autoloader" + require-lock-file: "true" + + - name: "Run test suite" + run: composer run-script phpunit + + - name: "Coverage check" + run: composer run-script code-coverage + + - name: "Upload coverage reports to Scrutinizer" + uses: sudo-bot/action-scrutinizer@latest + with: + cli-args: "--format=php-clover build/logs/clover.xml" + + - name: "Upload coverage reports to Codecov" + uses: codecov/codecov-action@v5.3.1 + with: + token: ${{ secrets.CODECOV_TOKEN }} + slug: ericsizemore/numverify-api-client-php diff --git a/.github/workflows/psalm.yml b/.github/workflows/psalm.yml deleted file mode 100644 index 1acb314..0000000 --- a/.github/workflows/psalm.yml +++ /dev/null @@ -1,23 +0,0 @@ -name: Psalm Static analysis - -on: [push, pull_request] - -jobs: - psalm: - name: Psalm - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Psalm - uses: docker://vimeo/psalm-github-actions:latest - with: - args: --shepherd - composer_require_dev: true - security_analysis: true - report_file: results.sarif - - - name: Upload Security Analysis results to GitHub - uses: github/codeql-action/upload-sarif@v3 - with: - sarif_file: results.sarif \ No newline at end of file diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml deleted file mode 100644 index 4fe7d93..0000000 --- a/.github/workflows/tests.yml +++ /dev/null @@ -1,61 +0,0 @@ -name: Tests - -on: - push: - branches: [ master ] - pull_request: - branches: [ master ] - -jobs: - test: - name: Run Unit Tests ${{ matrix.php }} - runs-on: ubuntu-latest - strategy: - matrix: - php: [ '8.2', '8.3'] - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 10 - - - name: Install PHP ${{ matrix.php }} - uses: shivammathur/setup-php@master - with: - php-version: ${{ matrix.php }} - extensions: mbstring, - coverage: xdebug, - tools: composer:v2 - - - name: Validate composer.json and composer.lock - run: composer validate --strict - - - name: Cache Composer packages - id: composer-cache - run: | - echo "dir=$(composer config cache-files-dir)" >> $GITHUB_OUTPUT - - - uses: actions/cache@v4 - with: - path: ${{ steps.composer-cache.outputs.dir }} - key: ${{ runner.os }}-composer-${{ hashFiles('**/composer.lock') }} - restore-keys: | - ${{ runner.os }}-composer- - - - name: Install dependencies - run: composer install --prefer-dist --no-progress - - - name: Run test suite - run: composer run-script test - - - name: Coverage check - run: composer run-script coverage - - - uses: sudo-bot/action-scrutinizer@latest - with: - cli-args: "--format=php-clover build/logs/clover.xml" - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v5.3.1 - with: - token: ${{ secrets.CODECOV_TOKEN }} - slug: ericsizemore/numverify-api-client-php diff --git a/.gitignore b/.gitignore index d2dffb7..cd17090 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,3 @@ -.idea/ -vendor/ -build/ -.php-cs-fixer.cache -*.iws -out/ -.idea_modules/ \ No newline at end of file +/vendor/ +/build/ +*.cache diff --git a/.php-cs-fixer.dist.php b/.php-cs-fixer.dist.php index 2a2d853..23a43a9 100644 --- a/.php-cs-fixer.dist.php +++ b/.php-cs-fixer.dist.php @@ -146,7 +146,7 @@ 'phpdoc_to_comment' => false, 'phpdoc_trim' => true, 'phpdoc_trim_consecutive_blank_line_separation' => true, - 'phpdoc_types_order' => true, + 'phpdoc_types_order' => ['sort_algorithm' => 'none'], 'phpdoc_var_annotation_correct_order' => true, 'phpdoc_var_without_name' => true, 'php_unit_data_provider_return_type' => true, diff --git a/CHANGELOG.md b/CHANGELOG.md index e42e43b..32ed478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,13 +1,38 @@ -# CHANGELOG -A not so exhaustive list of changes for each release. +# Changelog -For a more detailed listing of changes between each version, -you can use the following url: https://github.com/ericsizemore/api/compare/v3.0.0...v3.0.1. +All notable changes to this project will be documented in this file. -Simply replace the version numbers depending on which set of changes you wish to see. +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). -## 3.0.1 (2024-03-13) +## [Unreleased] + +### Added + + * Added `rector/rector` dev-dependency + * Added issue templates, and a pull request template. + * Added new docs/files: + * backward-compatibility.md + * CODE_OF_CONDUCT.md + * CONTRIBUTING.md + +### Changed + + * Changed locally called `private static` methods to non static methods. + * Changed test classes to `final` + * Merged workflows into `.github/workflows/continuous-integration.yml` + * Updated `CHANGELOG.md` to be compatibile with the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format. + * Updated `README.md` + +### Removed + +* Removed the following workflows from `.github/workflows` + * `analysis.yml` + * `psalm.yml` + * `tests.yml` + +## [3.0.1] - 2024-03-13 ### Added @@ -32,10 +57,10 @@ Simply replace the version numbers depending on which set of changes you wish to ### TODO - * At the moment the cache middleware for Guzzle is using files. For 3.1, perhaps I could look into supporting Redis, Memcached, etc. + * At the moment, the cache middleware for Guzzle is using files. For 3.1, perhaps I could look into supporting Redis, Memcached, etc. -## 3.0.0 (2024-03-10) +## [3.0.0] - 2024-03-10 Forked from [`markrogoyski/numverify-api-client-php`](https://github.com/markrogoyski/numverify-api-client-php) v2.2.0. @@ -79,4 +104,8 @@ Forked from [`markrogoyski/numverify-api-client-php`](https://github.com/markrog ### TODO/WIP - * Documentation improvements. \ No newline at end of file + * Documentation improvements. + +[unreleased]: https://github.com/ericsizemore/numverify-api-client-php/tree/master +[3.0.1]: https://github.com/ericsizemore/numverify-api-client-php/releases/tag/v3.0.1 +[3.0.0]: https://github.com/ericsizemore/numverify-api-client-php/releases/tag/v3.0.0 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..20bcc4f --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,133 @@ + +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, caste, color, religion, or sexual +identity and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the overall + community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or advances of + any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email address, + without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official email address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +[INSERT CONTACT METHOD]. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series of +actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or permanent +ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within the +community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.1, available at +[https://www.contributor-covenant.org/version/2/1/code_of_conduct.html][v2.1]. + +Community Impact Guidelines were inspired by +[Mozilla's code of conduct enforcement ladder][Mozilla CoC]. + +For answers to common questions about this code of conduct, see the FAQ at +[https://www.contributor-covenant.org/faq][FAQ]. Translations are available at +[https://www.contributor-covenant.org/translations][translations]. + +[homepage]: https://www.contributor-covenant.org +[v2.1]: https://www.contributor-covenant.org/version/2/1/code_of_conduct.html +[Mozilla CoC]: https://github.com/mozilla/diversity +[FAQ]: https://www.contributor-covenant.org/faq +[translations]: https://www.contributor-covenant.org/translations diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..5113f4c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,126 @@ +# Contributing to this library + +#### Important Note + +The contributing guidelines for this project are heavily inspired by, and borrowed from, the [contributing guidelines](https://github.com/sebastianbergmann/phpunit/main/.github/CONTRIBUTING.md) of PHPUnit. + +## Welcome! + +This project accepts contributions of code and documentation from the community. +These contributions can be made in the form of Issues or [Pull Requests](http://help.github.com/send-pull-requests/) on the [library's repository](https://github.com/ericsizemore/numverify-api-client-php). + +Here are some examples how you can contribute: + +* [Report a bug](https://github.com/ericsizemore/numverify-api-client-php/issues/new?labels=bug,unverified&template=1-bug_report.yml) +* [Propose a new feature](https://github.com/ericsizemore/numverify-api-client-php/issues/new?labels=enhancement,unverified&template=2-feature_request.yml) +* [Send a pull request](https://github.com/ericsizemore/numverify-api-client-php/pulls) + +I look forward to your contributions! + +## Code of Conduct + +Please note that this project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By participating in this project you agree to abide by its terms. + +## Any contributions you make will be under the MIT License + +When you submit code changes, your submissions are understood to be under the same [MIT License](https://github.com/ericsizemore/numverify-api-client-php/blob/master/LICENSE.md) that covers the project. By contributing to this project, you agree that your contributions will be licensed under its MIT License. + +## Workflow for Pull Requests + +- Fork the repository. +- Create your branch from `master` if you plan to implement new functionality or change existing code significantly. + - Create your branch from the oldest branch that is affected by the bug if you plan to fix a bug. + - Pull requests for bug fixes must be made for the oldest branch that is [supported](https://github.com/ericsizemore/numverify-api-client-php/blob/master/SECURITY.md). +- Implement your change and add tests for it. +- Ensure the test suite passes. +- Ensure the code complies with our coding guidelines (see below). +- Create the pull request. + +Please make sure you have [set up your username and email address](https://git-scm.com/book/en/v2/Getting-Started-First-Time-Git-Setup) for use with Git. +You are encouraged to [sign your Git commits with your GPG key](https://docs.github.com/en/github/authenticating-to-github/signing-commits). + +[Backwards compatibility](https://github.com/ericsizemore/numverify-api-client-php/blob/master/backward-compatibility.md) breaks in this project are being kept to an absolute minimum. Please take this into account when proposing changes. + +## Guidelines + +Before we look into how, here are the guidelines. If your Pull Requests fail to pass these guidelines it will be declined, and you will need to re-submit when you’ve made the changes. This might sound a bit tough, but it is required for me to maintain quality of the code-base. + +### Git Checkout + +The following commands can be used to perform the initial checkout of this library: + +```bash +$ git clone https://github.com/ericsizemore/numverify-api-client-php.git +$ cd numverify-api-client-php +``` + +Install dependencies using [Composer](https://getcomposer.org/): + +```bash +$ composer install +``` + +### PHP Style and Coding Guidelines + +Please ensure all new contributions match the [PSR-12](https://www.php-fig.org/psr/psr-12/) coding style guide. + +This project attempts to adhere to PHPStan level 9 with strict rules and bleeding edge. Please ensure any contributions do as well. + +This project comes with configuration files for various tools that are used within the development workflow of this project. Please understand that I will not accept a pull request when its changes violate this project's coding guidelines. + +#### Coverage Check + +No configuration is needed for [PHPUnit Coverage Check](https://github.com/ericsizemore/phpunit-coverage-check). You can use PHPUnit Coverage Check to check the coverage percentage in the codebase after your changes. I try to stick to 100% line coverage. + +```bash +$ composer run-script code-coverage +``` + +#### PHPStan + +The configuration file can be found at `phpstan.neon`, in the repository, for [PHPStan](https://phpstan.org/). You can use PHPStan to perform static analysis: + +```bash +$ composer run-script phpstan +``` + +#### Psalm + +The configuration file can be found at `psalm.xml`, in the repository, for [Psalm](https://psalm.dev/). You can use Psalm to perform static analysis (with a focus on type checking): + +```bash +$ composer run-script psalm +``` + +#### PHP-CS-Fixer + +The configuration file can be found at `.php-cs-fixer.dist.php`, in the repository, for [PHP-CS-Fixer](https://github.com/PHP-CS-Fixer/PHP-CS-Fixer). You can use PHP-CS-Fixer to (re)format your source code for compliance with this project's coding guidelines: + +```bash +$ composer run-script phpcs:fix +``` + +#### Unit tests (via PHPUnit) + +The configuration file can be found at `phpunit.xml`, in the repository, for [PHPUnit](https://phpunit.de/index.html). You can run the test suite with: + +```bash +$ composer run-script phpunit +``` + +### Documentation + +If you change anything that requires a change to documentation then you will need to add it. New methods, parameters, changing default values, adding constants, etc. are all things that will require a change to documentation. The change-log must also be updated for every change. Also, PHPDoc blocks must be maintained. + +#### Documenting functions/variables (PHPDoc) + +Please ensure all new contributions adhere to: + +* [PSR-5 PHPDoc](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md) +* [PSR-19 PHPDoc Tags](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc-tags.md) + +when documenting new functions, or changing existing documentation. + +#### Changelog Entries + +If adding new changelog entries, please ensure they adhere to the [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) format as much as possible. diff --git a/LICENSE.md b/LICENSE.md index f8aa9c9..21b9e64 100644 --- a/LICENSE.md +++ b/LICENSE.md @@ -3,7 +3,7 @@ The MIT License (MIT) The MIT License (MIT) -Copyright (c) 2024 Eric Sizemore +Copyright (c) 2024-2025 Eric Sizemore Copyright (c) 2018-2021 Mark Rogoyski @@ -23,4 +23,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. \ No newline at end of file +THE SOFTWARE. diff --git a/README.md b/README.md index fd8f39d..f25b033 100644 --- a/README.md +++ b/README.md @@ -6,17 +6,14 @@ Numverify phone number validation and country API client library for PHP. [![Build Status](https://scrutinizer-ci.com/g/ericsizemore/numverify-api-client-php/badges/build.png?b=master)](https://scrutinizer-ci.com/g/ericsizemore/numverify-api-client-php/build-status/master) [![Code Coverage](https://scrutinizer-ci.com/g/ericsizemore/numverify-api-client-php/badges/coverage.png?b=master)](https://scrutinizer-ci.com/g/ericsizemore/numverify-api-client-php/?branch=master) [![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/ericsizemore/numverify-api-client-php/badges/quality-score.png?b=master)](https://scrutinizer-ci.com/g/ericsizemore/numverify-api-client-php/?branch=master) -[![Tests](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/tests.yml/badge.svg)](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/tests.yml) -[![PHPStan](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/analysis.yml/badge.svg)](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/analysis.yml) -[![Psalm Static analysis](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/psalm.yml/badge.svg?branch=master)](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/psalm.yml) - +[![Continuous Integration](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/ericsizemore/numverify-api-client-php/actions/workflows/continuous-integration.yml) [![Type Coverage](https://shepherd.dev/github/ericsizemore/numverify-api-client-php/coverage.svg)](https://shepherd.dev/github/ericsizemore/numverify-api-client-php) [![Psalm Level](https://shepherd.dev/github/ericsizemore/numverify-api-client-php/level.svg)](https://shepherd.dev/github/ericsizemore/numverify-api-client-php) [![Latest Stable Version](https://img.shields.io/packagist/v/esi/numverify-api-client-php.svg)](https://packagist.org/packages/esi/numverify-api-client-php) [![Downloads per Month](https://img.shields.io/packagist/dm/esi/numverify-api-client-php.svg)](https://packagist.org/packages/esi/numverify-api-client-php) [![License](https://img.shields.io/packagist/l/esi/numverify-api-client-php.svg)](https://packagist.org/packages/esi/numverify-api-client-php) -This library is a fork of [`markrogoyski/numverify-api-client-php`](https://github.com/markrogoyski/numverify-api-client-php). See [Acknowledgements](#acknowledgements) for more information. +This library is a fork of [`markrogoyski/numverify-api-client-php`](https://github.com/markrogoyski/numverify-api-client-php). See [Credits](#credits) for more information. ## Features @@ -33,47 +30,22 @@ This library is a fork of [`markrogoyski/numverify-api-client-php`](https://gith Numverify API documentation: https://numverify.com/documentation -## Setup - -Add the library to your `composer.json` file in your project: - -```javascript -{ - "require": { - "esi/numverify-api-client-php": "3.*" - } -} -``` +## Installation -Use [composer](http://getcomposer.org) to install the library: +Compatible with PHP >= 8.2 and can be installed with [Composer](https://getcomposer.org). ```bash -$ php composer.phar install +$ composer require esi/numverify-api-client-php ``` -Composer will install Numverify API Client Library for PHP inside your vendor folder. Then you can add the following to your -.php files to the use library with Autoloading. - -```php -require_once __DIR__ . '/vendor/autoload.php'; -``` - -Alternatively, use composer on the command line to require and install Numverify API Client Library: - -``` -$ php composer.phar require esi/numverify-api-client-php:3.* -``` - -### Minimum Requirements - -* PHP 8.2 with `ext-json`. - ## Usage ### Create New API ```php +use Numverify\Api; + $accessKey = 'AccountAccessKeyGoesHere'; -$api = new \Numverify\Api($accessKey); +$api = new Api($accessKey); ``` ### Phone Number Validation API @@ -81,7 +53,7 @@ $api = new \Numverify\Api($accessKey); $phoneNumber = '14158586273'; $validatedPhoneNumber = $api->validatePhoneNumber($phoneNumber); -// Phone number information +// Phone number information. if ($validatedPhoneNumber->isValid()) { $number = $validatedPhoneNumber->getNumber(); // 14158586273 $localFormat = $validatedPhoneNumber->getLocalFormat(); // 4158586273 @@ -94,12 +66,12 @@ if ($validatedPhoneNumber->isValid()) { $lineType = $validatedPhoneNumber->getLineType(); // mobile } -// Use optional country code parameter for local (non-E.164) phone numbers +// Use optional country code parameter for local (non-E.164) phone numbers. $phoneNumber = '4158586273'; $countryCode = 'US'; $validatedPhoneNumber = $api->validatePhoneNumber($phoneNumber, $countryCode); -// PHP Interfaces +// PHP Interfaces. $stringRepresentation = (string) $validatedPhoneNumber; $jsonRepresentation = json_encode($validatedPhoneNumber); ``` @@ -108,11 +80,11 @@ $jsonRepresentation = json_encode($validatedPhoneNumber); ```php $countries = $api->getCountries(); -// Find countries (by country code or by name) +// Find countries (by country code or by name). $unitedStates = $countries->findByCountryCode('US'); $japan = $countries->findByCountryName('Japan'); -// Country information +// Country information. $usCountryCode = $unitedStates->getCountryCode(); // US $usCountryName = $unitedStates->getCountryName(); // United States $usDialingCode = $unitedStates->getDialingCode(); // +1 @@ -121,39 +93,39 @@ $japanCountryCode = $japan->getCountryCode(); // JP $japanCountryName = $japan->getCountryName(); // Japan $japanDialingCode = $japan->getDialingCode(); // +81 -// Country collection is iterable +// Country collection is iterable. foreach ($countries as $country) { $countryCode = $country->getCountryCode(); $countryName = $country->getCountryName(); $dialingCode = $country->getDialingCode(); } -// Country collection PHP interfaces +// Country collection PHP interfaces. $numberOfCountries = count($countries); $jsonRepresentation = json_encode($numberOfCountries); -// Country PHP interfaces +// Country PHP interfaces. $stringRepresentation = (string) $unitedStates; // US: United States (+1) $jsonRepresentation = json_encode($unitedStates); ``` ### Options -#### Signature of the Api constructor +#### Signature of the Api Constructor ```php /** * Api constructor. * - * Requires an access (or api) key. You can get one from Numverify: + * Requires an access key. You can get one from Numverify. * * @see https://numverify.com/product * * Note: If you are on their free plan, $useHttps = true will not work for you. * - * @param string $accessKey API access key. - * @param bool $useHttps (optional) Flag to determine if API calls should use http or https. - * @param ClientInterface|null $client (optional) Parameter to provide your own Guzzle client. - * @param array $options (optional) Array of options to pass to the Guzzle client. + * @param string $accessKey API access key. + * @param bool $useHttps (optional) Flag to determine if API calls should use http or https. + * @param null|ClientInterface $client (optional) Parameter to provide your own Guzzle client. + * @param array $options (optional) Array of options to pass to the Guzzle client. */ public function __construct( #[SensitiveParameter] @@ -164,46 +136,55 @@ $jsonRepresentation = json_encode($unitedStates); ); ``` -#### Construct API to use HTTPS for API calls +#### Construct API to use HTTPS for API Calls -Note: The Numverify api has different plan options when signing up for an access key. The 'free' plan can not use the secure (HTTPS) url for the API. +Note: The Numverify api has different plan options when signing up for an access key. The 'free' plan cannot use the secure (HTTPS) url for the API. ```php +use Numverify\Api; + $useHttps = true; -$api = new \Numverify\Api($accessKey, $useHttps); // Optional second parameter +$api = new Api($accessKey, $useHttps); // Optional second parameter ``` -#### Construct API to use a custom Guzzle client or options +#### Construct API to use a Custom Guzzle Client or Options Note: If creating and passing your own client to `Api`, it will completely ignore `$useHttps`. ```php -$client = new \GuzzleHttp\Client([ +use GuzzleHttp\Client; +use Numverify\Api; + +$client = new Client([ 'base_uri' => 'http://apilayer.net/api', - 'timeout => 10 + 'timeout' => 10 ]); -$api = new \Numverify\Api($accessKey, $useHttps, $client); +$api = new Api($accessKey, false, $client); ``` If you simply want to change some of Guzzle's default options, pass them along to the optional $options parameter instead. ```php -$api = new \Numverify\Api($accessKey, $useHttps, null, ['timeout => 10]); +use Numverify\Api; + +$api = new Api($accessKey, false, null, ['timeout' => 10]); // or -$api = new \Numverify\Api($accessKey, $useHttps, options: ['timeout => 10]); +$api = new Api($accessKey, false, options: ['timeout' => 10]); ``` -#### Construct API to use a cache +#### Construct API to use a Cache The Api constructor allows you to pass an optional `$options` parameter, typically used to pass Guzzle options on to the client. If you specify `cachePath` within `$options`, and it is a valid directory, the constructor will add the cache handler to Guzzle's handler stack. ```php -$api = new \Numverify\Api($accessKey, $useHttps, options: ['cachePath' => '/tmp']); +use Numverify\Api; + +$api = new Api($accessKey, false, options: ['cachePath' => '/tmp']); ``` ### Exceptions @@ -211,7 +192,7 @@ $api = new \Numverify\Api($accessKey, $useHttps, options: ['cachePath' => '/tmp' API failures throw a ```NumverifyApiFailureException``` ```php -// Numverify API server error +// Numverify API server error. try { $validatedPhoneNumber = $api->validatePhoneNumber($phoneNumber); } catch (\Numverify\Exception\NumverifyApiFailureException $e) { @@ -234,59 +215,38 @@ try { - PHP 8.2.0 or above. -### Submitting bugs and feature requests - -Bugs and feature requests are tracked on [GitHub](https://github.com/ericsizemore/numverify-api-client-php/issues) - -Issues are the quickest way to report a bug. If you find a bug or documentation error, please check the following first: - -* That there is not an Issue already open concerning the bug -* That the issue has not already been addressed (within closed Issues, for example) +### Credits -### Contributing +- Author: [Eric Sizemore](https://github.com/ericsizemore) +- Thanks to [all Contributors](https://github.com/ericsizemore/numverify-api-client-php/contributors). +- Special thanks to [JetBrains](https://www.jetbrains.com/?from=esi-numverify-api-client-php) for their Licenses for Open Source Development. -Contributions of code and documentation from the community is welcome. -These contributions can be made in the form of Issues or [Pull Requests](http://help.github.com/send-pull-requests/) on the [Numverify API for PHP repository](https://github.com/ericsizemore/numverify-api-client-php). +`numverify-api-client-php` is forked from [`markrogoyski/numverify-api-client-php`](https://github.com/markrogoyski/numverify-api-client-php) by [`Mark Rogoyski`](https://github.com/markrogoyski). -Numverify API Client for PHP is licensed under the MIT license. When submitting new features or patches to this library, you are giving permission to license those features or patches under the MIT license. +My thanks to them, and all their contributors. To view changes in this library in comparison to the original library, please see the [CHANGELOG.md](./CHANGELOG.md) file. -Numverify API Client for PHP tries to adhere to PHPStan level 9 with strict rules and bleeding edge. Please ensure any contributions do as well. +## Contributing -#### Guidelines +See [CONTRIBUTING](./CONTRIBUTING.md) for more information. -Before we look into how, here are the guidelines. If your Pull Requests fail to pass these guidelines it will be declined and you will need to re-submit when you’ve made the changes. This might sound a bit tough, but it is required for me to maintain quality of the code-base. +Bugs and feature requests are tracked on [GitHub](https://github.com/ericsizemore/numverify-api-client-php/issues). -#### PHP Style +### Contributor Covenant Code of Conduct -Please ensure all new contributions match the [PSR-12](https://www.php-fig.org/psr/psr-12/) coding style guide. The project is not fully PSR-12 compatible, yet; however, to ensure the easiest transition to the coding guidelines, I would like to go ahead and request that any contributions follow them. +See [CODE_OF_CONDUCT.md](./CODE_OF_CONDUCT.md) -#### Documentation +### Backward Compatibility Promise -If you change anything that requires a change to documentation then you will need to add it. New methods, parameters, changing default values, adding constants, etc are all things that will require a change to documentation. The change-log must also be updated for every change. Also PHPDoc blocks must be maintained. +See [backward-compatibility.md](./backward-compatibility.md) for more information on Backwards Compatibility. -##### Documenting functions/variables (PHPDoc) +### Changelog -Please ensure all new contributions adhere to: - -* [PSR-5 PHPDoc](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc.md) -* [PSR-19 PHPDoc Tags](https://github.com/php-fig/fig-standards/blob/master/proposed/phpdoc-tags.md) - -when documenting new functions, or changing existing documentation. - -#### Branching - -One thing at a time: A pull request should only contain one change. That does not mean only one commit, but one change - however many commits it took. The reason for this is that if you change X and Y but send a pull request for both at the same time, we might really want X but disagree with Y, meaning we cannot merge the request. Using the Git-Flow branching model you can create new branches for both of these features and send two requests. - -### Author - -Eric Sizemore - - +See the [CHANGELOG](./CHANGELOG.md) for more information on what has changed recently. ### License -Numverify API Client for PHP is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details - -### Acknowledgements +See the [LICENSE](./LICENSE.md) for more information on the license that applies to this project. -This library is a `fork` of the `markrogoyski/numverify-api-client-php`(https://github.com/markrogoyski/numverify-api-client-php) library by `Mark Rogoyski`(https://github.com/markrogoyski). +### Security -To see a list of changes in this library in comparison to the original library, please see the [CHANGELOG.md](CHANGELOG.md) file. +See [SECURITY](./SECURITY.md) for more information on the security disclosure process. diff --git a/backward-compatibility.md b/backward-compatibility.md new file mode 100644 index 0000000..8540fae --- /dev/null +++ b/backward-compatibility.md @@ -0,0 +1,120 @@ +# Backward Compatibility (BC) Promise + +I try to develop my libraries to be as backward compatible (BC) as possible. This file describes my backward compatibility promise, along with: + +* Changes that are (or are not) allowed in minor or patch versions. +* Exceptions to this promise. +* How deprecations are handled. +* Tags and branches in the Git repository. +* ...etc. + +Further restrictions (and/or allowances) might be added in the future. + +| **Document Information** | | +|:-------------------------|:-----------| +| **Effective Date** | 02/07/2025 | +| **Last Updated** | 02/07/2025 | +| **Version** | 1.0.0 | + +## Semantic Versioning + +This project follows [Semantic Versioning](https://semver.org/) (`..`). In general, this means that the version number is incremented based on the type of changes made: + +* Patch version for backward-compatible bug fixes. +* Minor version for backward-compatible additions. +* Major version for backward-incompatible changes. + +#### Major Version Changes + +Any backward-incompatible changes will only occur in a new major version. Users should expect to update their code to accommodate these changes. + +#### Minor Version Changes + +Minor versions may include new features and improvements but will maintain backward compatibility with previous minor versions within the same major release. + +#### Patch Version Changes + +Patch versions will only include backward-compatible bug fixes. Users can safely update without fear of breaking changes. + +## Public API Stability: + +* All public classes, interfaces, methods, and properties are subject to our backward compatibility promise. +* Any changes to the public API that are not backward-compatible will result in a new major version release. + +### Exceptions + +There are some exceptions which are not covered by the backward compatibility promise. + +#### Security fixes and Critical bug fixes + +Backward compatibility can be ignored in security bug fixes or critical bugs. In this case, all the incompatible changes are described in the [CHANGELOG](CHANGELOG.md). + +#### Internal Code + +* Classes, interfaces, properties and methods that are tagged with the @internal annotation. +* The classes located in the *\Tests\ namespace. + +They are meant for internal use only and should not be accessed by your own code. They are subject to change or removal even in minor or patch versions. + +#### Unreleased + +* Generally, any code found within a `*-dev*` branch is not covered by this backward compatibility promise. + * Normally, only major versions will be assigned their own `dev` branch. +* Unreleased versions will be tagged with `[Unreleased]` in the `CHANGELOG.md`. + +See [Branches](#branches) for more information. + +#### Named Arguments + +[Named arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments) are not covered by the backward compatibility (BC) promise. I may choose to rename method/function parameter names when necessary in order to improve the codebase. + +## Deprecations + +* Deprecated features will be clearly marked with @deprecated annotations or documented in the changelog. +* Deprecated features will continue to function without issues for at least two minor versions before being removed. +* Users are encouraged to migrate away from deprecated features to maintain compatibility with future releases. + +## Composer Dependencies: + +* I will strive to minimize direct dependencies on external libraries as much as possible. +* Any changes to dependencies that could impact users will be clearly documented in the changelog, with guidance on how to adapt. + +## Changelogs + +* I will strive to format the changelog to adhere to [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). +* Changelogs will clearly indicate whether a release contains backward-incompatible changes, deprecated features, or backward-compatible bug fixes. + +## Version Control + +### Tags + +Tags in this project's Git repository are immutable. I do not change published tags to point to a different revision, for example. + +In very rare cases I may delete a tag in order to remove a broken release. The new release that fixes what was broken will always have a different tag than the one that was removed. + +### Branches + +Branches in this project's Git repository are private implementation details. For example, I delete branches for versions of this library that are no longer supported. In general: + +* The `master` branch will contain the currently released major version (and `` or `` versions that fall under it). +* Previous major versions will be under a `.x` branch. +* `Next` or development code of a new major version will be under a `.x-dev` branch. + +For example, let's say the latest released version of this project is 3.0.0, the last major version is 2, and the next major version is 4. + +* The `master` branch will be all version 3 code, which includes: 3.0.1, 3.1.0, 3.2.0, etc. +* The previous major version, version 2, will be under `2.x` (which includes: 2.0.1, 2.1.0, 2.2.0, etc.). +* The `Next` or development code for a new major version, version 4, will be in `4.x-dev`. + * Once v4.0.0 is officially released, it will be merged into `master` and the `4.x-dev` branch will be deleted. + * Which then makes version 3 the previous major version, so it would have a new branch created for it: `3.x` + +## Updates + +I will keep the backward compatibility promise updated as this project evolves and new use cases emerge. The last updated date and version of this document under `Document Information` at the beginning of this file will be updated if any changes are made. + +## Acknowledgements + +This backward compatibility promise was highly inspired by, and borrows from, the BC promises of: + +* [PHPUnit](https://phpunit.de/backward-compatibility.html) +* [Symfony](https://symfony.com/doc/current/contributing/code/bc.html) diff --git a/composer.json b/composer.json index 87488c5..fc6d446 100644 --- a/composer.json +++ b/composer.json @@ -31,26 +31,39 @@ "issues": "https://github.com/ericsizemore/numverify-api-client-php/issues", "forum": "https://github.com/ericsizemore/numverify-api-client-php/discussions", "source": "https://github.com/ericsizemore/numverify-api-client-php/tree/master", + "docs": "https://github.com/ericsizemore/numverify-api-client-php", + "rss": "https://github.com/ericsizemore/numverify-api-client-php/releases.atom", "security": "https://github.com/ericsizemore/numverify-api-client-php/security/policy" }, + "funding": [ + { + "type": "custom", + "url": "https://ko-fi.com/ericsizemore" + }, + { + "type": "github", + "url": "https://github.com/ericsizemore" + } + ], "require": { "php": "^8.2 <8.5", "ext-json": "*", "guzzlehttp/guzzle": "^7.9", "kevinrob/guzzle-cache-middleware": "^6.0", - "symfony/cache": "^7.1" + "symfony/cache": "^7.2" }, "require-dev": { "esi/phpunit-coverage-check": "^2.0", - "friendsofphp/php-cs-fixer": "^3.65", + "friendsofphp/php-cs-fixer": "^3.68", "phpstan/extension-installer": "^1.4", - "phpstan/phpstan": "^2.0", + "phpstan/phpstan": "^2.1", "phpstan/phpstan-deprecation-rules": "^2.0", "phpstan/phpstan-phpunit": "^2.0", "phpstan/phpstan-strict-rules": "^2.0", - "phpunit/phpunit": "^11.5", + "phpunit/phpunit": "^11.5 || ^12.0", "psalm/plugin-phpunit": "^0.19.0", - "vimeo/psalm": "dev-master" + "rector/rector": "^2.0", + "vimeo/psalm": "^6.1" }, "replace": { "markrogoyski/numverify-api-client-php": "^2.1" @@ -78,19 +91,27 @@ } }, "scripts": { - "coverage": "vendor/bin/coverage-check build/logs/clover.xml 100", - "cs:check": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --dry-run --diff", - "cs:fix": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php", - "phpstan": "vendor/bin/phpstan analyse -c phpstan.neon", - "psalm": "vendor/bin/psalm -c psalm.xml --no-diff", - "static-analysis": [ - "@phpstan", - "@psalm" + "analyze": [ + "@clear-build", + "@composer validate", + "@phpunit", + "@code-coverage", + "@psalm:shepherd", + "@psalm:security", + "@phpstan" ], - "test": "phpunit", - "test:coverage": [ - "@test", - "@coverage" - ] + "clear-build": "rm -rf ./build/*", + "code-coverage": "vendor/bin/coverage-check build/logs/clover.xml 100", + "phpcs:check": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php --dry-run --diff", + "phpcs:fix": "vendor/bin/php-cs-fixer fix --config=.php-cs-fixer.dist.php", + "phpstan": "vendor/bin/phpstan analyse -c phpstan.neon -vvv", + "phpunit": "vendor/bin/phpunit", + "phpunit:migrate": "@phpunit --migrate-configuration", + "psalm": "vendor/bin/psalm -c psalm.xml --no-cache --no-diff --use-baseline=psalm-baseline.xml", + "psalm:baseline": "vendor/bin/psalm -c psalm.xml --no-cache --no-diff --set-baseline=psalm-baseline.xml", + "psalm:security": "vendor/bin/psalm -c psalm.xml --no-cache --no-diff --taint-analysis", + "psalm:shepherd": "@psalm --shepherd --stats", + "refactor:check": "@refactor:fix --dry-run", + "refactor:fix": "vendor/bin/rector process" } } diff --git a/composer.lock b/composer.lock index 1bd48e4..fd29916 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "0ca82858e8664b9c87aab091df954fe0", + "content-hash": "2765173c4e7a74d8cdd54fbd24a57c6a", "packages": [ { "name": "guzzlehttp/guzzle", @@ -1176,16 +1176,16 @@ "packages-dev": [ { "name": "amphp/amp", - "version": "v3.0.2", + "version": "v3.1.0", "source": { "type": "git", "url": "https://github.com/amphp/amp.git", - "reference": "138801fb68cfc9c329da8a7b39d01ce7291ee4b0" + "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/amp/zipball/138801fb68cfc9c329da8a7b39d01ce7291ee4b0", - "reference": "138801fb68cfc9c329da8a7b39d01ce7291ee4b0", + "url": "https://api.github.com/repos/amphp/amp/zipball/7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", + "reference": "7cf7fef3d667bfe4b2560bc87e67d5387a7bcde9", "shasum": "" }, "require": { @@ -1245,7 +1245,7 @@ ], "support": { "issues": "https://github.com/amphp/amp/issues", - "source": "https://github.com/amphp/amp/tree/v3.0.2" + "source": "https://github.com/amphp/amp/tree/v3.1.0" }, "funding": [ { @@ -1253,7 +1253,7 @@ "type": "github" } ], - "time": "2024-05-10T21:37:46+00:00" + "time": "2025-01-26T16:07:39+00:00" }, { "name": "amphp/byte-stream", @@ -1330,6 +1330,244 @@ ], "time": "2024-02-17T04:49:38+00:00" }, + { + "name": "amphp/cache", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/cache.git", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/cache/zipball/46912e387e6aa94933b61ea1ead9cf7540b7797c", + "reference": "46912e387e6aa94933b61ea1ead9cf7540b7797c", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/serialization": "^1", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Amp\\Cache\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + } + ], + "description": "A fiber-aware cache API based on Amp and Revolt.", + "homepage": "https://amphp.org/cache", + "support": { + "issues": "https://github.com/amphp/cache/issues", + "source": "https://github.com/amphp/cache/tree/v2.0.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-19T03:38:06+00:00" + }, + { + "name": "amphp/dns", + "version": "v2.4.0", + "source": { + "type": "git", + "url": "https://github.com/amphp/dns.git", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/dns/zipball/78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "reference": "78eb3db5fc69bf2fc0cb503c4fcba667bc223c71", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/process": "^2", + "daverandom/libdns": "^2.0.2", + "ext-filter": "*", + "ext-json": "*", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Dns\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Chris Wright", + "email": "addr@daverandom.com" + }, + { + "name": "Daniel Lowrey", + "email": "rdlowrey@php.net" + }, + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + } + ], + "description": "Async DNS resolution for Amp.", + "homepage": "https://github.com/amphp/dns", + "keywords": [ + "amp", + "amphp", + "async", + "client", + "dns", + "resolve" + ], + "support": { + "issues": "https://github.com/amphp/dns/issues", + "source": "https://github.com/amphp/dns/tree/v2.4.0" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-01-19T15:43:40+00:00" + }, + { + "name": "amphp/parallel", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/parallel.git", + "reference": "5113111de02796a782f5d90767455e7391cca190" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/parallel/zipball/5113111de02796a782f5d90767455e7391cca190", + "reference": "5113111de02796a782f5d90767455e7391cca190", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/cache": "^2", + "amphp/parser": "^1", + "amphp/pipeline": "^1", + "amphp/process": "^2", + "amphp/serialization": "^1", + "amphp/socket": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.18" + }, + "type": "library", + "autoload": { + "files": [ + "src/Context/functions.php", + "src/Context/Internal/functions.php", + "src/Ipc/functions.php", + "src/Worker/functions.php" + ], + "psr-4": { + "Amp\\Parallel\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + }, + { + "name": "Stephen Coakley", + "email": "me@stephencoakley.com" + } + ], + "description": "Parallel processing component for Amp.", + "homepage": "https://github.com/amphp/parallel", + "keywords": [ + "async", + "asynchronous", + "concurrent", + "multi-processing", + "multi-threading" + ], + "support": { + "issues": "https://github.com/amphp/parallel/issues", + "source": "https://github.com/amphp/parallel/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-12-21T01:56:09+00:00" + }, { "name": "amphp/parser", "version": "v1.1.1", @@ -1394,16 +1632,16 @@ }, { "name": "amphp/pipeline", - "version": "v1.2.1", + "version": "v1.2.2", "source": { "type": "git", "url": "https://github.com/amphp/pipeline.git", - "reference": "66c095673aa5b6e689e63b52d19e577459129ab3" + "reference": "97cbf289f4d8877acfe58dd90ed5a4370a43caa4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/amphp/pipeline/zipball/66c095673aa5b6e689e63b52d19e577459129ab3", - "reference": "66c095673aa5b6e689e63b52d19e577459129ab3", + "url": "https://api.github.com/repos/amphp/pipeline/zipball/97cbf289f4d8877acfe58dd90ed5a4370a43caa4", + "reference": "97cbf289f4d8877acfe58dd90ed5a4370a43caa4", "shasum": "" }, "require": { @@ -1449,7 +1687,75 @@ ], "support": { "issues": "https://github.com/amphp/pipeline/issues", - "source": "https://github.com/amphp/pipeline/tree/v1.2.1" + "source": "https://github.com/amphp/pipeline/tree/v1.2.2" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2025-01-19T15:42:46+00:00" + }, + { + "name": "amphp/process", + "version": "v2.0.3", + "source": { + "type": "git", + "url": "https://github.com/amphp/process.git", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/process/zipball/52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "reference": "52e08c09dec7511d5fbc1fb00d3e4e79fc77d58d", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/sync": "^2", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "phpunit/phpunit": "^9", + "psalm/phar": "^5.4" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "Amp\\Process\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bob Weinand", + "email": "bobwei9@hotmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "A fiber-aware process manager based on Amp and Revolt.", + "homepage": "https://amphp.org/process", + "support": { + "issues": "https://github.com/amphp/process/issues", + "source": "https://github.com/amphp/process/tree/v2.0.3" }, "funding": [ { @@ -1457,7 +1763,7 @@ "type": "github" } ], - "time": "2024-07-04T00:56:47+00:00" + "time": "2024-04-19T03:13:44+00:00" }, { "name": "amphp/serialization", @@ -1517,6 +1823,90 @@ }, "time": "2020-03-25T21:39:07+00:00" }, + { + "name": "amphp/socket", + "version": "v2.3.1", + "source": { + "type": "git", + "url": "https://github.com/amphp/socket.git", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/amphp/socket/zipball/58e0422221825b79681b72c50c47a930be7bf1e1", + "reference": "58e0422221825b79681b72c50c47a930be7bf1e1", + "shasum": "" + }, + "require": { + "amphp/amp": "^3", + "amphp/byte-stream": "^2", + "amphp/dns": "^2", + "ext-openssl": "*", + "kelunik/certificate": "^1.1", + "league/uri": "^6.5 | ^7", + "league/uri-interfaces": "^2.3 | ^7", + "php": ">=8.1", + "revolt/event-loop": "^1 || ^0.2" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "amphp/phpunit-util": "^3", + "amphp/process": "^2", + "phpunit/phpunit": "^9", + "psalm/phar": "5.20" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php", + "src/Internal/functions.php", + "src/SocketAddress/functions.php" + ], + "psr-4": { + "Amp\\Socket\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Lowrey", + "email": "rdlowrey@gmail.com" + }, + { + "name": "Aaron Piotrowski", + "email": "aaron@trowski.com" + }, + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Non-blocking socket connection / server implementations based on Amp and Revolt.", + "homepage": "https://github.com/amphp/socket", + "keywords": [ + "amp", + "async", + "encryption", + "non-blocking", + "sockets", + "tcp", + "tls" + ], + "support": { + "issues": "https://github.com/amphp/socket/issues", + "source": "https://github.com/amphp/socket/tree/v2.3.1" + }, + "funding": [ + { + "url": "https://github.com/amphp", + "type": "github" + } + ], + "time": "2024-04-21T14:33:03+00:00" + }, { "name": "amphp/sync", "version": "v2.3.0", @@ -1955,6 +2345,50 @@ ], "time": "2024-05-06T16:37:16+00:00" }, + { + "name": "daverandom/libdns", + "version": "v2.1.0", + "source": { + "type": "git", + "url": "https://github.com/DaveRandom/LibDNS.git", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/DaveRandom/LibDNS/zipball/b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "reference": "b84c94e8fe6b7ee4aecfe121bfe3b6177d303c8a", + "shasum": "" + }, + "require": { + "ext-ctype": "*", + "php": ">=7.1" + }, + "suggest": { + "ext-intl": "Required for IDN support" + }, + "type": "library", + "autoload": { + "files": [ + "src/functions.php" + ], + "psr-4": { + "LibDNS\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "DNS protocol implementation written in pure PHP", + "keywords": [ + "dns" + ], + "support": { + "issues": "https://github.com/DaveRandom/LibDNS/issues", + "source": "https://github.com/DaveRandom/LibDNS/tree/v2.1.0" + }, + "time": "2024-04-12T12:12:48+00:00" + }, { "name": "dnoegel/php-xdg-base-dir", "version": "v0.1.1", @@ -2445,6 +2879,238 @@ ], "time": "2025-01-30T17:00:50+00:00" }, + { + "name": "kelunik/certificate", + "version": "v1.1.3", + "source": { + "type": "git", + "url": "https://github.com/kelunik/certificate.git", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/kelunik/certificate/zipball/7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "reference": "7e00d498c264d5eb4f78c69f41c8bd6719c0199e", + "shasum": "" + }, + "require": { + "ext-openssl": "*", + "php": ">=7.0" + }, + "require-dev": { + "amphp/php-cs-fixer-config": "^2", + "phpunit/phpunit": "^6 | 7 | ^8 | ^9" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Kelunik\\Certificate\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Niklas Keller", + "email": "me@kelunik.com" + } + ], + "description": "Access certificate details and transform between different formats.", + "keywords": [ + "DER", + "certificate", + "certificates", + "openssl", + "pem", + "x509" + ], + "support": { + "issues": "https://github.com/kelunik/certificate/issues", + "source": "https://github.com/kelunik/certificate/tree/v1.1.3" + }, + "time": "2023-02-03T21:26:53+00:00" + }, + { + "name": "league/uri", + "version": "7.5.1", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri.git", + "reference": "81fb5145d2644324614cc532b28efd0215bda430" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri/zipball/81fb5145d2644324614cc532b28efd0215bda430", + "reference": "81fb5145d2644324614cc532b28efd0215bda430", + "shasum": "" + }, + "require": { + "league/uri-interfaces": "^7.5", + "php": "^8.1" + }, + "conflict": { + "league/uri-schemes": "^1.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-fileinfo": "to create Data URI from file contennts", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "jeremykendall/php-domain-parser": "to resolve Public Suffix and Top Level Domain", + "league/uri-components": "Needed to easily manipulate URI objects components", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "URI manipulation library", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "middleware", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "uri-template", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri/tree/7.5.1" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:40:02+00:00" + }, + { + "name": "league/uri-interfaces", + "version": "7.5.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/uri-interfaces.git", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/uri-interfaces/zipball/08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "reference": "08cfc6c4f3d811584fb09c37e2849e6a7f9b0742", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^8.1", + "psr/http-factory": "^1", + "psr/http-message": "^1.1 || ^2.0" + }, + "suggest": { + "ext-bcmath": "to improve IPV4 host parsing", + "ext-gmp": "to improve IPV4 host parsing", + "ext-intl": "to handle IDN host with the best performance", + "php-64bit": "to improve IPV4 host parsing", + "symfony/polyfill-intl-idn": "to handle IDN host via the Symfony polyfill if ext-intl is not present" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "7.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Uri\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignace Nyamagana Butera", + "email": "nyamsprod@gmail.com", + "homepage": "https://nyamsprod.com" + } + ], + "description": "Common interfaces and classes for URI representation and interaction", + "homepage": "https://uri.thephpleague.com", + "keywords": [ + "data-uri", + "file-uri", + "ftp", + "hostname", + "http", + "https", + "parse_str", + "parse_url", + "psr-7", + "query-string", + "querystring", + "rfc3986", + "rfc3987", + "rfc6570", + "uri", + "url", + "ws" + ], + "support": { + "docs": "https://uri.thephpleague.com", + "forum": "https://thephpleague.slack.com", + "issues": "https://github.com/thephpleague/uri-src/issues", + "source": "https://github.com/thephpleague/uri-interfaces/tree/7.5.0" + }, + "funding": [ + { + "url": "https://github.com/sponsors/nyamsprod", + "type": "github" + } + ], + "time": "2024-12-08T08:18:47+00:00" + }, { "name": "myclabs/deep-copy", "version": "1.12.1", @@ -3004,16 +3670,16 @@ }, { "name": "phpstan/phpstan", - "version": "2.1.2", + "version": "2.1.3", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "7d08f569e582ade182a375c366cbd896eccadd3a" + "reference": "64ae44e48214f3deebdaeebf2694297a10a2bea9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/7d08f569e582ade182a375c366cbd896eccadd3a", - "reference": "7d08f569e582ade182a375c366cbd896eccadd3a", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/64ae44e48214f3deebdaeebf2694297a10a2bea9", + "reference": "64ae44e48214f3deebdaeebf2694297a10a2bea9", "shasum": "" }, "require": { @@ -3058,7 +3724,7 @@ "type": "github" } ], - "time": "2025-01-21T14:54:06+00:00" + "time": "2025-02-07T15:05:24+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", @@ -4266,6 +4932,65 @@ ], "time": "2024-06-11T12:45:25+00:00" }, + { + "name": "rector/rector", + "version": "2.0.8", + "source": { + "type": "git", + "url": "https://github.com/rectorphp/rector.git", + "reference": "3c70238bc677eb98866000a05b19a34f12955954" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/rectorphp/rector/zipball/3c70238bc677eb98866000a05b19a34f12955954", + "reference": "3c70238bc677eb98866000a05b19a34f12955954", + "shasum": "" + }, + "require": { + "php": "^7.4|^8.0", + "phpstan/phpstan": "^2.1.2" + }, + "conflict": { + "rector/rector-doctrine": "*", + "rector/rector-downgrade-php": "*", + "rector/rector-phpunit": "*", + "rector/rector-symfony": "*" + }, + "suggest": { + "ext-dom": "To manipulate phpunit.xml via the custom-rule command" + }, + "bin": [ + "bin/rector" + ], + "type": "library", + "autoload": { + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Instant Upgrade and Automated Refactoring of any PHP code", + "keywords": [ + "automation", + "dev", + "migration", + "refactoring" + ], + "support": { + "issues": "https://github.com/rectorphp/rector/issues", + "source": "https://github.com/rectorphp/rector/tree/2.0.8" + }, + "funding": [ + { + "url": "https://github.com/tomasvotruba", + "type": "github" + } + ], + "time": "2025-02-06T14:02:49+00:00" + }, { "name": "revolt/event-loop", "version": "v1.0.6", @@ -6566,21 +7291,22 @@ }, { "name": "vimeo/psalm", - "version": "dev-master", + "version": "6.5.0", "source": { "type": "git", "url": "https://github.com/vimeo/psalm.git", - "reference": "765dcbfe43002e52e4808b65561842784fe7bcc7" + "reference": "38fc8444edf0cebc9205296ee6e30e906ade783b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/vimeo/psalm/zipball/765dcbfe43002e52e4808b65561842784fe7bcc7", - "reference": "765dcbfe43002e52e4808b65561842784fe7bcc7", + "url": "https://api.github.com/repos/vimeo/psalm/zipball/38fc8444edf0cebc9205296ee6e30e906ade783b", + "reference": "38fc8444edf0cebc9205296ee6e30e906ade783b", "shasum": "" }, "require": { "amphp/amp": "^3", "amphp/byte-stream": "^2", + "amphp/parallel": "^2.3", "composer-runtime-api": "^2", "composer/semver": "^1.4 || ^2.0 || ^3.0", "composer/xdebug-handler": "^2.0 || ^3.0", @@ -6593,15 +7319,15 @@ "ext-simplexml": "*", "ext-tokenizer": "*", "felixfbecker/advanced-json-rpc": "^3.1", - "felixfbecker/language-server-protocol": "^1.5.2", + "felixfbecker/language-server-protocol": "^1.5.3", "fidry/cpu-core-counter": "^0.4.1 || ^0.5.1 || ^1.0.0", "netresearch/jsonmapper": "^1.0 || ^2.0 || ^3.0 || ^4.0", "nikic/php-parser": "^5.0.0", "php": "~8.1.17 || ~8.2.4 || ~8.3.0 || ~8.4.0", - "sebastian/diff": "^4.0 || ^5.0 || ^6.0", + "sebastian/diff": "^4.0 || ^5.0 || ^6.0 || ^7.0", "spatie/array-to-xml": "^2.17.0 || ^3.0", - "symfony/console": "^4.1.6 || ^5.0 || ^6.0 || ^7.0", - "symfony/filesystem": "^5.4 || ^6.0 || ^7.0" + "symfony/console": "^6.0 || ^7.0", + "symfony/filesystem": "^6.0 || ^7.0" }, "provide": { "psalm/psalm": "self.version" @@ -6618,10 +7344,10 @@ "phpstan/phpdoc-parser": "^1.6", "phpunit/phpunit": "^9.6", "psalm/plugin-mockery": "^1.1", - "psalm/plugin-phpunit": "^0.18", + "psalm/plugin-phpunit": "^0.19", "slevomat/coding-standard": "^8.4", "squizlabs/php_codesniffer": "^3.6", - "symfony/process": "^4.4 || ^5.0 || ^6.0 || ^7.0" + "symfony/process": "^6.0 || ^7.0" }, "suggest": { "ext-curl": "In order to send data to shepherd", @@ -6632,6 +7358,7 @@ "psalm-language-server", "psalm-plugin", "psalm-refactor", + "psalm-review", "psalter" ], "type": "project", @@ -6642,7 +7369,8 @@ "dev-3.x": "3.x-dev", "dev-4.x": "4.x-dev", "dev-5.x": "5.x-dev", - "dev-master": "6.x-dev" + "dev-6.x": "6.x-dev", + "dev-master": "7.x-dev" } }, "autoload": { @@ -6657,6 +7385,10 @@ "authors": [ { "name": "Matthew Brown" + }, + { + "name": "Daniil Gentili", + "email": "daniil@daniil.it" } ], "description": "A static analysis tool for finding errors in PHP applications", @@ -6671,7 +7403,7 @@ "issues": "https://github.com/vimeo/psalm/issues", "source": "https://github.com/vimeo/psalm" }, - "time": "2024-12-15T08:19:36+00:00" + "time": "2025-02-07T20:42:25+00:00" }, { "name": "webmozart/assert", @@ -6734,9 +7466,7 @@ ], "aliases": [], "minimum-stability": "dev", - "stability-flags": { - "vimeo/psalm": 20 - }, + "stability-flags": {}, "prefer-stable": true, "prefer-lowest": false, "platform": { diff --git a/phpstan-baseline.neon b/phpstan-baseline.neon index 22a4936..42fb550 100644 --- a/phpstan-baseline.neon +++ b/phpstan-baseline.neon @@ -1,6 +1,37 @@ parameters: ignoreErrors: - - message: "#^You should use assertCount\\(\\$expectedCount, \\$variable\\) instead of assertSame\\(\\$expectedCount, \\$variable\\-\\>count\\(\\)\\)\\.$#" + message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Numverify\\\\Country\\\\Collection'' and Numverify\\Country\\Collection will always evaluate to true\.$#' + identifier: staticMethod.alreadyNarrowedType + count: 1 + path: tests/ApiCountryTest.php + + - + message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Numverify\\\\Country\\\\Country'' and Numverify\\Country\\Country will always evaluate to true\.$#' + identifier: staticMethod.alreadyNarrowedType + count: 1 + path: tests/ApiCountryTest.php + + - + message: '#^Cannot cast mixed to string\.$#' + identifier: cast.string + count: 1 + path: tests/ApiTest.php + + - + message: '#^Call to static method PHPUnit\\Framework\\Assert\:\:assertInstanceOf\(\) with ''Numverify\\\\Country\\\\Country'' and Numverify\\Country\\Country will always evaluate to true\.$#' + identifier: staticMethod.alreadyNarrowedType count: 1 path: tests/Country/CollectionTest.php + + - + message: '#^Parameter \#1 \$validatedPhoneNumber of class Numverify\\PhoneNumber\\InvalidPhoneNumber constructor expects object\{valid\: bool\|string, number\: int\|string\}&stdClass, stdClass given\.$#' + identifier: argument.type + count: 6 + path: tests/PhoneNumber/InvalidPhoneNumberTest.php + + - + message: '#^Parameter \#1 \$validatedPhoneNumberData of class Numverify\\PhoneNumber\\ValidPhoneNumber constructor expects object\{valid\: bool\|string, number\: int\|string, local_format\: string, international_format\: string, country_prefix\: string, country_code\: string, country_name\: string, location\: string, carrier\: string, line_type\: string\}&stdClass, stdClass given\.$#' + identifier: argument.type + count: 6 + path: tests/PhoneNumber/ValidPhoneNumberTest.php diff --git a/psalm-baseline.xml b/psalm-baseline.xml new file mode 100644 index 0000000..7533a21 --- /dev/null +++ b/psalm-baseline.xml @@ -0,0 +1,23 @@ + + + + + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + + + + + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + validatedPhoneNumberData]]> + + + diff --git a/psalm.xml b/psalm.xml index 34cfee6..16ccb55 100644 --- a/psalm.xml +++ b/psalm.xml @@ -14,8 +14,12 @@ + + + + diff --git a/rector.php b/rector.php new file mode 100644 index 0000000..c47b29f --- /dev/null +++ b/rector.php @@ -0,0 +1,41 @@ +withParallel() + ->withPaths([ + __DIR__ . '/src', + __DIR__ . '/tests', + ]) + ->withCache( + __DIR__ . '/build/rector' + ) + ->withRules([ + PreferPHPUnitSelfCallRector::class, + ]) + ->withSkip([ + JoinStringConcatRector::class, + PreferPHPUnitThisCallRector::class, + ]) + ->withPhpSets( + php82: true + ) + ->withPreparedSets( + deadCode: true, + codeQuality: true, + codingStyle: true, + typeDeclarations: true, + privatization: true, + naming: true, + earlyReturn: true, + strictBooleans: true, + rectorPreset: true, + phpunitCodeQuality: true, + ) + ; diff --git a/src/Api.php b/src/Api.php index 0600e02..9331d65 100644 --- a/src/Api.php +++ b/src/Api.php @@ -48,8 +48,24 @@ * * @psalm-api * - * @phpstan-type ApiJsonArray array{success?: bool, error?: array{code?: int, type?: string, info?: string}, valid?: bool, number?: string, local_format?: string, international_format?: string, country_prefix?: string, country_code?: string, country_name?: string, location?: string, carrier?: string, line_type?: string} + * @phpstan-type ApiJsonArray array{ + * success?: bool, + * error?: array{code?: int, type?: string, info?: string}, + * valid?: bool, + * number?: string, + * local_format?: string, + * international_format?: string, + * country_prefix?: string, + * country_code?: string, + * country_name?: string, + * location?: string, + * carrier?: string, + * line_type?: string + * } * @phpstan-type ApiCountryJsonArray array + * + * @phpstan-import-type InvalidPhoneNumberObject from PhoneNumber\Factory + * @phpstan-import-type ValidPhoneNumberObject from PhoneNumber\Factory */ class Api { @@ -82,7 +98,7 @@ class Api /** * Api constructor. * - * Requires an access key. You can get one from Numverify: + * Requires an access key. You can get one from Numverify. * * @see https://numverify.com/product * @@ -108,11 +124,11 @@ public function __construct( } // Build client - $clientOptions = ['base_uri' => self::getUrl($useHttps)]; + $clientOptions = ['base_uri' => $this->getUrl($useHttps)]; // If $options has 'cachePath' key, and it is a valid directory, then buildCacheHandler() will // add Cache to the Guzzle handler stack. - $options = self::buildCacheHandler($options); + $options = $this->buildCacheHandler($options); // Merge $options into main client options. $clientOptions = array_merge($clientOptions, $options); @@ -141,7 +157,7 @@ public function getCountries(): Collection } /** @var ApiCountryJsonArray $body */ - $body = self::validateAndDecodeResponse($response, true); + $body = $this->validateAndDecodeResponse($response, true); $countries = array_map( static fn (array $country, string $countryCode): Country => new Country($countryCode, $country['country_name'], $country['dialling_code']), @@ -186,8 +202,7 @@ public function validatePhoneNumber(string $phoneNumber, string $countryCode = ' throw new NumverifyApiFailureException($serverException->getResponse()); } - /** @var stdClass $body */ - $body = self::validateAndDecodeResponse($result); + $body = $this->validateAndDecodeResponse($result); return Factory::create($body); } @@ -203,7 +218,7 @@ public function validatePhoneNumber(string $phoneNumber, string $countryCode = ' * * @return array */ - private static function buildCacheHandler(array $options): array + private function buildCacheHandler(array $options): array { $cachePath = (string) ($options['cachePath'] ?? null); // @phpstan-ignore-line @@ -223,7 +238,7 @@ private static function buildCacheHandler(array $options): array /** * Get the URL to use for API calls. */ - private static function getUrl(bool $useHttps): string + private function getUrl(bool $useHttps): string { return $useHttps ? self::HTTPS_URL : self::HTTP_URL; } @@ -237,9 +252,9 @@ private static function getUrl(bool $useHttps): string * * @throws NumverifyApiFailureException If the response is non 200 or success field is false. * - * @return ApiCountryJsonArray|ApiJsonArray|stdClass + * @return ($asArray is true ? ApiCountryJsonArray|ApiJsonArray : InvalidPhoneNumberObject|ValidPhoneNumberObject) */ - private static function validateAndDecodeResponse(ResponseInterface $response, bool $asArray = false): array|stdClass + private function validateAndDecodeResponse(ResponseInterface $response, bool $asArray = false): array|stdClass { // If not 200 ok if ($response->getStatusCode() !== 200) { @@ -247,21 +262,26 @@ private static function validateAndDecodeResponse(ResponseInterface $response, b } /** - * @var ApiCountryJsonArray|ApiJsonArray|stdClass $body + * @var ApiCountryJsonArray|ApiJsonArray|InvalidPhoneNumberObject|ValidPhoneNumberObject $body */ $body = json_decode($response->getBody()->getContents(), $asArray); - /** - * @var ApiCountryJsonArray|ApiJsonArray $data - */ - $data = $asArray ? $body : (array) $body; - - if (isset($data['success']) && $data['success'] === false) { + if (!$this->verifySuccess($body)) { throw new NumverifyApiFailureException($response); } - unset($data); - return $body; } + + /** + * @param ApiCountryJsonArray|ApiJsonArray|InvalidPhoneNumberObject|ValidPhoneNumberObject $body + */ + private function verifySuccess(array|stdClass $body): bool + { + if (!\is_array($body)) { + $body = (array) $body; + } + + return !(isset($body['success']) && $body['success'] === false); + } } diff --git a/src/Country/Collection.php b/src/Country/Collection.php index f01ddcd..eb4c7a9 100644 --- a/src/Country/Collection.php +++ b/src/Country/Collection.php @@ -54,6 +54,8 @@ public function __construct(Country ...$countries) /** * @inheritDoc + * + * @psalm-api */ public function count(): int { diff --git a/src/Exception/NumverifyApiFailureException.php b/src/Exception/NumverifyApiFailureException.php index 9460528..2f570f1 100644 --- a/src/Exception/NumverifyApiFailureException.php +++ b/src/Exception/NumverifyApiFailureException.php @@ -31,6 +31,7 @@ class NumverifyApiFailureException extends RuntimeException private readonly string $body; private readonly string $reasonPhrase; + private readonly int $statusCode; public function __construct(ResponseInterface $response) diff --git a/src/PhoneNumber/Factory.php b/src/PhoneNumber/Factory.php index f87c854..6d5195a 100644 --- a/src/PhoneNumber/Factory.php +++ b/src/PhoneNumber/Factory.php @@ -19,16 +19,40 @@ /** * PhoneNumber Factory. + * * Role: Factory class to create the appropriate PhoneNumber object. + * + * @phpstan-type ValidPhoneNumberObject = stdClass&object{ + * valid: bool|string, + * number: int|string, + * local_format: string, + * international_format: string, + * country_prefix: string, + * country_code: string, + * country_name: string, + * location: string, + * carrier: string, + * line_type: string + * } + * @phpstan-type InvalidPhoneNumberObject = stdClass&object{valid: bool|string, number: int|string} */ class Factory { + /** + * @param InvalidPhoneNumberObject|ValidPhoneNumberObject $validatedPhoneNumber + */ public static function create(stdClass $validatedPhoneNumber): PhoneNumberInterface { if ((bool) $validatedPhoneNumber->valid === false) { + /** + * @var InvalidPhoneNumberObject $validatedPhoneNumber + */ return new InvalidPhoneNumber($validatedPhoneNumber); } + /** + * @var ValidPhoneNumberObject $validatedPhoneNumber + */ return new ValidPhoneNumber($validatedPhoneNumber); } } diff --git a/src/PhoneNumber/InvalidPhoneNumber.php b/src/PhoneNumber/InvalidPhoneNumber.php index 37a96af..6b2f562 100644 --- a/src/PhoneNumber/InvalidPhoneNumber.php +++ b/src/PhoneNumber/InvalidPhoneNumber.php @@ -31,25 +31,26 @@ class InvalidPhoneNumber implements PhoneNumberInterface private const FIELDS = ['valid', 'number']; private readonly string $number; + private readonly bool $valid; /** * InvalidPhoneNumber constructor. + * + * @param stdClass&object{valid: bool|string, number: int|string} $validatedPhoneNumber */ public function __construct(stdClass $validatedPhoneNumber) { $this->verifyPhoneNumberData($validatedPhoneNumber); - \assert(\is_bool($validatedPhoneNumber->valid)); - \assert(\is_string($validatedPhoneNumber->number)); - $this->valid = $validatedPhoneNumber->valid; - $this->number = $validatedPhoneNumber->number; + $this->valid = (bool) $validatedPhoneNumber->valid; + $this->number = (string) $validatedPhoneNumber->number; } /** * Debug info. * - * @return array + * @return array{valid: bool, number: string} */ public function __debugInfo(): array { @@ -83,7 +84,7 @@ public function isValid(): bool /** * @inheritDoc * - * @return array + * @return array{valid: bool, number: string} */ public function jsonSerialize(): array { diff --git a/src/PhoneNumber/PhoneNumberInterface.php b/src/PhoneNumber/PhoneNumberInterface.php index 29ece6d..c992379 100644 --- a/src/PhoneNumber/PhoneNumberInterface.php +++ b/src/PhoneNumber/PhoneNumberInterface.php @@ -27,6 +27,7 @@ interface PhoneNumberInterface extends JsonSerializable, Stringable * Get the phone number. */ public function getNumber(): string; + /** * Is the phone number valid? */ diff --git a/src/PhoneNumber/ValidPhoneNumber.php b/src/PhoneNumber/ValidPhoneNumber.php index 0c36eb6..cee3393 100644 --- a/src/PhoneNumber/ValidPhoneNumber.php +++ b/src/PhoneNumber/ValidPhoneNumber.php @@ -21,11 +21,28 @@ use function implode; /** - * ValidPhoneNumber + * ValidPhoneNumber. + * * Role: Value object to represent a phone number that the Numverify returned as valid. * + * @phpstan-import-type ValidPhoneNumberObject from Factory + * + * @phpstan-type ValidNumberArray = array{ + * valid: bool, + * number: string, + * localFormat: string, + * internationalFormat: string, + * countryPrefix: string, + * countryCode: string, + * countryName: string, + * location: string, + * carrier: string, + * lineType: string + * } + * * @see \Numverify\Tests\PhoneNumber\ValidPhoneNumberTest */ + class ValidPhoneNumber implements PhoneNumberInterface { /** @@ -53,28 +70,20 @@ class ValidPhoneNumber implements PhoneNumberInterface private readonly string $location; private readonly string $number; + private readonly bool $valid; /** * ValidPhoneNumber constructor. + * + * @param ValidPhoneNumberObject $validatedPhoneNumberData */ public function __construct(stdClass $validatedPhoneNumberData) { $this->verifyPhoneNumberData($validatedPhoneNumberData); - \assert(\is_bool($validatedPhoneNumberData->valid)); - \assert(\is_string($validatedPhoneNumberData->number)); - \assert(\is_string($validatedPhoneNumberData->local_format)); - \assert(\is_string($validatedPhoneNumberData->international_format)); - \assert(\is_string($validatedPhoneNumberData->country_prefix)); - \assert(\is_string($validatedPhoneNumberData->country_code)); - \assert(\is_string($validatedPhoneNumberData->country_name)); - \assert(\is_string($validatedPhoneNumberData->location)); - \assert(\is_string($validatedPhoneNumberData->carrier)); - \assert(\is_string($validatedPhoneNumberData->line_type)); - - $this->valid = $validatedPhoneNumberData->valid; - $this->number = $validatedPhoneNumberData->number; + $this->valid = (bool) $validatedPhoneNumberData->valid; + $this->number = (string) $validatedPhoneNumberData->number; $this->localFormat = $validatedPhoneNumberData->local_format; $this->internationalFormat = $validatedPhoneNumberData->international_format; $this->countryPrefix = $validatedPhoneNumberData->country_prefix; @@ -88,18 +97,7 @@ public function __construct(stdClass $validatedPhoneNumberData) /** * Debug info. * - * @return array{ - * valid: bool, - * number: string, - * localFormat: string, - * internationalFormat: string, - * countryPrefix: string, - * countryCode: string, - * countryName: string, - * location: string, - * carrier: string, - * lineType: string - * } + * @return ValidNumberArray */ public function __debugInfo(): array { @@ -197,18 +195,7 @@ public function isValid(): bool /** * @inheritDoc * - * @return array{ - * valid: bool, - * number: string, - * localFormat: string, - * internationalFormat: string, - * countryPrefix: string, - * countryCode: string, - * countryName: string, - * location: string, - * carrier: string, - * lineType: string - * } + * @return ValidNumberArray */ public function jsonSerialize(): array { diff --git a/tests/ApiCountryTest.php b/tests/ApiCountryTest.php index 690c0f6..661ee6b 100644 --- a/tests/ApiCountryTest.php +++ b/tests/ApiCountryTest.php @@ -37,7 +37,7 @@ #[CoversClass(Country::class)] #[CoversClass(Api::class)] #[CoversClass(NumverifyApiFailureException::class)] -class ApiCountryTest extends TestCase +final class ApiCountryTest extends TestCase { private const ACCESS_KEY = 'SomeAccessKey'; @@ -89,7 +89,7 @@ public function testCountriesInvalidAccessKey(bool $useHttps): void public function testCountriesReturnsCollectionOfCountries(bool $useHttps): void { $countryCollection = $this->aClient(useHttps: $useHttps)->getCountries(); - self::assertInstanceOf(Collection::class, $countryCollection); // @phpstan-ignore-line + self::assertInstanceOf(Collection::class, $countryCollection); self::assertContainsOnlyInstancesOf(Country::class, $countryCollection); } @@ -103,7 +103,7 @@ public function testCountriesReturnsExpectedCountries(bool $useHttps): void foreach ($countryCollection as $countryCode => $country) { /** @var string $countryCode */ $expectedCountries[$countryCode] = true; - self::assertInstanceOf(Country::class, $country); // @phpstan-ignore-line + self::assertInstanceOf(Country::class, $country); } foreach ($expectedCountries as $expectedCountry) { diff --git a/tests/ApiPhoneNumberTest.php b/tests/ApiPhoneNumberTest.php index 045ff84..b890f25 100644 --- a/tests/ApiPhoneNumberTest.php +++ b/tests/ApiPhoneNumberTest.php @@ -40,7 +40,7 @@ #[CoversClass(Api::class)] #[CoversClass(Factory::class)] #[CoversClass(NumverifyApiFailureException::class)] -class ApiPhoneNumberTest extends TestCase +final class ApiPhoneNumberTest extends TestCase { private const ACCESS_KEY = 'SomeAccessKey'; diff --git a/tests/ApiTest.php b/tests/ApiTest.php index b09d073..1c7337a 100644 --- a/tests/ApiTest.php +++ b/tests/ApiTest.php @@ -34,7 +34,7 @@ * @internal */ #[CoversClass(Api::class)] -class ApiTest extends TestCase +final class ApiTest extends TestCase { /** * Current version of the Numverify package. @@ -72,7 +72,7 @@ public function testConstructionWithCustomClient(bool $useHttps): void /** @var Client $client */ $client = $reflectionProperty->getValue($api); - $client = self::parseGuzzleConfig($client); + $client = $this->parseGuzzleConfig($client); $expected = 'http://apilayer.net/api'; $actual = $client['base_uri']; @@ -93,7 +93,7 @@ public function testConstructionWithDefaultClient(bool $useHttps): void /** @var Client $client */ $client = $reflectionProperty->getValue($api); - $client = self::parseGuzzleConfig($client); + $client = $this->parseGuzzleConfig($client); $expected = ($useHttps ? 'https' : 'http') . '://apilayer.net/api'; $actual = $client['base_uri']; @@ -114,7 +114,7 @@ public function testConstructionWithDefaultClientExtraOptions(bool $useHttps): v /** @var Client $client */ $client = $reflectionProperty->getValue($api); - $client = self::parseGuzzleConfig($client); + $client = $this->parseGuzzleConfig($client); $expected = ($useHttps ? 'https' : 'http') . '://apilayer.net/api'; $actual = $client['base_uri']; @@ -134,7 +134,7 @@ public static function dataProviderForHttp(): Iterator /** * @return array */ - private static function parseGuzzleConfig(Client $client): array + private function parseGuzzleConfig(Client $client): array { $client = (array) $client; @@ -143,7 +143,7 @@ private static function parseGuzzleConfig(Client $client): array /** @var array $config */ $config = [ - 'base_uri' => (string) $config['base_uri'], // @phpstan-ignore-line + 'base_uri' => (string) $config['base_uri'], 'timeout' => $config['timeout'] ?? 0, ]; return $config; diff --git a/tests/Country/CollectionTest.php b/tests/Country/CollectionTest.php index 2874f57..850faaf 100644 --- a/tests/Country/CollectionTest.php +++ b/tests/Country/CollectionTest.php @@ -31,11 +31,12 @@ */ #[CoversClass(Collection::class)] #[UsesClass(Country::class)] -class CollectionTest extends TestCase +final class CollectionTest extends TestCase { private Country $countryGb; private Country $countryJp; + private Country $countryUs; /** @@ -57,7 +58,6 @@ public function testCount(array $countries, int $expectedCount): void { $collection = new Collection(...$countries); - self::assertSame($expectedCount, $collection->count()); self::assertCount($expectedCount, $collection); } @@ -120,7 +120,7 @@ public function testIterator(): void foreach ($collection as $countryCode => $country) { /** @var string $countryCode */ $expectedCountries[$countryCode] = true; - self::assertInstanceOf(Country::class, $country); // @phpstan-ignore-line + self::assertInstanceOf(Country::class, $country); } foreach ($expectedCountries as $expectedCountry) { diff --git a/tests/Country/CountryTest.php b/tests/Country/CountryTest.php index f29a5af..bb15b39 100644 --- a/tests/Country/CountryTest.php +++ b/tests/Country/CountryTest.php @@ -25,7 +25,7 @@ * @internal */ #[CoversClass(Country::class)] -class CountryTest extends TestCase +final class CountryTest extends TestCase { private const COUNTRY_CODE = 'US'; @@ -33,7 +33,7 @@ class CountryTest extends TestCase private const DIALLING_CODE = '+1'; - #[TestDox('Country \'getters\' returns expected results.')] + #[TestDox("Country 'getters' returns expected results.")] public function testGetters(): void { $country = new Country(self::COUNTRY_CODE, self::COUNTRY_NAME, self::DIALLING_CODE); diff --git a/tests/Exception/NumverifyApiFailureExceptionTest.php b/tests/Exception/NumverifyApiFailureExceptionTest.php index b1d4bc0..6afdbe6 100644 --- a/tests/Exception/NumverifyApiFailureExceptionTest.php +++ b/tests/Exception/NumverifyApiFailureExceptionTest.php @@ -25,12 +25,13 @@ * @internal */ #[CoversClass(NumverifyApiFailureException::class)] -class NumverifyApiFailureExceptionTest extends TestCase +final class NumverifyApiFailureExceptionTest extends TestCase { private const BODY = 'server error'; private const REASON_PHRASE = 'Internal Server Error'; - private const STATUS_CODE = 500; + + private const STATUS_CODE = 500; private Response $response; diff --git a/tests/Exception/NumverifyApiResponseExceptionTest.php b/tests/Exception/NumverifyApiResponseExceptionTest.php index 951fdbb..87e8dff 100644 --- a/tests/Exception/NumverifyApiResponseExceptionTest.php +++ b/tests/Exception/NumverifyApiResponseExceptionTest.php @@ -23,7 +23,7 @@ * @internal */ #[CoversClass(NumverifyApiResponseException::class)] -class NumverifyApiResponseExceptionTest extends TestCase +final class NumverifyApiResponseExceptionTest extends TestCase { /** * Case getMessage. diff --git a/tests/PhoneNumber/InvalidPhoneNumberTest.php b/tests/PhoneNumber/InvalidPhoneNumberTest.php index 919010b..f17d959 100644 --- a/tests/PhoneNumber/InvalidPhoneNumberTest.php +++ b/tests/PhoneNumber/InvalidPhoneNumberTest.php @@ -32,10 +32,11 @@ * @internal */ #[CoversClass(InvalidPhoneNumber::class)] -class InvalidPhoneNumberTest extends TestCase +final class InvalidPhoneNumberTest extends TestCase { private const NUMBER = '14158586273'; - private const VALID = false; + + private const VALID = false; private stdClass $validatedPhoneNumberData; diff --git a/tests/PhoneNumber/ValidPhoneNumberTest.php b/tests/PhoneNumber/ValidPhoneNumberTest.php index eb03cbb..ff23e59 100644 --- a/tests/PhoneNumber/ValidPhoneNumberTest.php +++ b/tests/PhoneNumber/ValidPhoneNumberTest.php @@ -32,7 +32,7 @@ * @internal */ #[CoversClass(ValidPhoneNumber::class)] -class ValidPhoneNumberTest extends TestCase +final class ValidPhoneNumberTest extends TestCase { private const CARRIER = 'AT&T Mobility LLC'; @@ -51,7 +51,8 @@ class ValidPhoneNumberTest extends TestCase private const LOCATION = 'Novato'; private const NUMBER = '14158586273'; - private const VALID = true; + + private const VALID = true; private stdClass $validatedPhoneNumberData; @@ -89,7 +90,7 @@ public function testDebugInfo(): void self::assertStringContainsString('lineType', $debugInfo); } - #[TestDox('ValidPhoneNumber \'getters\' returns appropriate data.')] + #[TestDox("ValidPhoneNumber 'getters' returns appropriate data.")] public function testGetters(): void { $validPhoneNumber = new ValidPhoneNumber($this->validatedPhoneNumberData);