diff --git a/.github/dependabot.yml b/.github/dependabot.yml index f42ee701..34e51160 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,34 +1,52 @@ version: 2 updates: -- package-ecosystem: composer - directory: "/" - schedule: - interval: daily - open-pull-requests-limit: 10 - reviewers: - - mimmi20 - - asgrim - - jaydiablo - versioning-strategy: increase-if-necessary - ignore: - - dependency-name: monolog/monolog - versions: - - ">= 0" - - dependency-name: phpunit/phpunit - versions: - - ">= 0" - - dependency-name: roave/doctrine-simplecache - versions: - - ">= 0" - - dependency-name: symfony/cache - versions: - - ">= 0" - - dependency-name: symfony/console - versions: - - ">= 0" - - dependency-name: symfony/finder - versions: - - ">= 0" - commit-message: - prefix: Build - include: scope + - package-ecosystem: "composer" + directory: "/" + schedule: + interval: "daily" + time: "05:00" + open-pull-requests-limit: 10 + reviewers: + - "mimmi20" + - "asgrim" + - "jaydiablo" + labels: + - "dependencies" + versioning-strategy: "increase-if-necessary" + ignore: + - dependency-name: "monolog/monolog" + versions: + - ">= 0" + - dependency-name: "phpunit/phpunit" + versions: + - ">= 0" + - dependency-name: "roave/doctrine-simplecache" + versions: + - ">= 0" + - dependency-name: "symfony/cache" + versions: + - ">= 0" + - dependency-name: "symfony/console" + versions: + - ">= 0" + - dependency-name: "symfony/finder" + versions: + - ">= 0" + commit-message: + include: "scope" + prefix: "Build" + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "daily" + time: "05:00" + open-pull-requests-limit: 10 + reviewers: + - "mimmi20" + - "asgrim" + - "jaydiablo" + labels: + - "dependencies" + commit-message: + prefix: "github-actions" diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml deleted file mode 100644 index ec49b034..00000000 --- a/.github/workflows/build.yml +++ /dev/null @@ -1,136 +0,0 @@ -name: CI -on: [push, pull_request] -jobs: - - composer-validate: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 - - - name: Composer validate - run: | - composer install - composer validate --strict - composer normalize --dry-run - - unit-tests: - strategy: - matrix: - dependencies: ["lowest", "locked", "highest"] - php-versions: - - 7.4 - - 8.0 - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - coverage: pcov - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ~/.composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.json') }} - - - name: "Install lowest dependencies" - if: ${{ matrix.dependencies == 'lowest' }} - run: "composer update --prefer-lowest --prefer-dist --no-interaction --no-progress" - - name: "Install highest dependencies" - if: ${{ matrix.dependencies == 'highest' }} - run: "composer update --prefer-dist --no-interaction --no-progress" - - name: "Install locked dependencies" - if: ${{ matrix.dependencies == 'locked' }} - run: "composer install --no-interaction --no-progress" - - - name: Test with coverage - run: vendor/bin/phpunit --colors --verbose --exclude-group compare --coverage-text - - comparison-checks: - strategy: - matrix: - dependencies: ["lowest", "locked", "highest"] - php-versions: - - 7.4 - - 8.0 - runs-on: ubuntu-latest - - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Install PHP - uses: shivammathur/setup-php@v2 - with: - php-version: ${{ matrix.php-versions }} - ini-values: browscap=/tmp/browscap.ini - - - name: Cache dependencies - uses: actions/cache@v1 - with: - path: ~/.composer/cache/files - key: dependencies-composer-${{ hashFiles('composer.json') }} - - - name: "Download browscap.ini" - run: | - wget -q http://browscap.org/stream?q=Full_PHP_BrowsCapINI -O /tmp/browscap.ini - mkdir -p resources - cp /tmp/browscap.ini resources/browscap.ini - - - name: "Install lowest dependencies" - if: ${{ matrix.dependencies == 'lowest' }} - run: "composer update --prefer-lowest --prefer-dist --no-interaction --no-progress" - - name: "Install highest dependencies" - if: ${{ matrix.dependencies == 'highest' }} - run: "composer update --prefer-dist --no-interaction --no-progress" - - name: "Install locked dependencies" - if: ${{ matrix.dependencies == 'locked' }} - run: "composer install --no-interaction --no-progress" - - - name: Compare get_browser to browscap-php results - run: vendor/bin/phpunit --colors --verbose --no-coverage --group compare - - coding-standards: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 7.4 - - - name: Install dependencies - run: composer install - - - name: Run php-cs-fixer - run: vendor/bin/php-cs-fixer fix --dry-run -vv - - static-analysis: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v2 - - - name: Setup PHP - uses: shivammathur/setup-php@v2 - with: - php-version: 8.0 - - - name: Install dependencies - run: composer install - - - name: Run phpstan - run: vendor/bin/phpstan analyse -l max -c phpstan.neon --autoload-file=vendor/autoload.php --memory-limit=768M --no-progress src tests diff --git a/.github/workflows/continuous-integration.yml b/.github/workflows/continuous-integration.yml new file mode 100644 index 00000000..b14231d9 --- /dev/null +++ b/.github/workflows/continuous-integration.yml @@ -0,0 +1,488 @@ +name: "Continuous Integration" + +on: + - pull_request + - push + +env: + PHP_EXTENSIONS: "json, curl, opcache, mbstring" + PHP_INI_VALUES: "opcache.enable=1, opcache.enable_cli=1, opcache.fast_shutdown=0, zend.assertions=1, assert.exception=On" + +jobs: + validate: + name: "Validate composer" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "7.4" + + dependencies: + - "" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2, composer-normalize" + + - name: "Validate composer.json" + run: "composer validate --strict" + + - name: "Run composer-normalize" + run: "composer-normalize --dry-run" + + install: + name: "Install dependencies" + + needs: "validate" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: ${{ matrix.experimental }} + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-18.04" + - "ubuntu-20.04" + + php-version: + - "7.4" + - "8.0" + - "8.1" + + dependencies: + - "lowest" + - "highest" + + experimental: [false] + + include: + - operating-system: "ubuntu-20.04" + php-version: "8.0" + dependencies: "locked" + experimental: false + - operating-system: "ubuntu-20.04" + php-version: "8.1" + dependencies: "locked" + experimental: false + - operating-system: "ubuntu-20.04" + php-version: "8.2" + dependencies: "highest" + experimental: true + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Install lowest dependencies" + if: "${{ matrix.dependencies == 'lowest' }}" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi --prefer-lowest" + + - name: "Install highest dependencies" + if: "${{ matrix.dependencies == 'highest' && matrix.experimental == false }}" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi" + + - name: "Install highest dependencies (Experimental)" + if: "${{ matrix.dependencies == 'highest' && matrix.experimental == true }}" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi --ignore-platform-reqs" + + - name: "Install locked dependencies" + if: "${{ matrix.dependencies == 'locked' }}" + run: "composer install --no-interaction --no-progress" + + coding-standards: + name: "Check Coding Standards with PHPCS" + + needs: "validate" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "7.4" + + dependencies: + - "" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2, cs2pr" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Update dependencies with composer" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi ${{ matrix.dependencies }}" + + - name: "Run squizlabs/php_codesniffer" + run: "vendor/bin/phpcs --report=checkstyle -q | cs2pr" + + static-code-analysis: + name: "Static Code Analysis with PHPStan" + + needs: "validate" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "7.4" + + dependencies: + - "" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Update dependencies with composer" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi ${{ matrix.dependencies }}" + + - name: "Run phpstan/phpstan" + run: "vendor/bin/phpstan analyse -c phpstan.neon --memory-limit=768M --no-progress" + + unit-tests: + name: "UnitTests with PHPUnit" + + needs: "validate" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "7.4" + - "8.0" + - "8.1" + + dependencies: + - "" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Update dependencies with composer" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi ${{ matrix.dependencies }}" + + - name: "Run unit tests with phpunit/phpunit" + run: "vendor/bin/phpunit -c phpunit.xml.dist --verbose --exclude-group compare --no-coverage --colors" + + code-coverage: + name: "Code Coverage with PHPUnit" + + needs: "unit-tests" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "7.4" + + dependencies: + - "" + + coverage-drivers: + - "xdebug" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "${{ matrix.coverage-drivers }}" + tools: "composer:v2, infection" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Update dependencies with composer" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi ${{ matrix.dependencies }}" + + - name: "Create cache directory for phpunit/phpunit" + run: "mkdir -p .build/coverage" + + - name: "Collect code coverage with Xdebug and phpunit/phpunit" + run: "vendor/bin/phpunit -c phpunit.xml.dist --verbose --exclude-group compare --coverage-clover=.build/coverage/clover.xml --coverage-text --colors" + + - name: "Upload coverage to Codecov" + uses: "codecov/codecov-action@v2.1.0" + with: + file: ".build/coverage/clover.xml" + flags: "phpunit,php-${{ matrix.php-version }},${{ matrix.coverage-drivers }},${{ matrix.php-version }},${{ matrix.operating-system }}" + verbose: false + + comparison-checks: + name: "Compare results with PHPUnit" + + needs: "unit-tests" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "7.4" + + dependencies: + - "" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Update dependencies with composer" + run: "composer update --optimize-autoloader --prefer-dist --prefer-stable --no-progress --no-interaction -v --ansi ${{ matrix.dependencies }}" + + - name: "Download browscap.ini" + run: | + wget -q http://browscap.org/stream?q=Full_PHP_BrowsCapINI -O /tmp/browscap.ini + mkdir -p resources + cp /tmp/browscap.ini resources/browscap.ini + + - name: "Compare get_browser to browscap-php results" + run: "vendor/bin/phpunit -c phpunit.xml.dist --verbose --no-coverage --group compare --colors" + + roave-backwards-compatibility-check: + name: "Check for Backward Compatibility breaks" + + needs: "validate" + + runs-on: "${{ matrix.operating-system }}" + + continue-on-error: false + + strategy: + fail-fast: false + + matrix: + operating-system: + - "ubuntu-20.04" + + php-version: + - "8.1" + + dependencies: + - "" + + steps: + - name: "Checkout" + uses: "actions/checkout@v2.4.0" + with: + # Disabling shallow clone is recommended for improving relevancy of reporting + fetch-depth: 0 + + - name: "Install PHP" + uses: "shivammathur/setup-php@2.16.0" + with: + php-version: "${{ matrix.php-version }}" + extensions: "${{ env.PHP_EXTENSIONS }}" + ini-values: "${{ env.PHP_INI_VALUES }}" + coverage: "none" + tools: "composer:v2" + + - name: "Determine composer cache directory" + id: "determine-composer-cache-directory" + run: "echo \"::set-output name=directory::$(composer config cache-dir)\"" + + - name: "Cache dependencies installed with composer" + uses: "actions/cache@v2.1.7" + with: + path: "${{ steps.determine-composer-cache-directory.outputs.directory }}" + key: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-${{ hashFiles('composer.lock') }}" + restore-keys: "php-${{ matrix.php-version }}-composer-${{ matrix.dependencies }}-" + + - name: "Require Roave/BackwardCompatibilityCheck" + run: "composer require --no-update --no-interaction --prefer-dist --prefer-stable --dev \"roave/backward-compatibility-check:6.0.x-dev\" \"roave/better-reflection:5.0.x-dev\"" + + - name: "Composer update with new requirements" + run: "composer update --no-interaction --prefer-dist --prefer-stable" + + - name: "Check for BC breaks" + run: "vendor/bin/roave-backward-compatibility-check --format=markdown" diff --git a/.php_cs b/.php_cs deleted file mode 100644 index 3f4a10ef..00000000 --- a/.php_cs +++ /dev/null @@ -1,147 +0,0 @@ -files() - ->name('*.php') - ->in(__DIR__ . '/src') - ->in(__DIR__ . '/tests') - ->append([__FILE__]); - -ini_set('memory_limit', '-1'); - -return PhpCsFixer\Config::create() - ->setRiskyAllowed(true) - ->setRules( - [ - '@PSR2' => true, - '@PhpCsFixer' => true, - '@PhpCsFixer:risky' => true, - '@Symfony' => true, - '@Symfony:risky' => true, - '@PHP70Migration' => true, - '@PHP70Migration:risky' => true, - '@PHP71Migration' => true, - '@PHP71Migration:risky' => true, - '@PHP73Migration' => true, - '@PHPUnit60Migration:risky' => true, - '@PHPUnit75Migration:risky' => true, - - // @PSR2 rules configured different from default - 'blank_line_after_namespace' => true, - 'class_definition' => [ - 'single_line' => false, - 'single_item_single_line' => true, - 'multi_line_extends_each_single_line' => true, - ], - 'method_argument_space' => [ - 'on_multiline' => 'ensure_fully_multiline', - 'keep_multiple_spaces_after_comma' => false, - ], - 'no_break_comment' => false, - 'visibility_required' => ['elements' => ['property', 'method', 'const']], - - // @PhpCsFixer rules configured different from default - 'align_multiline_comment' => ['comment_type' => 'all_multiline'], - 'array_syntax' => ['syntax' => 'short'], - 'binary_operator_spaces' => ['default' => 'single_space'], - 'concat_space' => ['spacing' => 'one'], - 'declare_equal_normalize' => ['space' => 'single'], - 'php_unit_internal_class' => false, - 'no_superfluous_phpdoc_tags' => false, - 'multiline_whitespace_before_semicolons' => [ - 'strategy' => 'no_multi_line', - ], - 'no_extra_blank_lines' => [ - 'tokens' => ['break', 'case', 'continue', 'curly_brace_block', 'default', 'extra', 'parenthesis_brace_block', 'return', 'square_brace_block', 'switch', 'throw', 'use', 'useTrait', 'use_trait'], - ], - 'no_useless_return' => false, - 'php_unit_test_class_requires_covers' => false, - 'phpdoc_add_missing_param_annotation' => ['only_untyped' => false], - 'phpdoc_no_empty_return' => false, - 'phpdoc_summary' => false, - 'single_blank_line_before_namespace' => false, - 'single_line_comment_style' => ['comment_types' => ['hash']], - 'blank_line_after_opening_tag' => false, - 'return_type_declaration' => ['space_before' => 'one'], - 'unary_operator_spaces' => false, - 'phpdoc_annotation_without_dot' => false, - 'phpdoc_align' => false, - - // @PhpCsFixer:risky rules configured different from default - 'php_unit_strict' => ['assertions' => ['assertAttributeEquals', 'assertAttributeNotEquals', 'assertNotEquals']], - 'no_alias_functions' => ['sets' => ['@internal', '@IMAP', '@mbreg', '@all']], - 'php_unit_test_case_static_method_calls' => ['call_type' => 'self'], - 'strict_param' => false, - 'comment_to_phpdoc' => false, - - // @Symfony rules configured different from default - 'no_blank_lines_after_phpdoc' => false, - 'space_after_semicolon' => ['remove_in_empty_for_expressions' => true], - 'yoda_style' => [ - 'equal' => true, - 'identical' => true, - 'less_and_greater' => true, - ], - 'single_line_throw' => false, - - // @Symfony:risky rules configured different from default - 'non_printable_character' => ['use_escape_sequences_in_strings' => true], - - // @PHP70Migration rules configured different from default - 'ternary_to_null_coalescing' => false, - - // @PHP70Migration:risky rules configured different from default - 'pow_to_exponentiation' => false, - - // @PHPUnit60Migration:risky rules configured different from default - 'php_unit_dedicate_assert' => ['target' => 'newest'], - - // other rules - 'backtick_to_shell_exec' => true, - 'class_keyword_remove' => false, - 'final_class' => false, - 'final_internal_class' => [ - 'annotation-black-list' => ['@final', '@Entity', '@ORM'], - 'annotation-white-list' => ['@internal'], - ], - 'final_public_method_for_abstract_class' => true, - 'final_static_access' => true, - 'general_phpdoc_annotation_remove' => [ - 'expectedExceptionMessageRegExp', - 'expectedException', - 'expectedExceptionMessage', - 'author', - ], - 'global_namespace_import' => false, - 'header_comment' => false, - 'linebreak_after_opening_tag' => true, - 'list_syntax' => ['syntax' => 'short'], - 'mb_str_functions' => false, - 'native_constant_invocation' => false, - 'native_function_invocation' => false, - 'no_blank_lines_before_namespace' => false, - 'no_null_property_initialization' => true, - 'no_php4_constructor' => true, - 'not_operator_with_space' => false, - 'not_operator_with_successor_space' => false, - 'nullable_type_declaration_for_default_null_value' => ['use_nullable_type_declaration' => true], - 'ordered_class_elements' => false, - 'ordered_imports' => ['sort_algorithm' => 'alpha'], - 'ordered_interfaces' => ['direction' => 'ascend', 'order' => 'alpha'], - 'php_unit_size_class' => false, - 'php_unit_test_annotation' => ['case' => 'camel', 'style' => 'prefix'], - 'phpdoc_to_param_type' => false, - 'phpdoc_to_return_type' => false, - 'phpdoc_types_order' => [ - 'null_adjustment' => 'always_last', - 'sort_algorithm' => 'alpha', - ], - 'psr0' => true, - 'self_static_accessor' => true, - 'simplified_null_return' => false, - 'static_lambda' => true, - ] - ) - ->setUsingCache(true) - ->setFinder($finder); diff --git a/README.md b/README.md index ac99a931..b6532458 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,7 @@ Browser Capabilities PHP Project This is a userland replacement for PHP's native `get_browser()` function, which is _officially supported_ by the Browser Capabilities Project. -**Note that you are currently viewing the 4.x series. If you're looking for the unsupported 2.x version, please read the documentation for that branch [here](https://github.com/browscap/browscap-php/tree/2.x).** - -[![Build Status](https://secure.travis-ci.org/browscap/browscap-php.png?branch=master)](http://travis-ci.org/browscap/browscap-php) [![codecov](https://codecov.io/gh/browscap/browscap-php/branch/master/graph/badge.svg)](https://codecov.io/gh/browscap/browscap-php) +[![CI](https://github.com/browscap/browscap-php/actions/workflows/continuous-integration.yml/badge.svg)](https://github.com/browscap/browscap-php/actions/workflows/continuous-integration.yml) Installation ------------ @@ -19,7 +17,7 @@ composer require browscap/browscap-php Then you may identify the current user agent this way: ```php -$cache = new \Roave\DoctrineSimpleCache\SimpleCacheAdapter($doctrineFileCache); // or maybe any other PSR-16 compatible caches +$cache = new \MatthiasMullie\Scrapbook\Psr16\SimpleCache($doctrineFileCache); // or maybe any other PSR-16 compatible caches $logger = new \Monolog\Logger('name'); // or maybe any other PSR-3 compatible logger $browscap = new \BrowscapPHP\Browscap($cache, $logger); @@ -29,7 +27,8 @@ $info = $browscap->getBrowser(); Recommended Setup ----------------- -Before you can start, you have to download the browscap.ini file and convert it into a cache. There are two ways. +Before you can start, you have to run the `browscap:fetch` command to download the `browscap.ini` file, and use the +`browscap:convert` command to convert it into a cache. There are two ways. a. Download the file and convert it in two steps. The downloaded file will be stored in a local file, but there is no check if the remote file has changed. If your cache gets corrupted you only need to rerun the `convert` command. @@ -45,73 +44,74 @@ b. Download the file and convert it in one step. The downloaded file will not be ```php vendor/bin/browscap-php browscap:update ``` - -If you want to autoupdate the used cache, we recommend a separate cron job that calls the command listed above. - -What's changed in version 4.x ------------------------------ - -## BC breaks listed - - * Strict type hints have been added throughout. This may break some type assumptions made in earlier versions. - * `CheckUpdateCommand`, `ConvertCommand`, `LogfileCommand`, `ParserCommand`, `UpdateCommand` removed `setCache` methods - so that caches must now be constructor-injected - * Many classes are now `final` - use composition instead of inheritance - * `PropertyFormatter` now assumes any non-truthy values are `false` - * `checkUpdate` method now throws an exception if we could not determine the "remote" version, or if there is no - version in cache already. - * `log` method was removed - -## Changes - -* for caching the [Doctrine Cache](https://github.com/doctrine/cache) package is used - * Any other Cache compatible with [PSR-16](https://github.com/php-fig/simple-cache) could be used -* instead of the `debug` flag for the CLI commands the verbose flag has to be used +If you want to autoupdate the used cache, we recommend a separate cron job that calls the command listed above. -What's changed in version 3.x +BC breaks in version 6.0.x ----------------------------- -## Changes - -* the namespace was changed to `BrowscapPHP` -* the `Browscap` class was split into pieces - * for caching the [WurflCache](https://github.com/mimmi20/WurflCache) package is used - * for downloading the browscap.ini the [Guzzle HTTP](https://github.com/guzzle/guzzle) package is used - -## Removed features - -* the autoupdate function was removed -* all public properties were removed - -## New features - -* now it is possible to use other caches than the file cache (see the [WurflCache](https://github.com/mimmi20/WurflCache) package formore information) -* now it is possible to write your own formatter to change the output format -* now it is possbile to set a PSR-3 compatible logger +# Added +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapInterface#setFormatter() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapInterface#setParser() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapInterface#getParser() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapInterface#getBrowser() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Formatter\FormatterInterface#setData() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Formatter\FormatterInterface#getData() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\IniParser\ParserInterface#createIniParts() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\IniParser\ParserInterface#createPatterns() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Parser\ParserInterface#getBrowser() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Parser\Helper\GetDataInterface#getSettings() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Parser\Helper\GetPatternInterface#getPatterns() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapUpdaterInterface#convertFile() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapUpdaterInterface#convertString() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapUpdaterInterface#fetch() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapUpdaterInterface#update() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\BrowscapUpdaterInterface#checkUpdate() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#getVersion() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#getReleaseDate() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#getType() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#getItem() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#setItem() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#hasItem() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#removeItem() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Cache\BrowscapCacheInterface#flush() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\IniLoaderInterface#setRemoteFilename() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\IniLoaderInterface#getRemoteIniUrl() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\IniLoaderInterface#getRemoteTimeUrl() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\IniLoaderInterface#getRemoteVersionUrl() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\ConverterInterface#setFilesystem() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\ConverterInterface#convertFile() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\ConverterInterface#convertString() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\ConverterInterface#getIniVersion() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\ConverterInterface#setVersion() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\ConverterInterface#storeVersion() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\SupportInterface#getUserAgent() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\QuoterInterface#pregQuote() +- [BC] The @no-named-arguments annotation was added from BrowscapPHP\Helper\QuoterInterface#pregUnQuote() + +# Changed +- [BC] The parameter $content of BrowscapPHP\IniParser\ParserInterface#createPatterns() changed from no type to a non-contravariant string +- [BC] The parameter $content of BrowscapPHP\IniParser\ParserInterface#createPatterns() changed from no type to string +- [BC] The parameter $content of BrowscapPHP\IniParser\IniParser#createPatterns() changed from no type to a non-contravariant string +- [BC] The parameter $filename of BrowscapPHP\Helper\Filesystem#dumpFile() changed from no type to a non-contravariant string +- [BC] The parameter $filename of BrowscapPHP\Helper\Filesystem#dumpFile() changed from no type to string + +# Removed +- [BC] Constant BrowscapPHP\Data\PropertyHolder::TYPE_IN_ARRAY was removed +- [BC] Method BrowscapPHP\Data\PropertyHolder#checkValueInArray() was removed +- [BC] Method BrowscapPHP\Parser\Helper\GetDataInterface#__construct() was removed +- [BC] Method BrowscapPHP\Parser\Helper\GetPatternInterface#__construct() was removed +- [BC] Method BrowscapPHP\Cache\BrowscapCacheInterface#__construct() was removed Setup Examples -------------- -## Update your setup to version 4.x - -This is the base setup in version 3.x. -```php -$bc = new \BrowscapPHP\Browscap(); - -$adapter = new \WurflCache\Adapter\File([\WurflCache\Adapter\File::DIR => $cacheDir]); -$bc->setCache($adapter); - -$logger = new \Monolog\Logger('name'); -$bc->setLogger($logger); - -$result = $bc->getBrowser(); -``` - -Change this to the base setup for version 4.x. to use the current cache directory ```php -$fileCache = new \Doctrine\Common\Cache\FilesystemCache($cacheDir); -$cache = new \Roave\DoctrineSimpleCache\SimpleCacheAdapter($fileCache); +$fileCache = new \League\Flysystem\Local\LocalFilesystemAdapter($cacheDir); +$filesystem = new \League\Flysystem\Filesystem($fileCache); +$cache = new \MatthiasMullie\Scrapbook\Psr16\SimpleCache( + new \MatthiasMullie\Scrapbook\Adapters\Flysystem($filesystem) +); $logger = new \Monolog\Logger('name'); diff --git a/composer.json b/composer.json index 96596ed6..080338ec 100644 --- a/composer.json +++ b/composer.json @@ -1,15 +1,14 @@ { "name": "browscap/browscap-php", - "type": "library", "description": "Standalone replacement for php's native get_browser() function", + "license": "MIT", + "type": "library", "keywords": [ "get_browser", "browser", "capabilities", "user agent" ], - "homepage": "https://github.com/browscap/browscap-php", - "license": "MIT", "authors": [ { "name": "Jonathan Stoppani", @@ -24,39 +23,39 @@ "email": "mimmi20@live.de" } ], + "homepage": "https://github.com/browscap/browscap-php", + "support": { + "issues": "https://github.com/browscap/browscap-php/issues", + "source": "https://github.com/browscap/browscap-php" + }, "require": { - "php": ">=7.3.0,<8.1.0", + "php": ">=7.4.3,<8.2.0", "ext-json": "*", - "daverandom/exceptional-json": "^1.0.4", - "guzzlehttp/guzzle": "^6.5.2 || ^7.0", - "monolog/monolog": "^1.25.3 || ^2.0.2", + "guzzlehttp/guzzle": "^7.4.1", + "league/flysystem": "^2.3.2", + "matthiasmullie/scrapbook": "^1.4.8", + "monolog/monolog": "^2.3.5", + "psr/log": "^1.1.4 || ^2.0.0 || ^3.0.0", "psr/simple-cache": "^1.0.1", - "roave/doctrine-simplecache": "^2.2.0", - "symfony/console": "^3.4.36 || ^4.4.2 || ^5.0.2", - "symfony/filesystem": "^3.4.36 || ^4.4.2 || ^5.0.2" + "symfony/console": "^5.4.0", + "symfony/filesystem": "^5.4.0" }, "require-dev": { - "ergebnis/composer-normalize": "^2.2.2", - "friendsofphp/php-cs-fixer": "^2.16.1", - "mikey179/vfsstream": "^1.6.8", - "pepakriz/phpstan-exception-rules": "^0.11.1", - "phpstan/phpstan": "^0.12.9", - "phpstan/phpstan-beberlei-assert": "^0.12.2", - "phpstan/phpstan-deprecation-rules": "^0.12.2", - "phpstan/phpstan-phpunit": "^0.12.6", - "phpstan/phpstan-strict-rules": "^0.12.2", - "phpunit/phpunit": "^9.5.0" + "doctrine/coding-standard": "^9.0.0", + "ergebnis/composer-normalize": "^2.18.0", + "mikey179/vfsstream": "^v1.6.10", + "phpstan/extension-installer": "^1.1.0", + "phpstan/phpstan": "^1.2.0", + "phpstan/phpstan-beberlei-assert": "^1.0.0", + "phpstan/phpstan-deprecation-rules": "^1.0.0", + "phpstan/phpstan-phpunit": "^1.0.0", + "phpunit/phpunit": "^9.5.10" }, "suggest": { "ext-curl": "to use curl requests to get the ini file" }, - "config": { - "platform": { - "php": "7.4.0" - }, - "preferred-install": "dist", - "sort-packages": true - }, + "minimum-stability": "stable", + "prefer-stable": true, "autoload": { "psr-4": { "BrowscapPHP\\": "src/" @@ -67,13 +66,11 @@ "BrowscapPHPTest\\": "tests/" } }, - "minimum-stability": "stable", - "prefer-stable": true, "bin": [ "bin/browscap-php" ], - "support": { - "issues": "https://github.com/browscap/browscap-php/issues", - "source": "https://github.com/browscap/browscap-php" + "config": { + "preferred-install": "dist", + "sort-packages": true } } diff --git a/composer.lock b/composer.lock index fe34b1d4..259855fb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,142 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4df7a7c27712f916215b86325786e868", + "content-hash": "92afa09b145a244a63f1ae764ea3eff8", "packages": [ - { - "name": "daverandom/exceptional-json", - "version": "v1.0.4", - "source": { - "type": "git", - "url": "https://github.com/DaveRandom/ExceptionalJSON.git", - "reference": "fed957142b4687b079495c80975666dd1a67d61d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/DaveRandom/ExceptionalJSON/zipball/fed957142b4687b079495c80975666dd1a67d61d", - "reference": "fed957142b4687b079495c80975666dd1a67d61d", - "shasum": "" - }, - "require": { - "php": ">=7.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "ExceptionalJSON\\": "src/" - }, - "files": [ - "src/functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Chris Wright" - } - ], - "description": "JSON encoding and decoding that throws exceptions on failure", - "time": "2018-06-11T11:25:57+00:00" - }, - { - "name": "doctrine/cache", - "version": "1.10.2", - "source": { - "type": "git", - "url": "https://github.com/doctrine/cache.git", - "reference": "13e3381b25847283a91948d04640543941309727" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/cache/zipball/13e3381b25847283a91948d04640543941309727", - "reference": "13e3381b25847283a91948d04640543941309727", - "shasum": "" - }, - "require": { - "php": "~7.1 || ^8.0" - }, - "conflict": { - "doctrine/common": ">2.2,<2.4" - }, - "require-dev": { - "alcaeus/mongo-php-adapter": "^1.1", - "doctrine/coding-standard": "^6.0", - "mongodb/mongodb": "^1.1", - "phpunit/phpunit": "^7.0", - "predis/predis": "~1.0" - }, - "suggest": { - "alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.9.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Benjamin Eberlei", - "email": "kontakt@beberlei.de" - }, - { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Cache library is a popular cache implementation that supports many different drivers such as redis, memcache, apc, mongodb and others.", - "homepage": "https://www.doctrine-project.org/projects/cache.html", - "keywords": [ - "abstraction", - "apcu", - "cache", - "caching", - "couchdb", - "memcached", - "php", - "redis", - "xcache" - ], - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Fcache", - "type": "tidelift" - } - ], - "time": "2020-07-07T18:54:01+00:00" - }, { "name": "guzzlehttp/guzzle", "version": "7.4.1", @@ -244,6 +110,10 @@ "rest", "web service" ], + "support": { + "issues": "https://github.com/guzzle/guzzle/issues", + "source": "https://github.com/guzzle/guzzle/tree/7.4.1" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -324,6 +194,10 @@ "keywords": [ "promise" ], + "support": { + "issues": "https://github.com/guzzle/promises/issues", + "source": "https://github.com/guzzle/promises/tree/1.5.1" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -435,6 +309,10 @@ "uri", "url" ], + "support": { + "issues": "https://github.com/guzzle/psr7/issues", + "source": "https://github.com/guzzle/psr7/tree/2.1.0" + }, "funding": [ { "url": "https://github.com/GrahamCampbell", @@ -451,26 +329,264 @@ ], "time": "2021-10-06T17:43:30+00:00" }, + { + "name": "league/flysystem", + "version": "2.3.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "4b6da3e75b5e8eee53bb5ee46ded15a532843f80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4b6da3e75b5e8eee53bb5ee46ded15a532843f80", + "reference": "4b6da3e75b5e8eee53bb5ee46ded15a532843f80", + "shasum": "" + }, + "require": { + "ext-json": "*", + "league/mime-type-detection": "^1.0.0", + "php": "^7.2 || ^8.0" + }, + "conflict": { + "guzzlehttp/ringphp": "<1.1.1" + }, + "require-dev": { + "async-aws/s3": "^1.5", + "async-aws/simple-s3": "^1.0", + "aws/aws-sdk-php": "^3.132.4", + "composer/semver": "^3.0", + "ext-fileinfo": "*", + "friendsofphp/php-cs-fixer": "^3.2", + "google/cloud-storage": "^1.23", + "phpseclib/phpseclib": "^2.0", + "phpstan/phpstan": "^0.12.26", + "phpunit/phpunit": "^8.5 || ^9.4", + "sabre/dav": "^4.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "File storage abstraction for PHP", + "keywords": [ + "WebDAV", + "aws", + "cloud", + "file", + "files", + "filesystem", + "filesystems", + "ftp", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/2.3.2" + }, + "funding": [ + { + "url": "https://offset.earth/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2021-11-28T20:19:08+00:00" + }, + { + "name": "league/mime-type-detection", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/mime-type-detection.git", + "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69", + "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": "^7.2 || ^8.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "^3.2", + "phpstan/phpstan": "^0.12.68", + "phpunit/phpunit": "^8.5.8 || ^9.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\MimeTypeDetection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "Mime-type detection for Flysystem", + "support": { + "issues": "https://github.com/thephpleague/mime-type-detection/issues", + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.9.0" + }, + "funding": [ + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2021-11-21T11:48:40+00:00" + }, + { + "name": "matthiasmullie/scrapbook", + "version": "1.4.8", + "source": { + "type": "git", + "url": "https://github.com/matthiasmullie/scrapbook.git", + "reference": "df200ba063722798a73bc020ff154604830043d4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/matthiasmullie/scrapbook/zipball/df200ba063722798a73bc020ff154604830043d4", + "reference": "df200ba063722798a73bc020ff154604830043d4", + "shasum": "" + }, + "require": { + "php": ">=5.3.0", + "psr/cache": "~1.0", + "psr/simple-cache": "~1.0" + }, + "provide": { + "psr/cache-implementation": "~1.0", + "psr/simple-cache-implementation": "~1.0" + }, + "require-dev": { + "friendsofphp/php-cs-fixer": "~2.0", + "phpunit/phpunit": ">=4.8" + }, + "suggest": { + "ext-apc": ">=3.1.1", + "ext-couchbase": ">=2.0.0", + "ext-memcached": ">=2.0.0", + "ext-pdo": ">=0.1.0", + "ext-redis": ">=2.2.0 || 0.0.0.0", + "league/flysystem": "~1.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "MatthiasMullie\\Scrapbook\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Matthias Mullie", + "email": "scrapbook@mullie.eu", + "homepage": "https://www.mullie.eu", + "role": "Developer" + } + ], + "description": "Scrapbook is a PHP cache library, with adapters for e.g. Memcached, Redis, Couchbase, APC(u), SQL and additional capabilities (e.g. transactions, stampede protection) built on top.", + "homepage": "https://scrapbook.cash", + "keywords": [ + "Buffer", + "Flysystem", + "apc", + "buffered", + "cache", + "caching", + "commit", + "couchbase", + "filesystem", + "key", + "memcached", + "mitigation", + "mysql", + "postgresql", + "protection", + "psr-16", + "psr-6", + "psr-cache", + "psr-simple-cache", + "redis", + "rollback", + "sql", + "sqlite", + "stampede", + "store", + "transaction", + "transactional", + "value" + ], + "support": { + "issues": "https://github.com/matthiasmullie/scrapbook/issues", + "source": "https://github.com/matthiasmullie/scrapbook/tree/1.4.8" + }, + "funding": [ + { + "url": "https://github.com/matthiasmullie", + "type": "github" + } + ], + "time": "2021-01-27T18:04:01+00:00" + }, { "name": "monolog/monolog", - "version": "2.2.0", + "version": "2.3.5", "source": { "type": "git", "url": "https://github.com/Seldaek/monolog.git", - "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084" + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/monolog/zipball/1cb1cde8e8dd0f70cc0fe51354a59acad9302084", - "reference": "1cb1cde8e8dd0f70cc0fe51354a59acad9302084", + "url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd4380d6fc37626e2f799f29d91195040137eba9", + "reference": "fd4380d6fc37626e2f799f29d91195040137eba9", "shasum": "" }, "require": { "php": ">=7.2", - "psr/log": "^1.0.1" + "psr/log": "^1.0.1 || ^2.0 || ^3.0" }, "provide": { - "psr/log-implementation": "1.0.0" + "psr/log-implementation": "1.0.0 || 2.0.0 || 3.0.0" }, "require-dev": { "aws/aws-sdk-php": "^2.4.9 || ^3.0", @@ -478,14 +594,14 @@ "elasticsearch/elasticsearch": "^7", "graylog2/gelf-php": "^1.4.2", "mongodb/mongodb": "^1.8", - "php-amqplib/php-amqplib": "~2.4", + "php-amqplib/php-amqplib": "~2.4 || ^3", "php-console/php-console": "^3.1.3", "phpspec/prophecy": "^1.6.1", - "phpstan/phpstan": "^0.12.59", + "phpstan/phpstan": "^0.12.91", "phpunit/phpunit": "^8.5", "predis/predis": "^1.1", "rollbar/rollbar": "^1.3", - "ruflin/elastica": ">=0.90 <7.0.1", + "ruflin/elastica": ">=0.90@dev", "swiftmailer/swiftmailer": "^5.3|^6.0" }, "suggest": { @@ -493,8 +609,11 @@ "doctrine/couchdb": "Allow sending log messages to a CouchDB server", "elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client", "ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)", + "ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler", "ext-mbstring": "Allow to work properly with unicode symbols", "ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)", + "ext-openssl": "Required to send log messages using SSL", + "ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)", "graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server", "mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)", "php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib", @@ -531,6 +650,10 @@ "logging", "psr-3" ], + "support": { + "issues": "https://github.com/Seldaek/monolog/issues", + "source": "https://github.com/Seldaek/monolog/tree/2.3.5" + }, "funding": [ { "url": "https://github.com/Seldaek", @@ -541,29 +664,34 @@ "type": "tidelift" } ], - "time": "2020-12-14T13:15:25+00:00" + "time": "2021-10-01T21:08:31+00:00" }, { - "name": "psr/container", - "version": "1.1.1", + "name": "psr/cache", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf" + "url": "https://github.com/php-fig/cache.git", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/8622567409010282b7aeebe4bb841fe98b58dcaf", - "reference": "8622567409010282b7aeebe4bb841fe98b58dcaf", + "url": "https://api.github.com/repos/php-fig/cache/zipball/d11b50ad223250cf17b86e38383413f5a6764bf8", + "reference": "d11b50ad223250cf17b86e38383413f5a6764bf8", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=5.3.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, "autoload": { "psr-4": { - "Psr\\Container\\": "src/" + "Psr\\Cache\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -573,42 +701,95 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "homepage": "http://www.php-fig.org/" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", + "description": "Common interface for caching libraries", "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" + "cache", + "psr", + "psr-6" ], - "time": "2021-03-05T17:36:06+00:00" + "support": { + "source": "https://github.com/php-fig/cache/tree/master" + }, + "time": "2016-08-06T20:24:11+00:00" }, { - "name": "psr/http-client", - "version": "1.0.1", + "name": "psr/container", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", - "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "php": ">=7.4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common Container Interface (PHP FIG PSR-11)", + "homepage": "https://github.com/php-fig/container", + "keywords": [ + "PSR-11", + "container", + "container-interface", + "container-interop", + "psr" + ], + "support": { + "issues": "https://github.com/php-fig/container/issues", + "source": "https://github.com/php-fig/container/tree/2.0.2" + }, + "time": "2021-11-05T16:47:00+00:00" + }, + { + "name": "psr/http-client", + "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "reference": "2dfb5f6c5eff0e91e20e913f8c5452ed95b86621", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -634,6 +815,9 @@ "psr", "psr-18" ], + "support": { + "source": "https://github.com/php-fig/http-client/tree/master" + }, "time": "2020-06-29T06:28:15+00:00" }, { @@ -686,6 +870,9 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-factory/tree/master" + }, "time": "2019-04-30T12:38:16+00:00" }, { @@ -736,34 +923,37 @@ "request", "response" ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/master" + }, "time": "2016-08-06T14:39:51+00:00" }, { "name": "psr/log", - "version": "1.1.3", + "version": "2.0.0", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc" + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/0f73288fd15629204f9d42b7055f72dacbe811fc", - "reference": "0f73288fd15629204f9d42b7055f72dacbe811fc", + "url": "https://api.github.com/repos/php-fig/log/zipball/ef29f6d262798707a9edd554e2b82517ef3a9376", + "reference": "ef29f6d262798707a9edd554e2b82517ef3a9376", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=8.0.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { "psr-4": { - "Psr\\Log\\": "Psr/Log/" + "Psr\\Log\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -773,7 +963,7 @@ "authors": [ { "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "homepage": "https://www.php-fig.org/" } ], "description": "Common interface for logging libraries", @@ -783,7 +973,10 @@ "psr", "psr-3" ], - "time": "2020-03-23T09:12:05+00:00" + "support": { + "source": "https://github.com/php-fig/log/tree/2.0.0" + }, + "time": "2021-07-14T16:41:46+00:00" }, { "name": "psr/simple-cache", @@ -831,6 +1024,9 @@ "psr-16", "simple-cache" ], + "support": { + "source": "https://github.com/php-fig/simple-cache/tree/master" + }, "time": "2017-10-23T01:57:42+00:00" }, { @@ -871,83 +1067,37 @@ } ], "description": "A polyfill for getallheaders.", - "time": "2019-03-08T08:55:37+00:00" - }, - { - "name": "roave/doctrine-simplecache", - "version": "2.3.0", - "source": { - "type": "git", - "url": "https://github.com/Roave/DoctrineSimpleCache.git", - "reference": "165599198031cf2a14b52bc7de6eca970e9dfdf5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Roave/DoctrineSimpleCache/zipball/165599198031cf2a14b52bc7de6eca970e9dfdf5", - "reference": "165599198031cf2a14b52bc7de6eca970e9dfdf5", - "shasum": "" - }, - "require": { - "doctrine/cache": "^1.7", - "php": "^7.2,<7.5", - "psr/simple-cache": "^1.0" - }, - "provide": { - "psr/simple-cache-implementation": "1.0" - }, - "require-dev": { - "cache/integration-tests": "dev-master", - "cache/tag-interop": "dev-master", - "infection/infection": "^0.14.2", - "phpunit/phpunit": "^8.4", - "symfony/console": "^4.3", - "symfony/phpunit-bridge": "^4.4@dev" - }, - "type": "library", - "autoload": { - "psr-4": { - "Roave\\DoctrineSimpleCache\\": "src/" - }, - "files": [ - "namespace-bc-aliases.php" - ] + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "James Titcumb", - "email": "james@asgrim.com" - } - ], - "description": "Doctrine Cache adapter for PSR-16 Simple Cache", - "time": "2019-10-23T17:43:38+00:00" + "time": "2019-03-08T08:55:37+00:00" }, { "name": "symfony/console", - "version": "v5.2.1", + "version": "v5.4.1", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "47c02526c532fb381374dab26df05e7313978976" + "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/47c02526c532fb381374dab26df05e7313978976", - "reference": "47c02526c532fb381374dab26df05e7313978976", + "url": "https://api.github.com/repos/symfony/console/zipball/9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", + "reference": "9130e1a0fc93cb0faadca4ee917171bd2ca9e5f4", "shasum": "" }, "require": { "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php73": "^1.8", - "symfony/polyfill-php80": "^1.15", - "symfony/service-contracts": "^1.1|^2", - "symfony/string": "^5.1" + "symfony/polyfill-php73": "^1.9", + "symfony/polyfill-php80": "^1.16", + "symfony/service-contracts": "^1.1|^2|^3", + "symfony/string": "^5.1|^6.0" }, "conflict": { + "psr/log": ">=3", "symfony/dependency-injection": "<4.4", "symfony/dotenv": "<5.1", "symfony/event-dispatcher": "<4.4", @@ -955,16 +1105,16 @@ "symfony/process": "<4.4" }, "provide": { - "psr/log-implementation": "1.0" + "psr/log-implementation": "1.0|2.0" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/event-dispatcher": "^4.4|^5.0", - "symfony/lock": "^4.4|^5.0", - "symfony/process": "^4.4|^5.0", - "symfony/var-dumper": "^4.4|^5.0" + "psr/log": "^1|^2", + "symfony/config": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^4.4|^5.0|^6.0", + "symfony/event-dispatcher": "^4.4|^5.0|^6.0", + "symfony/lock": "^4.4|^5.0|^6.0", + "symfony/process": "^4.4|^5.0|^6.0", + "symfony/var-dumper": "^4.4|^5.0|^6.0" }, "suggest": { "psr/log": "For using the console logger", @@ -995,7 +1145,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Eases the creation of beautiful and testable command line interfaces", "homepage": "https://symfony.com", "keywords": [ "cli", @@ -1003,6 +1153,9 @@ "console", "terminal" ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1017,29 +1170,29 @@ "type": "tidelift" } ], - "time": "2020-12-18T08:03:05+00:00" + "time": "2021-12-09T11:22:43+00:00" }, { "name": "symfony/deprecation-contracts", - "version": "v2.2.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665" + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/5fa56b4074d1ae755beb55617ddafe6f5d78f665", - "reference": "5fa56b4074d1ae755beb55617ddafe6f5d78f665", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", + "reference": "c726b64c1ccfe2896cb7df2e1331c357ad1c8ced", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.0.2" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -1067,6 +1220,9 @@ ], "description": "A generic function and convention to trigger deprecation notices", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.0.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1081,25 +1237,27 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-11-01T23:48:49+00:00" }, { "name": "symfony/filesystem", - "version": "v5.2.4", + "version": "v5.4.0", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "710d364200997a5afde34d9fe57bd52f3cc1e108" + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/710d364200997a5afde34d9fe57bd52f3cc1e108", - "reference": "710d364200997a5afde34d9fe57bd52f3cc1e108", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/731f917dc31edcffec2c6a777f3698c33bea8f01", + "reference": "731f917dc31edcffec2c6a777f3698c33bea8f01", "shasum": "" }, "require": { "php": ">=7.2.5", - "symfony/polyfill-ctype": "~1.8" + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8", + "symfony/polyfill-php80": "^1.16" }, "type": "library", "autoload": { @@ -1126,6 +1284,9 @@ ], "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v5.4.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1140,20 +1301,20 @@ "type": "tidelift" } ], - "time": "2021-02-12T10:38:38+00:00" + "time": "2021-10-28T13:39:27+00:00" }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.1", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -1165,7 +1326,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1202,6 +1363,9 @@ "polyfill", "portable" ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1216,20 +1380,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-intl-grapheme", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-grapheme.git", - "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c" + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", - "reference": "c7cf3f858ec7d70b89559d6e6eb1f7c2517d479c", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/16880ba9c5ebe3642d1995ab866db29270b36535", + "reference": "16880ba9c5ebe3642d1995ab866db29270b36535", "shasum": "" }, "require": { @@ -1241,7 +1405,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1280,6 +1444,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1294,20 +1461,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-intl-normalizer", - "version": "v1.20.0", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-intl-normalizer.git", - "reference": "727d1096295d807c309fb01a851577302394c897" + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/727d1096295d807c309fb01a851577302394c897", - "reference": "727d1096295d807c309fb01a851577302394c897", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/8590a5f561694770bdcd3f9b5c69dde6945028e8", + "reference": "8590a5f561694770bdcd3f9b5c69dde6945028e8", "shasum": "" }, "require": { @@ -1319,7 +1486,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1361,6 +1528,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1375,20 +1545,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.20.0", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", - "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/9174a3d80210dca8daa7f31fec659150bbeabfc6", + "reference": "9174a3d80210dca8daa7f31fec659150bbeabfc6", "shasum": "" }, "require": { @@ -1400,7 +1570,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.20-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1438,6 +1608,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1452,20 +1625,20 @@ "type": "tidelift" } ], - "time": "2020-10-23T14:02:19+00:00" + "time": "2021-05-27T12:26:48+00:00" }, { "name": "symfony/polyfill-php73", - "version": "v1.22.1", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php73.git", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2" + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", - "reference": "a678b42e92f86eca04b7fa4c0f6f19d097fb69e2", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/fba8933c384d6476ab14fb7b8526e5287ca7e010", + "reference": "fba8933c384d6476ab14fb7b8526e5287ca7e010", "shasum": "" }, "require": { @@ -1474,7 +1647,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1514,6 +1687,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php73/tree/v1.23.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1528,20 +1704,20 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-php80", - "version": "v1.22.1", + "version": "v1.23.1", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91" + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dc3063ba22c2a1fd2f45ed856374d79114998f91", - "reference": "dc3063ba22c2a1fd2f45ed856374d79114998f91", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/1100343ed1a92e3a38f9ae122fc0eb21602547be", + "reference": "1100343ed1a92e3a38f9ae122fc0eb21602547be", "shasum": "" }, "require": { @@ -1550,7 +1726,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -1594,6 +1770,9 @@ "portable", "shim" ], + "support": { + "source": "https://github.com/symfony/polyfill-php80/tree/v1.23.1" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1608,25 +1787,28 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-07-28T13:41:28+00:00" }, { "name": "symfony/service-contracts", - "version": "v2.2.0", + "version": "v3.0.0", "source": { "type": "git", "url": "https://github.com/symfony/service-contracts.git", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1" + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/service-contracts/zipball/d15da7ba4957ffb8f1747218be9e1a121fd298a1", - "reference": "d15da7ba4957ffb8f1747218be9e1a121fd298a1", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/36715ebf9fb9db73db0cb24263c79077c6fe8603", + "reference": "36715ebf9fb9db73db0cb24263c79077c6fe8603", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.0" + "php": ">=8.0.2", + "psr/container": "^2.0" + }, + "conflict": { + "ext-psr": "<1.1|>=2" }, "suggest": { "symfony/service-implementation": "" @@ -1634,7 +1816,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "2.2-dev" + "dev-main": "3.0-dev" }, "thanks": { "name": "symfony/contracts", @@ -1670,6 +1852,9 @@ "interoperability", "standards" ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v3.0.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1684,35 +1869,37 @@ "type": "tidelift" } ], - "time": "2020-09-07T11:33:47+00:00" + "time": "2021-11-04T17:53:12+00:00" }, { "name": "symfony/string", - "version": "v5.2.1", + "version": "v6.0.0", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed" + "reference": "ba727797426af0f587f4800566300bdc0cda0777" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", - "reference": "5bd67751d2e3f7d6f770c9154b8fbcb2aa05f7ed", + "url": "https://api.github.com/repos/symfony/string/zipball/ba727797426af0f587f4800566300bdc0cda0777", + "reference": "ba727797426af0f587f4800566300bdc0cda0777", "shasum": "" }, "require": { - "php": ">=7.2.5", + "php": ">=8.0.2", "symfony/polyfill-ctype": "~1.8", "symfony/polyfill-intl-grapheme": "~1.0", "symfony/polyfill-intl-normalizer": "~1.0", - "symfony/polyfill-mbstring": "~1.0", - "symfony/polyfill-php80": "~1.15" + "symfony/polyfill-mbstring": "~1.0" + }, + "conflict": { + "symfony/translation-contracts": "<2.0" }, "require-dev": { - "symfony/error-handler": "^4.4|^5.0", - "symfony/http-client": "^4.4|^5.0", - "symfony/translation-contracts": "^1.1|^2", - "symfony/var-exporter": "^4.4|^5.0" + "symfony/error-handler": "^5.4|^6.0", + "symfony/http-client": "^5.4|^6.0", + "symfony/translation-contracts": "^2.0|^3.0", + "symfony/var-exporter": "^5.4|^6.0" }, "type": "library", "autoload": { @@ -1740,7 +1927,7 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony String component", + "description": "Provides an object-oriented API to strings and deals with bytes, UTF-8 code points and grapheme clusters in a unified way", "homepage": "https://symfony.com", "keywords": [ "grapheme", @@ -1750,6 +1937,9 @@ "utf-8", "utf8" ], + "support": { + "source": "https://github.com/symfony/string/tree/v6.0.0" + }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -1764,111 +1954,41 @@ "type": "tidelift" } ], - "time": "2020-12-05T07:33:16+00:00" + "time": "2021-10-29T07:35:21+00:00" } ], "packages-dev": [ { - "name": "composer/semver", - "version": "3.2.4", + "name": "dealerdirect/phpcodesniffer-composer-installer", + "version": "v0.7.1", "source": { "type": "git", - "url": "https://github.com/composer/semver.git", - "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464" + "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", - "reference": "a02fdf930a3c1c3ed3a49b5f63859c0c20e10464", + "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/fe390591e0241955f22eb9ba327d137e501c771c", + "reference": "fe390591e0241955f22eb9ba327d137e501c771c", "shasum": "" }, "require": { - "php": "^5.3.2 || ^7.0 || ^8.0" + "composer-plugin-api": "^1.0 || ^2.0", + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.0 || ^3.0 || ^4.0" }, "require-dev": { - "phpstan/phpstan": "^0.12.54", - "symfony/phpunit-bridge": "^4.2 || ^5" + "composer/composer": "*", + "phpcompatibility/php-compatibility": "^9.0", + "sensiolabs/security-checker": "^4.1.0" }, - "type": "library", + "type": "composer-plugin", "extra": { - "branch-alias": { - "dev-main": "3.x-dev" - } - }, - "autoload": { - "psr-4": { - "Composer\\Semver\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nils Adermann", - "email": "naderman@naderman.de", - "homepage": "http://www.naderman.de" - }, - { - "name": "Jordi Boggiano", - "email": "j.boggiano@seld.be", - "homepage": "http://seld.be" - }, - { - "name": "Rob Bast", - "email": "rob.bast@gmail.com", - "homepage": "http://robbast.nl" - } - ], - "description": "Semver library that offers utilities, version constraint parsing and validation.", - "keywords": [ - "semantic", - "semver", - "validation", - "versioning" - ], - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2020-11-13T08:59:24+00:00" - }, - { - "name": "composer/xdebug-handler", - "version": "1.4.5", - "source": { - "type": "git", - "url": "https://github.com/composer/xdebug-handler.git", - "reference": "f28d44c286812c714741478d968104c5e604a1d4" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/f28d44c286812c714741478d968104c5e604a1d4", - "reference": "f28d44c286812c714741478d968104c5e604a1d4", - "shasum": "" - }, - "require": { - "php": "^5.3.2 || ^7.0 || ^8.0", - "psr/log": "^1.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || 6.5 - 8" + "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" }, - "type": "library", "autoload": { "psr-4": { - "Composer\\XdebugHandler\\": "src" + "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -1877,96 +1997,91 @@ ], "authors": [ { - "name": "John Stevenson", - "email": "john-stevenson@blueyonder.co.uk" + "name": "Franck Nijhof", + "email": "franck.nijhof@dealerdirect.com", + "homepage": "http://www.frenck.nl", + "role": "Developer / IT Manager" } ], - "description": "Restarts a process without Xdebug.", + "description": "PHP_CodeSniffer Standards Composer Installer Plugin", + "homepage": "http://www.dealerdirect.com", "keywords": [ - "Xdebug", - "performance" - ], - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } - ], - "time": "2020-11-13T08:04:11+00:00" + "PHPCodeSniffer", + "PHP_CodeSniffer", + "code quality", + "codesniffer", + "composer", + "installer", + "phpcs", + "plugin", + "qa", + "quality", + "standard", + "standards", + "style guide", + "stylecheck", + "tests" + ], + "support": { + "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", + "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" + }, + "time": "2020-12-07T18:04:37+00:00" }, { - "name": "doctrine/annotations", - "version": "1.12.1", + "name": "doctrine/coding-standard", + "version": "9.0.0", "source": { "type": "git", - "url": "https://github.com/doctrine/annotations.git", - "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b" + "url": "https://github.com/doctrine/coding-standard.git", + "reference": "35a2452c6025cb739c3244b3348bcd1604df07d1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/annotations/zipball/b17c5014ef81d212ac539f07a1001832df1b6d3b", - "reference": "b17c5014ef81d212ac539f07a1001832df1b6d3b", + "url": "https://api.github.com/repos/doctrine/coding-standard/zipball/35a2452c6025cb739c3244b3348bcd1604df07d1", + "reference": "35a2452c6025cb739c3244b3348bcd1604df07d1", "shasum": "" }, "require": { - "doctrine/lexer": "1.*", - "ext-tokenizer": "*", - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/cache": "1.*", - "doctrine/coding-standard": "^6.0 || ^8.1", - "phpstan/phpstan": "^0.12.20", - "phpunit/phpunit": "^7.5 || ^9.1.5" - }, - "type": "library", - "autoload": { - "psr-4": { - "Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations" - } + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "php": "^7.1 || ^8.0", + "slevomat/coding-standard": "^7.0.0", + "squizlabs/php_codesniffer": "^3.6.0" }, + "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, { "name": "Benjamin Eberlei", "email": "kontakt@beberlei.de" }, { - "name": "Jonathan Wage", - "email": "jonwage@gmail.com" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" + "name": "Steve Müller", + "email": "st.mueller@dzh-online.de" } ], - "description": "Docblock Annotations Parser", - "homepage": "https://www.doctrine-project.org/projects/annotations.html", + "description": "The Doctrine Coding Standard is a set of PHPCS rules applied to all Doctrine projects.", + "homepage": "https://www.doctrine-project.org/projects/coding-standard.html", "keywords": [ - "annotations", - "docblock", - "parser" - ], - "time": "2021-02-21T21:00:45+00:00" + "checks", + "code", + "coding", + "cs", + "doctrine", + "rules", + "sniffer", + "sniffs", + "standard", + "style" + ], + "support": { + "issues": "https://github.com/doctrine/coding-standard/issues", + "source": "https://github.com/doctrine/coding-standard/tree/9.0.0" + }, + "time": "2021-04-12T15:11:14+00:00" }, { "name": "doctrine/instantiator", @@ -2017,6 +2132,10 @@ "constructor", "instantiate" ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.4.0" + }, "funding": [ { "url": "https://www.doctrine-project.org/sponsorship.html", @@ -2033,119 +2152,37 @@ ], "time": "2020-11-10T18:47:58+00:00" }, - { - "name": "doctrine/lexer", - "version": "1.2.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/lexer.git", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/lexer/zipball/e864bbf5904cb8f5bb334f99209b48018522f042", - "reference": "e864bbf5904cb8f5bb334f99209b48018522f042", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpstan/phpstan": "^0.11.8", - "phpunit/phpunit": "^8.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Common\\Lexer\\": "lib/Doctrine/Common/Lexer" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Guilherme Blanco", - "email": "guilhermeblanco@gmail.com" - }, - { - "name": "Roman Borschel", - "email": "roman@code-factory.org" - }, - { - "name": "Johannes Schmitt", - "email": "schmittjoh@gmail.com" - } - ], - "description": "PHP Doctrine Lexer parser library that can be used in Top-Down, Recursive Descent Parsers.", - "homepage": "https://www.doctrine-project.org/projects/lexer.html", - "keywords": [ - "annotations", - "docblock", - "lexer", - "parser", - "php" - ], - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Flexer", - "type": "tidelift" - } - ], - "time": "2020-05-25T17:44:05+00:00" - }, { "name": "ergebnis/composer-normalize", - "version": "2.13.3", + "version": "2.18.0", "source": { "type": "git", "url": "https://github.com/ergebnis/composer-normalize.git", - "reference": "eff003890c655ee0e4b6ac5d4c5b40ce61247f7c" + "reference": "294fcd40aa2ee991dfdfbd6a106dbee25f54c658" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/eff003890c655ee0e4b6ac5d4c5b40ce61247f7c", - "reference": "eff003890c655ee0e4b6ac5d4c5b40ce61247f7c", + "url": "https://api.github.com/repos/ergebnis/composer-normalize/zipball/294fcd40aa2ee991dfdfbd6a106dbee25f54c658", + "reference": "294fcd40aa2ee991dfdfbd6a106dbee25f54c658", "shasum": "" }, "require": { - "composer-plugin-api": "^1.1.0 || ^2.0.0", + "composer-plugin-api": "^2.0.0", "ergebnis/json-normalizer": "^1.0.3", "ergebnis/json-printer": "^3.1.1", - "justinrainbow/json-schema": "^5.2.10", + "justinrainbow/json-schema": "^5.2.11", "localheinz/diff": "^1.1.1", "php": "^7.2 || ^8.0" }, "require-dev": { - "composer/composer": "^1.10.19 || ^2.0.8", + "composer/composer": "^2.1.14", "ergebnis/license": "^1.1.0", - "ergebnis/php-cs-fixer-config": "^2.13.0", - "ergebnis/phpstan-rules": "~0.15.3", - "ergebnis/test-util": "^1.4.0", - "phpstan/extension-installer": "^1.1.0", - "phpstan/phpstan": "~0.12.80", - "phpstan/phpstan-deprecation-rules": "~0.12.6", - "phpstan/phpstan-phpunit": "~0.12.18", - "phpstan/phpstan-strict-rules": "~0.12.9", - "phpunit/phpunit": "^8.5.14", - "psalm/plugin-phpunit": "~0.15.0", - "symfony/filesystem": "^5.2.4", - "vimeo/psalm": "^4.6.2" + "ergebnis/php-cs-fixer-config": "^2.14.0", + "ergebnis/test-util": "^1.5.0", + "phpunit/phpunit": "^8.5.21", + "psalm/plugin-phpunit": "~0.16.1", + "symfony/filesystem": "^5.4.0", + "vimeo/psalm": "^4.14.0" }, "type": "composer-plugin", "extra": { @@ -2178,13 +2215,17 @@ "normalizer", "plugin" ], + "support": { + "issues": "https://github.com/ergebnis/composer-normalize/issues", + "source": "https://github.com/ergebnis/composer-normalize" + }, "funding": [ { "url": "https://github.com/localheinz", "type": "github" } ], - "time": "2021-03-06T14:00:23+00:00" + "time": "2021-12-08T09:16:32+00:00" }, { "name": "ergebnis/json-normalizer", @@ -2244,6 +2285,10 @@ "json", "normalizer" ], + "support": { + "issues": "https://github.com/ergebnis/json-normalizer/issues", + "source": "https://github.com/ergebnis/json-normalizer" + }, "funding": [ { "url": "https://github.com/localheinz", @@ -2309,6 +2354,10 @@ "json", "printer" ], + "support": { + "issues": "https://github.com/ergebnis/json-printer/issues", + "source": "https://github.com/ergebnis/json-printer" + }, "funding": [ { "url": "https://github.com/localheinz", @@ -2317,118 +2366,18 @@ ], "time": "2020-08-30T12:17:03+00:00" }, - { - "name": "friendsofphp/php-cs-fixer", - "version": "v2.18.4", - "source": { - "type": "git", - "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git", - "reference": "06f764e3cb6d60822d8f5135205f9d32b5508a31" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/06f764e3cb6d60822d8f5135205f9d32b5508a31", - "reference": "06f764e3cb6d60822d8f5135205f9d32b5508a31", - "shasum": "" - }, - "require": { - "composer/semver": "^1.4 || ^2.0 || ^3.0", - "composer/xdebug-handler": "^1.2", - "doctrine/annotations": "^1.2", - "ext-json": "*", - "ext-tokenizer": "*", - "php": "^5.6 || ^7.0 || ^8.0", - "php-cs-fixer/diff": "^1.3", - "symfony/console": "^3.4.43 || ^4.1.6 || ^5.0", - "symfony/event-dispatcher": "^3.0 || ^4.0 || ^5.0", - "symfony/filesystem": "^3.0 || ^4.0 || ^5.0", - "symfony/finder": "^3.0 || ^4.0 || ^5.0", - "symfony/options-resolver": "^3.0 || ^4.0 || ^5.0", - "symfony/polyfill-php70": "^1.0", - "symfony/polyfill-php72": "^1.4", - "symfony/process": "^3.0 || ^4.0 || ^5.0", - "symfony/stopwatch": "^3.0 || ^4.0 || ^5.0" - }, - "require-dev": { - "justinrainbow/json-schema": "^5.0", - "keradus/cli-executor": "^1.4", - "mikey179/vfsstream": "^1.6", - "php-coveralls/php-coveralls": "^2.4.2", - "php-cs-fixer/accessible-object": "^1.0", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "^1.2", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "^1.2.1", - "phpspec/prophecy-phpunit": "^1.1 || ^2.0", - "phpunit/phpunit": "^5.7.27 || ^6.5.14 || ^7.5.20 || ^8.5.13 || ^9.5", - "phpunitgoodpractices/polyfill": "^1.5", - "phpunitgoodpractices/traits": "^1.9.1", - "sanmai/phpunit-legacy-adapter": "^6.4 || ^8.2.1", - "symfony/phpunit-bridge": "^5.2.1", - "symfony/yaml": "^3.0 || ^4.0 || ^5.0" - }, - "suggest": { - "ext-dom": "For handling output formats in XML", - "ext-mbstring": "For handling non-UTF8 characters.", - "php-cs-fixer/phpunit-constraint-isidenticalstring": "For IsIdenticalString constraint.", - "php-cs-fixer/phpunit-constraint-xmlmatchesxsd": "For XmlMatchesXsd constraint.", - "symfony/polyfill-mbstring": "When enabling `ext-mbstring` is not possible." - }, - "bin": [ - "php-cs-fixer" - ], - "type": "application", - "autoload": { - "psr-4": { - "PhpCsFixer\\": "src/" - }, - "classmap": [ - "tests/Test/AbstractFixerTestCase.php", - "tests/Test/AbstractIntegrationCaseFactory.php", - "tests/Test/AbstractIntegrationTestCase.php", - "tests/Test/Assert/AssertTokensTrait.php", - "tests/Test/IntegrationCase.php", - "tests/Test/IntegrationCaseFactory.php", - "tests/Test/IntegrationCaseFactoryInterface.php", - "tests/Test/InternalIntegrationCaseFactory.php", - "tests/Test/IsIdenticalConstraint.php", - "tests/Test/TokensWithObservedTransformers.php", - "tests/TestCase.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Dariusz Rumiński", - "email": "dariusz.ruminski@gmail.com" - } - ], - "description": "A tool to automatically fix PHP code style", - "funding": [ - { - "url": "https://github.com/keradus", - "type": "github" - } - ], - "time": "2021-03-20T14:52:33+00:00" - }, { "name": "justinrainbow/json-schema", - "version": "5.2.10", + "version": "5.2.11", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b" + "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", - "reference": "2ba9c8c862ecd5510ed16c6340aa9f6eadb4f31b", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/2ab6744b7296ded80f8cc4f9509abbff393399aa", + "reference": "2ab6744b7296ded80f8cc4f9509abbff393399aa", "shasum": "" }, "require": { @@ -2481,7 +2430,11 @@ "json", "schema" ], - "time": "2020-05-27T16:41:55+00:00" + "support": { + "issues": "https://github.com/justinrainbow/json-schema/issues", + "source": "https://github.com/justinrainbow/json-schema/tree/5.2.11" + }, + "time": "2021-07-22T09:24:00+00:00" }, { "name": "localheinz/diff", @@ -2532,6 +2485,9 @@ "unidiff", "unified diff" ], + "support": { + "source": "https://github.com/localheinz/diff/tree/main" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -2542,16 +2498,16 @@ }, { "name": "mikey179/vfsstream", - "version": "v1.6.8", + "version": "v1.6.10", "source": { "type": "git", "url": "https://github.com/bovigo/vfsStream.git", - "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe" + "reference": "250c0825537d501e327df879fb3d4cd751933b85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/231c73783ebb7dd9ec77916c10037eff5a2b6efe", - "reference": "231c73783ebb7dd9ec77916c10037eff5a2b6efe", + "url": "https://api.github.com/repos/bovigo/vfsStream/zipball/250c0825537d501e327df879fb3d4cd751933b85", + "reference": "250c0825537d501e327df879fb3d4cd751933b85", "shasum": "" }, "require": { @@ -2584,7 +2540,12 @@ ], "description": "Virtual file system to mock the real file system in unit tests.", "homepage": "http://vfs.bovigo.org/", - "time": "2019-10-30T15:31:00+00:00" + "support": { + "issues": "https://github.com/bovigo/vfsStream/issues", + "source": "https://github.com/bovigo/vfsStream/tree/master", + "wiki": "https://github.com/bovigo/vfsStream/wiki" + }, + "time": "2021-09-25T08:05:01+00:00" }, { "name": "myclabs/deep-copy", @@ -2632,6 +2593,10 @@ "object", "object graph" ], + "support": { + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.10.2" + }, "funding": [ { "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", @@ -2642,16 +2607,16 @@ }, { "name": "nikic/php-parser", - "version": "v4.10.4", + "version": "v4.13.2", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e" + "reference": "210577fe3cf7badcc5814d99455df46564f3c077" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/c6d052fc58cb876152f89f532b95a8d7907e7f0e", - "reference": "c6d052fc58cb876152f89f532b95a8d7907e7f0e", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/210577fe3cf7badcc5814d99455df46564f3c077", + "reference": "210577fe3cf7badcc5814d99455df46564f3c077", "shasum": "" }, "require": { @@ -2690,73 +2655,24 @@ "parser", "php" ], - "time": "2020-12-20T10:01:03+00:00" - }, - { - "name": "pepakriz/phpstan-exception-rules", - "version": "v0.11.6", - "source": { - "type": "git", - "url": "https://github.com/pepakriz/phpstan-exception-rules.git", - "reference": "52a922396b448c8cbc78e4f2fc460d2f8958c99b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/pepakriz/phpstan-exception-rules/zipball/52a922396b448c8cbc78e4f2fc460d2f8958c99b", - "reference": "52a922396b448c8cbc78e4f2fc460d2f8958c99b", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.4", - "php": ">=7.1", - "phpstan/phpstan": "^0.12.26" - }, - "require-dev": { - "nette/utils": "^3.0", - "php-parallel-lint/php-console-highlighter": "^0.4.0", - "php-parallel-lint/php-parallel-lint": "^1.2.0", - "phpstan/phpstan-nette": "^0.12.0", - "phpstan/phpstan-phpunit": "^0.12.0", - "phpstan/phpstan-strict-rules": "^0.12.0", - "phpunit/phpunit": "^7.5.6 || ^9.4.2", - "slevomat/coding-standard": "^6.4.1", - "squizlabs/php_codesniffer": "~3.5.2" - }, - "type": "phpstan-extension", - "extra": { - "branch-alias": { - "dev-master": "0.11-dev" - }, - "phpstan": { - "includes": [ - "extension.neon" - ] - } - }, - "autoload": { - "psr-4": { - "Pepakriz\\PHPStanExceptionRules\\": "src" - } + "support": { + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v4.13.2" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Exception rules for PHPStan", - "time": "2021-01-27T17:23:33+00:00" + "time": "2021-11-30T19:35:32+00:00" }, { "name": "phar-io/manifest", - "version": "2.0.1", + "version": "2.0.3", "source": { "type": "git", "url": "https://github.com/phar-io/manifest.git", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + "reference": "97803eca37d319dfa7826cc2437fc020857acb53" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/97803eca37d319dfa7826cc2437fc020857acb53", + "reference": "97803eca37d319dfa7826cc2437fc020857acb53", "shasum": "" }, "require": { @@ -2799,20 +2715,24 @@ } ], "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2020-06-27T14:33:11+00:00" + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.3" + }, + "time": "2021-07-20T11:28:43+00:00" }, { "name": "phar-io/version", - "version": "3.0.4", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "e4782611070e50613683d2b9a57730e9a3ba5451" + "reference": "bae7c545bef187884426f042434e561ab1ddb182" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/e4782611070e50613683d2b9a57730e9a3ba5451", - "reference": "e4782611070e50613683d2b9a57730e9a3ba5451", + "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", + "reference": "bae7c545bef187884426f042434e561ab1ddb182", "shasum": "" }, "require": { @@ -2846,58 +2766,11 @@ } ], "description": "Library for handling version information and constraints", - "time": "2020-12-13T23:18:30+00:00" - }, - { - "name": "php-cs-fixer/diff", - "version": "v1.3.1", - "source": { - "type": "git", - "url": "https://github.com/PHP-CS-Fixer/diff.git", - "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/PHP-CS-Fixer/diff/zipball/dbd31aeb251639ac0b9e7e29405c1441907f5759", - "reference": "dbd31aeb251639ac0b9e7e29405c1441907f5759", - "shasum": "" - }, - "require": { - "php": "^5.6 || ^7.0 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^5.7.23 || ^6.4.3 || ^7.0", - "symfony/process": "^3.3" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.1.0" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - }, - { - "name": "SpacePossum" - } - ], - "description": "sebastian/diff v2 backport support for PHP5.6", - "homepage": "https://github.com/PHP-CS-Fixer", - "keywords": [ - "diff" - ], - "time": "2020-10-14T08:39:05+00:00" + "time": "2021-02-23T14:00:09+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -2946,20 +2819,24 @@ "reflection", "static analysis" ], + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", + "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" + }, "time": "2020-06-27T09:03:43+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "5.2.2", + "version": "5.3.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556" + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/069a785b2141f5bcf49f3e353548dc1cce6df556", - "reference": "069a785b2141f5bcf49f3e353548dc1cce6df556", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", + "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", "shasum": "" }, "require": { @@ -2970,7 +2847,8 @@ "webmozart/assert": "^1.9.1" }, "require-dev": { - "mockery/mockery": "~1.3.2" + "mockery/mockery": "~1.3.2", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -2998,20 +2876,24 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-09-03T19:13:55+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", + "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" + }, + "time": "2021-10-19T17:43:47+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "1.4.0", + "version": "1.5.1", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0" + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", - "reference": "6a467b8989322d92aa1c8bf2bebcc6e5c2ba55c0", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", "shasum": "" }, "require": { @@ -3019,7 +2901,8 @@ "phpdocumentor/reflection-common": "^2.0" }, "require-dev": { - "ext-tokenizer": "*" + "ext-tokenizer": "*", + "psalm/phar": "^4.8" }, "type": "library", "extra": { @@ -3043,37 +2926,41 @@ } ], "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-09-17T18:55:26+00:00" + "support": { + "issues": "https://github.com/phpDocumentor/TypeResolver/issues", + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + }, + "time": "2021-10-02T14:08:47+00:00" }, { "name": "phpspec/prophecy", - "version": "1.12.1", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/8ce87516be71aae9b956f81906aaf0338e0d8a2d", - "reference": "8ce87516be71aae9b956f81906aaf0338e0d8a2d", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.1", + "php": "^7.2 || ~8.0, <8.2", "phpdocumentor/reflection-docblock": "^5.2", "sebastian/comparator": "^3.0 || ^4.0", "sebastian/recursion-context": "^3.0 || ^4.0" }, "require-dev": { - "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0 || ^9.0 <9.3" + "phpspec/phpspec": "^6.0 || ^7.0", + "phpunit/phpunit": "^8.0 || ^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.11.x-dev" + "dev-master": "1.x-dev" } }, "autoload": { @@ -3106,20 +2993,118 @@ "spy", "stub" ], - "time": "2020-09-29T09:10:42+00:00" + "support": { + "issues": "https://github.com/phpspec/prophecy/issues", + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" + }, + "time": "2021-12-08T12:19:24+00:00" + }, + { + "name": "phpstan/extension-installer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/extension-installer.git", + "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/extension-installer/zipball/66c7adc9dfa38b6b5838a9fb728b68a7d8348051", + "reference": "66c7adc9dfa38b6b5838a9fb728b68a7d8348051", + "shasum": "" + }, + "require": { + "composer-plugin-api": "^1.1 || ^2.0", + "php": "^7.1 || ^8.0", + "phpstan/phpstan": ">=0.11.6" + }, + "require-dev": { + "composer/composer": "^1.8", + "phing/phing": "^2.16.3", + "php-parallel-lint/php-parallel-lint": "^1.2.0", + "phpstan/phpstan-strict-rules": "^0.11 || ^0.12" + }, + "type": "composer-plugin", + "extra": { + "class": "PHPStan\\ExtensionInstaller\\Plugin" + }, + "autoload": { + "psr-4": { + "PHPStan\\ExtensionInstaller\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Composer plugin for automatic installation of PHPStan extensions", + "support": { + "issues": "https://github.com/phpstan/extension-installer/issues", + "source": "https://github.com/phpstan/extension-installer/tree/1.1.0" + }, + "time": "2020-12-13T13:06:13+00:00" + }, + { + "name": "phpstan/phpdoc-parser", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpstan/phpdoc-parser.git", + "reference": "dbc093d7af60eff5cd575d2ed761b15ed40bd08e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpstan/phpdoc-parser/zipball/dbc093d7af60eff5cd575d2ed761b15ed40bd08e", + "reference": "dbc093d7af60eff5cd575d2ed761b15ed40bd08e", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "php-parallel-lint/php-parallel-lint": "^1.2", + "phpstan/extension-installer": "^1.0", + "phpstan/phpstan": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5", + "symfony/process": "^5.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "psr-4": { + "PHPStan\\PhpDocParser\\": [ + "src/" + ] + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "PHPDoc parser with support for nullable, intersection and generic types", + "support": { + "issues": "https://github.com/phpstan/phpdoc-parser/issues", + "source": "https://github.com/phpstan/phpdoc-parser/tree/1.2.0" + }, + "time": "2021-09-16T20:46:02+00:00" }, { "name": "phpstan/phpstan", - "version": "0.12.82", + "version": "1.2.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11" + "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/3920f0fb0aff39263d3a4cb0bca120a67a1a6a11", - "reference": "3920f0fb0aff39263d3a4cb0bca120a67a1a6a11", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", + "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", "shasum": "" }, "require": { @@ -3135,7 +3120,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "0.12-dev" + "dev-master": "1.2-dev" } }, "autoload": { @@ -3148,11 +3133,19 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "support": { + "issues": "https://github.com/phpstan/phpstan/issues", + "source": "https://github.com/phpstan/phpstan/tree/1.2.0" + }, "funding": [ { "url": "https://github.com/ondrejmirtes", "type": "github" }, + { + "url": "https://github.com/phpstan", + "type": "github" + }, { "url": "https://www.patreon.com/phpstan", "type": "patreon" @@ -3162,38 +3155,38 @@ "type": "tidelift" } ], - "time": "2021-03-19T06:08:17+00:00" + "time": "2021-11-18T14:09:01+00:00" }, { "name": "phpstan/phpstan-beberlei-assert", - "version": "0.12.6", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-beberlei-assert.git", - "reference": "daf1176ee507b7dcd01276fabf20a0a308c94124" + "reference": "b60cedb58a3668136977bf9e6e9bd7292391c78a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-beberlei-assert/zipball/daf1176ee507b7dcd01276fabf20a0a308c94124", - "reference": "daf1176ee507b7dcd01276fabf20a0a308c94124", + "url": "https://api.github.com/repos/phpstan/phpstan-beberlei-assert/zipball/b60cedb58a3668136977bf9e6e9bd7292391c78a", + "reference": "b60cedb58a3668136977bf9e6e9bd7292391c78a", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^0.12.40" + "phpstan/phpstan": "^1.0" }, "require-dev": { "beberlei/assert": "^3.3.0", - "phing/phing": "^2.16.3", + "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^0.12.16", - "phpstan/phpstan-strict-rules": "^0.12.5", - "phpunit/phpunit": "^7.5.20" + "phpstan/phpstan-phpunit": "^1.0", + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5" }, "type": "phpstan-extension", "extra": { "branch-alias": { - "dev-master": "0.12-dev" + "dev-master": "1.0-dev" }, "phpstan": { "includes": [ @@ -3211,36 +3204,39 @@ "MIT" ], "description": "PHPStan beberlei/assert extension", - "time": "2021-01-25T12:31:38+00:00" + "support": { + "issues": "https://github.com/phpstan/phpstan-beberlei-assert/issues", + "source": "https://github.com/phpstan/phpstan-beberlei-assert/tree/1.0.0" + }, + "time": "2021-10-14T08:11:20+00:00" }, { "name": "phpstan/phpstan-deprecation-rules", - "version": "0.12.6", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-deprecation-rules.git", - "reference": "46dbd43c2db973d2876d6653e53f5c2cc3a01fbb" + "reference": "e5ccafb0dd8d835dd65d8d7a1a0d2b1b75414682" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/46dbd43c2db973d2876d6653e53f5c2cc3a01fbb", - "reference": "46dbd43c2db973d2876d6653e53f5c2cc3a01fbb", + "url": "https://api.github.com/repos/phpstan/phpstan-deprecation-rules/zipball/e5ccafb0dd8d835dd65d8d7a1a0d2b1b75414682", + "reference": "e5ccafb0dd8d835dd65d8d7a1a0d2b1b75414682", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^0.12.60" + "phpstan/phpstan": "^1.0" }, "require-dev": { - "phing/phing": "^2.16.3", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^0.12", - "phpunit/phpunit": "^7.5.20" + "phpstan/phpstan-phpunit": "^1.0", + "phpunit/phpunit": "^9.5" }, "type": "phpstan-extension", "extra": { "branch-alias": { - "dev-master": "0.12-dev" + "dev-master": "1.0-dev" }, "phpstan": { "includes": [ @@ -3258,39 +3254,43 @@ "MIT" ], "description": "PHPStan rules for detecting usage of deprecated classes, methods, properties, constants and traits.", - "time": "2020-12-13T10:20:54+00:00" + "support": { + "issues": "https://github.com/phpstan/phpstan-deprecation-rules/issues", + "source": "https://github.com/phpstan/phpstan-deprecation-rules/tree/1.0.0" + }, + "time": "2021-09-23T11:02:21+00:00" }, { "name": "phpstan/phpstan-phpunit", - "version": "0.12.18", + "version": "1.0.0", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan-phpunit.git", - "reference": "ab44aec7cfb5cb267b8bc30a8caea86dd50d1f72" + "reference": "9eb88c9f689003a8a2a5ae9e010338ee94dc39b3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/ab44aec7cfb5cb267b8bc30a8caea86dd50d1f72", - "reference": "ab44aec7cfb5cb267b8bc30a8caea86dd50d1f72", + "url": "https://api.github.com/repos/phpstan/phpstan-phpunit/zipball/9eb88c9f689003a8a2a5ae9e010338ee94dc39b3", + "reference": "9eb88c9f689003a8a2a5ae9e010338ee94dc39b3", "shasum": "" }, "require": { "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^0.12.60" + "phpstan/phpstan": "^1.0" }, "conflict": { "phpunit/phpunit": "<7.0" }, "require-dev": { - "phing/phing": "^2.16.3", + "nikic/php-parser": "^4.13.0", "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-strict-rules": "^0.12.6", - "phpunit/phpunit": "^7.5.20" + "phpstan/phpstan-strict-rules": "^1.0", + "phpunit/phpunit": "^9.5" }, "type": "phpstan-extension", "extra": { "branch-alias": { - "dev-master": "0.12-dev" + "dev-master": "1.0-dev" }, "phpstan": { "includes": [ @@ -3309,74 +3309,31 @@ "MIT" ], "description": "PHPUnit extensions and rules for PHPStan", - "time": "2021-03-06T11:51:27+00:00" - }, - { - "name": "phpstan/phpstan-strict-rules", - "version": "0.12.9", - "source": { - "type": "git", - "url": "https://github.com/phpstan/phpstan-strict-rules.git", - "reference": "0705fefc7c9168529fd130e341428f5f10f4f01d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan-strict-rules/zipball/0705fefc7c9168529fd130e341428f5f10f4f01d", - "reference": "0705fefc7c9168529fd130e341428f5f10f4f01d", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0", - "phpstan/phpstan": "^0.12.66" - }, - "require-dev": { - "phing/phing": "^2.16.3", - "php-parallel-lint/php-parallel-lint": "^1.2", - "phpstan/phpstan-phpunit": "^0.12.16", - "phpunit/phpunit": "^7.5.20" - }, - "type": "phpstan-extension", - "extra": { - "branch-alias": { - "dev-master": "0.12-dev" - }, - "phpstan": { - "includes": [ - "rules.neon" - ] - } + "support": { + "issues": "https://github.com/phpstan/phpstan-phpunit/issues", + "source": "https://github.com/phpstan/phpstan-phpunit/tree/1.0.0" }, - "autoload": { - "psr-4": { - "PHPStan\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Extra strict and opinionated rules for PHPStan", - "time": "2021-01-13T08:50:28+00:00" + "time": "2021-10-14T08:03:54+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.5", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f3e026641cc91909d421802dd3ac7827ebfd97e1", - "reference": "f3e026641cc91909d421802dd3ac7827ebfd97e1", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.10.2", + "nikic/php-parser": "^4.13.0", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -3423,26 +3380,30 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-11-28T06:44:49+00:00" + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -3479,13 +3440,17 @@ "filesystem", "iterator" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -3538,6 +3503,10 @@ "keywords": [ "process" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3593,6 +3562,10 @@ "keywords": [ "template" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3648,6 +3621,10 @@ "keywords": [ "timer" ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/5.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3658,16 +3635,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.0", + "version": "9.5.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "8e16c225d57c3d6808014df6b1dd7598d0a5bbbe" + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/8e16c225d57c3d6808014df6b1dd7598d0a5bbbe", - "reference": "8e16c225d57c3d6808014df6b1dd7598d0a5bbbe", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", "shasum": "" }, "require": { @@ -3679,11 +3656,11 @@ "ext-xml": "*", "ext-xmlwriter": "*", "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.1", + "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", "phpspec/prophecy": "^1.12.1", - "phpunit/php-code-coverage": "^9.2.3", + "phpunit/php-code-coverage": "^9.2.7", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", "phpunit/php-text-template": "^2.0.3", @@ -3697,7 +3674,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^2.3", + "sebastian/type": "^2.3.4", "sebastian/version": "^3.0.2" }, "require-dev": { @@ -3743,6 +3720,10 @@ "testing", "xunit" ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + }, "funding": [ { "url": "https://phpunit.de/donate.html", @@ -3753,78 +3734,32 @@ "type": "github" } ], - "time": "2020-12-04T05:05:53+00:00" + "time": "2021-09-25T07:38:51+00:00" }, { - "name": "psr/event-dispatcher", - "version": "1.0.0", + "name": "sebastian/cli-parser", + "version": "1.0.1", "source": { "type": "git", - "url": "https://github.com/php-fig/event-dispatcher.git", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0" + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/event-dispatcher/zipball/dbefd12671e8a14ec7f180cab83036ed26714bb0", - "reference": "dbefd12671e8a14ec7f180cab83036ed26714bb0", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", + "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", "shasum": "" }, "require": { - "php": ">=7.2.0" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Psr\\EventDispatcher\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" - } - ], - "description": "Standard interfaces for event handling.", - "keywords": [ - "events", - "psr", - "psr-14" - ], - "time": "2019-01-08T18:20:26+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "1.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "reference": "442e7c7e687e42adc03470c7b668bc4b2402c0b2", - "shasum": "" - }, - "require": { - "php": ">=7.3" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "1.0-dev" } }, "autoload": { @@ -3845,6 +3780,10 @@ ], "description": "Library for parsing CLI options", "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/1.0.1" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3897,6 +3836,10 @@ ], "description": "Collection of value objects that represent the PHP code units", "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "source": "https://github.com/sebastianbergmann/code-unit/tree/1.0.8" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -3948,6 +3891,10 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/2.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4018,6 +3965,10 @@ "compare", "equality" ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.6" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4071,6 +4022,10 @@ ], "description": "Library for calculating the complexity of PHP code units", "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "source": "https://github.com/sebastianbergmann/complexity/tree/2.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4133,6 +4088,10 @@ "unidiff", "unified diff" ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4192,6 +4151,10 @@ "environment", "hhvm" ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4202,16 +4165,16 @@ }, { "name": "sebastian/exporter", - "version": "4.0.3", + "version": "4.0.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65" + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/d89cc98761b8cb5a1a235a6b703ae50d34080e65", - "reference": "d89cc98761b8cb5a1a235a6b703ae50d34080e65", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/65e8b7db476c5dd267e65eea9cab77584d3cfff9", + "reference": "65e8b7db476c5dd267e65eea9cab77584d3cfff9", "shasum": "" }, "require": { @@ -4260,31 +4223,35 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", + "homepage": "https://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "source": "https://github.com/sebastianbergmann/exporter/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-09-28T05:24:23+00:00" + "time": "2021-11-11T14:18:36+00:00" }, { "name": "sebastian/global-state", - "version": "5.0.2", + "version": "5.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455" + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a90ccbddffa067b51f574dea6eb25d5680839455", - "reference": "a90ccbddffa067b51f574dea6eb25d5680839455", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", "shasum": "" }, "require": { @@ -4325,13 +4292,17 @@ "keywords": [ "global state" ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-10-26T15:55:19+00:00" + "time": "2021-06-11T13:31:12+00:00" }, { "name": "sebastian/lines-of-code", @@ -4378,6 +4349,10 @@ ], "description": "Library for counting the lines of code in PHP source code", "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/1.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4431,6 +4406,10 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4482,6 +4461,10 @@ ], "description": "Allows reflection of object attributes, including inherited and non-public ones", "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/2.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4541,6 +4524,10 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4592,6 +4579,10 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "issues": "https://github.com/sebastianbergmann/resource-operations/issues", + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.3" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4602,16 +4593,16 @@ }, { "name": "sebastian/type", - "version": "2.3.1", + "version": "2.3.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2" + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/81cd61ab7bbf2de744aba0ea61fae32f721df3d2", - "reference": "81cd61ab7bbf2de744aba0ea61fae32f721df3d2", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8cd8a1c753c90bc1a0f5372170e3e489136f914", + "reference": "b8cd8a1c753c90bc1a0f5372170e3e489136f914", "shasum": "" }, "require": { @@ -4644,13 +4635,17 @@ ], "description": "Collection of value objects that represent the types of the PHP type system", "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "source": "https://github.com/sebastianbergmann/type/tree/2.3.4" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", "type": "github" } ], - "time": "2020-10-26T13:18:59+00:00" + "time": "2021-06-15T12:49:02+00:00" }, { "name": "sebastian/version", @@ -4693,6 +4688,10 @@ ], "description": "Library that helps with managing the version number of Git-hosted PHP projects", "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "source": "https://github.com/sebastianbergmann/version/tree/3.0.2" + }, "funding": [ { "url": "https://github.com/sebastianbergmann", @@ -4702,555 +4701,134 @@ "time": "2020-09-28T06:39:44+00:00" }, { - "name": "symfony/event-dispatcher", - "version": "v5.2.4", + "name": "slevomat/coding-standard", + "version": "7.0.18", "source": { "type": "git", - "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "d08d6ec121a425897951900ab692b612a61d6240" + "url": "https://github.com/slevomat/coding-standard.git", + "reference": "b81ac84f41a4797dc25c8ede1b0718e2a74be0fc" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/d08d6ec121a425897951900ab692b612a61d6240", - "reference": "d08d6ec121a425897951900ab692b612a61d6240", + "url": "https://api.github.com/repos/slevomat/coding-standard/zipball/b81ac84f41a4797dc25c8ede1b0718e2a74be0fc", + "reference": "b81ac84f41a4797dc25c8ede1b0718e2a74be0fc", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/event-dispatcher-contracts": "^2", - "symfony/polyfill-php80": "^1.15" - }, - "conflict": { - "symfony/dependency-injection": "<4.4" - }, - "provide": { - "psr/event-dispatcher-implementation": "1.0", - "symfony/event-dispatcher-implementation": "2.0" + "dealerdirect/phpcodesniffer-composer-installer": "^0.6.2 || ^0.7", + "php": "^7.1 || ^8.0", + "phpstan/phpdoc-parser": "^1.0.0", + "squizlabs/php_codesniffer": "^3.6.1" }, "require-dev": { - "psr/log": "~1.0", - "symfony/config": "^4.4|^5.0", - "symfony/dependency-injection": "^4.4|^5.0", - "symfony/error-handler": "^4.4|^5.0", - "symfony/expression-language": "^4.4|^5.0", - "symfony/http-foundation": "^4.4|^5.0", - "symfony/service-contracts": "^1.1|^2", - "symfony/stopwatch": "^4.4|^5.0" - }, - "suggest": { - "symfony/dependency-injection": "", - "symfony/http-kernel": "" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\EventDispatcher\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides tools that allow your application components to communicate with each other by dispatching events and listening to them", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-02-18T17:12:37+00:00" - }, - { - "name": "symfony/event-dispatcher-contracts", - "version": "v2.2.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/event-dispatcher-contracts.git", - "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher-contracts/zipball/0ba7d54483095a198fa51781bc608d17e84dffa2", - "reference": "0ba7d54483095a198fa51781bc608d17e84dffa2", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "psr/event-dispatcher": "^1" - }, - "suggest": { - "symfony/event-dispatcher-implementation": "" - }, - "type": "library", + "phing/phing": "2.17.0", + "php-parallel-lint/php-parallel-lint": "1.3.1", + "phpstan/phpstan": "1.2.0", + "phpstan/phpstan-deprecation-rules": "1.0.0", + "phpstan/phpstan-phpunit": "1.0.0", + "phpstan/phpstan-strict-rules": "1.1.0", + "phpunit/phpunit": "7.5.20|8.5.21|9.5.10" + }, + "type": "phpcodesniffer-standard", "extra": { "branch-alias": { - "dev-master": "2.2-dev" - }, - "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "dev-master": "7.x-dev" } }, "autoload": { "psr-4": { - "Symfony\\Contracts\\EventDispatcher\\": "" + "SlevomatCodingStandard\\": "SlevomatCodingStandard" } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Generic abstractions related to dispatching event", - "homepage": "https://symfony.com", - "keywords": [ - "abstractions", - "contracts", - "decoupling", - "interfaces", - "interoperability", - "standards" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2020-09-07T11:33:47+00:00" - }, - { - "name": "symfony/finder", - "version": "v5.2.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/finder.git", - "reference": "0d639a0943822626290d169965804f79400e6a04" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/0d639a0943822626290d169965804f79400e6a04", - "reference": "0d639a0943822626290d169965804f79400e6a04", - "shasum": "" - }, - "require": { - "php": ">=7.2.5" + "description": "Slevomat Coding Standard for PHP_CodeSniffer complements Consistence Coding Standard by providing sniffs with additional checks.", + "support": { + "issues": "https://github.com/slevomat/coding-standard/issues", + "source": "https://github.com/slevomat/coding-standard/tree/7.0.18" }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Finder\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Finds files and directories via an intuitive fluent interface", - "homepage": "https://symfony.com", "funding": [ { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", + "url": "https://github.com/kukulich", "type": "github" }, { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "url": "https://tidelift.com/funding/github/packagist/slevomat/coding-standard", "type": "tidelift" } ], - "time": "2021-02-15T18:55:04+00:00" + "time": "2021-12-07T17:19:06+00:00" }, { - "name": "symfony/options-resolver", - "version": "v5.2.4", + "name": "squizlabs/php_codesniffer", + "version": "3.6.1", "source": { "type": "git", - "url": "https://github.com/symfony/options-resolver.git", - "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce" + "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", + "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/options-resolver/zipball/5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce", - "reference": "5d0f633f9bbfcf7ec642a2b5037268e61b0a62ce", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f268ca40d54617c6e06757f83f699775c9b3ff2e", + "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/deprecation-contracts": "^2.1", - "symfony/polyfill-php73": "~1.0", - "symfony/polyfill-php80": "^1.15" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\OptionsResolver\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides an improved replacement for the array_replace PHP function", - "homepage": "https://symfony.com", - "keywords": [ - "config", - "configuration", - "options" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-01-27T12:56:27+00:00" - }, - { - "name": "symfony/polyfill-php70", - "version": "v1.20.0", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php70.git", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php70/zipball/5f03a781d984aae42cebd18e7912fa80f02ee644", - "reference": "5f03a781d984aae42cebd18e7912fa80f02ee644", - "shasum": "" - }, - "require": { - "php": ">=7.1" + "ext-simplexml": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": ">=5.4.0" }, - "type": "metapackage", - "extra": { - "branch-alias": { - "dev-main": "1.20-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "require-dev": { + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill backporting some PHP 7.0+ features to lower PHP versions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + "bin": [ + "bin/phpcs", + "bin/phpcbf" ], - "time": "2020-10-23T14:02:19+00:00" - }, - { - "name": "symfony/polyfill-php72", - "version": "v1.22.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-php72.git", - "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php72/zipball/cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", - "reference": "cc6e6f9b39fe8075b3dabfbaf5b5f645ae1340c9", - "shasum": "" - }, - "require": { - "php": ">=7.1" - }, "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "dev-master": "3.x-dev" } }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php72\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Nicolas Grekas", - "email": "p@tchwork.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" + "name": "Greg Sherwood", + "role": "lead" } ], - "description": "Symfony polyfill backporting some PHP 7.2+ features to lower PHP versions", - "homepage": "https://symfony.com", + "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ - "compatibility", - "polyfill", - "portable", - "shim" - ], - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-01-07T16:49:33+00:00" - }, - { - "name": "symfony/process", - "version": "v5.2.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/process.git", - "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/313a38f09c77fbcdc1d223e57d368cea76a2fd2f", - "reference": "313a38f09c77fbcdc1d223e57d368cea76a2fd2f", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.15" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Process\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Executes commands in sub-processes", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } + "phpcs", + "standards" ], - "time": "2021-01-27T10:15:41+00:00" - }, - { - "name": "symfony/stopwatch", - "version": "v5.2.4", - "source": { - "type": "git", - "url": "https://github.com/symfony/stopwatch.git", - "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/stopwatch/zipball/b12274acfab9d9850c52583d136a24398cdf1a0c", - "reference": "b12274acfab9d9850c52583d136a24398cdf1a0c", - "shasum": "" - }, - "require": { - "php": ">=7.2.5", - "symfony/service-contracts": "^1.0|^2" - }, - "type": "library", - "autoload": { - "psr-4": { - "Symfony\\Component\\Stopwatch\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "support": { + "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", + "source": "https://github.com/squizlabs/PHP_CodeSniffer", + "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Provides a way to profile code", - "homepage": "https://symfony.com", - "funding": [ - { - "url": "https://symfony.com/sponsor", - "type": "custom" - }, - { - "url": "https://github.com/fabpot", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", - "type": "tidelift" - } - ], - "time": "2021-01-27T10:15:41+00:00" + "time": "2021-10-11T04:00:11+00:00" }, { "name": "theseer/tokenizer", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/34a41e998c2183e22995f158c581e7b5e755ab9e", + "reference": "34a41e998c2183e22995f158c581e7b5e755ab9e", "shasum": "" }, "require": { @@ -5277,40 +4855,49 @@ } ], "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.1" + }, "funding": [ { "url": "https://github.com/theseer", "type": "github" } ], - "time": "2020-07-12T23:59:07+00:00" + "time": "2021-07-28T10:34:58+00:00" }, { "name": "webmozart/assert", - "version": "1.9.1", + "version": "1.10.0", "source": { "type": "git", "url": "https://github.com/webmozarts/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozarts/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, "conflict": { "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" + "vimeo/psalm": "<4.6.1 || 4.6.2" }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.10-dev" + } + }, "autoload": { "psr-4": { "Webmozart\\Assert\\": "src/" @@ -5332,7 +4919,11 @@ "check", "validate" ], - "time": "2020-07-08T17:02:28+00:00" + "support": { + "issues": "https://github.com/webmozarts/assert/issues", + "source": "https://github.com/webmozarts/assert/tree/1.10.0" + }, + "time": "2021-03-09T10:59:23+00:00" } ], "aliases": [], @@ -5341,12 +4932,9 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=7.3.0,<8.1.0", + "php": ">=7.4.3,<8.2.0", "ext-json": "*" }, "platform-dev": [], - "platform-overrides": { - "php": "7.4.0" - }, - "plugin-api-version": "1.1.0" + "plugin-api-version": "2.1.0" } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 00000000..80e86f0c --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,24 @@ + + + + + + + + + + + ./src + ./tests + + + + + + + + diff --git a/phpstan.neon b/phpstan.neon index 40837f4f..cad03fb1 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,23 +1,27 @@ parameters: - excludes_analyse: - - */tests/*/data/* - - */tests/*/Full2Test.php + level: max + parallel: + maximumNumberOfProcesses: 1 + processTimeout: 200.0 + paths: + - src + - tests + scanFiles: + - %currentWorkingDirectory%/vendor/autoload.php + - %currentWorkingDirectory%/vendor/squizlabs/php_codesniffer/autoload.php + - %currentWorkingDirectory%/vendor/squizlabs/php_codesniffer/src/Util/Tokens.php + checkGenericClassInNonGenericObjectType: false checkMissingIterableValueType: false -# exceptionRules: -# reportUnusedCatchesOfUncheckedExceptions: false -# uncheckedExceptions: [] + treatPhpDocTypesAsCertain: false + exceptions: + implicitThrows: false + checkedExceptionRegexes: + - '#Exception#' + - '#Throwable#' + check: + missingCheckedExceptionInThrows: true + tooWideThrowType: true ignoreErrors: - - '~MockObject~' - '~expects string, .*Exception given~' - '~expects string, Throwable given~' - '~Exception is not subtype of Throwable~' - - '~does not match assigned variable~' - - -#includes: -# - vendor/phpstan/phpstan-strict-rules/rules.neon -# - vendor/phpstan/phpstan-phpunit/extension.neon -# - vendor/phpstan/phpstan-phpunit/rules.neon -# - vendor/pepakriz/phpstan-exception-rules/extension.neon -# - vendor/phpstan/phpstan-deprecation-rules/rules.neon -# - vendor/phpstan/phpstan-beberlei-assert/extension.neon diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 9929a0ae..3f5df963 100644 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -9,9 +9,9 @@ beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutTodoAnnotatedTests="true" verbose="false" - colors="true" - failOnWarning="true" bootstrap="vendor/autoload.php" + failOnWarning="true" + failOnRisky="true" > @@ -23,9 +23,12 @@ tests/ - - + + src/ - - + + + + + diff --git a/src/Browscap.php b/src/Browscap.php index 4279fe3e..73c78d7a 100644 --- a/src/Browscap.php +++ b/src/Browscap.php @@ -1,13 +1,21 @@ cache = new BrowscapCache($cache, $logger); + $this->cache = new BrowscapCache($cache, $logger); $this->logger = $logger; $this->formatter = new Formatter\PhpGetBrowser(); @@ -57,9 +53,9 @@ public function __construct(CacheInterface $cache, LoggerInterface $logger) /** * Set theformatter instance to use for the getBrowser() result * - * @param \BrowscapPHP\Formatter\FormatterInterface $formatter + * @throws void */ - public function setFormatter(Formatter\FormatterInterface $formatter) : void + public function setFormatter(Formatter\FormatterInterface $formatter): void { $this->formatter = $formatter; } @@ -67,9 +63,9 @@ public function setFormatter(Formatter\FormatterInterface $formatter) : void /** * Sets the parser instance to use * - * @param \BrowscapPHP\Parser\ParserInterface $parser + * @throws void */ - public function setParser(ParserInterface $parser) : void + public function setParser(ParserInterface $parser): void { $this->parser = $parser; } @@ -77,13 +73,13 @@ public function setParser(ParserInterface $parser) : void /** * returns an instance of the used parser class * - * @return \BrowscapPHP\Parser\ParserInterface + * @throws void */ - public function getParser() : ParserInterface + public function getParser(): ParserInterface { - if (null === $this->parser) { + if ($this->parser === null) { $patternHelper = new Parser\Helper\GetPattern($this->cache, $this->logger); - $dataHelper = new Parser\Helper\GetData($this->cache, $this->logger, new Quoter()); + $dataHelper = new Parser\Helper\GetData($this->cache, $this->logger, new Quoter()); $this->parser = new Parser\Ini($patternHelper, $dataHelper, $this->formatter); } @@ -98,34 +94,34 @@ public function getParser() : ParserInterface * * @param string $userAgent the user agent string * - * @throws \BrowscapPHP\Exception + * @return stdClass the object containing the browsers details. * - * @return \stdClass the object containing the browsers details. + * @throws Exception */ - public function getBrowser(?string $userAgent = null) : \stdClass + public function getBrowser(?string $userAgent = null): stdClass { - if (null === $this->cache->getVersion()) { + if ($this->cache->getVersion() === null) { // there is no active/warm cache available throw new Exception('there is no active cache available, please use the BrowscapUpdater and run the update command'); } // Automatically detect the useragent if (! is_string($userAgent)) { - $support = new Helper\Support($_SERVER); + $support = new Helper\Support($_SERVER); $userAgent = $support->getUserAgent(); } try { // try to get browser data $formatter = $this->getParser()->getBrowser($userAgent); - } catch (\UnexpectedValueException $e) { + } catch (UnexpectedValueException $e) { $this->logger->error(sprintf('could not parse useragent "%s"', $userAgent)); $formatter = null; } // if return is still NULL, updates are disabled... in this // case we return an empty formatter instance - if (null === $formatter) { + if ($formatter === null) { $formatter = $this->formatter; } diff --git a/src/BrowscapInterface.php b/src/BrowscapInterface.php index 3aaf8cb3..ceaf1a13 100644 --- a/src/BrowscapInterface.php +++ b/src/BrowscapInterface.php @@ -1,9 +1,11 @@ cache = new BrowscapCache($cache, $logger); + $this->cache = new BrowscapCache($cache, $logger); $this->logger = $logger; - if (null === $client) { + if ($client === null) { $client = new Client(); } - $this->client = $client; + $this->client = $client; $this->connectTimeout = $connectTimeout; } /** * reads and parses an ini file and writes the results into the cache * - * @param string $iniFile - * - * @throws \BrowscapPHP\Exception\FileNameMissingException - * @throws \BrowscapPHP\Exception\FileNotFoundException - * @throws \BrowscapPHP\Exception\ErrorReadingFileException + * @throws FileNameMissingException + * @throws FileNotFoundException + * @throws ErrorReadingFileException */ - public function convertFile(string $iniFile) : void + public function convertFile(string $iniFile): void { if (empty($iniFile)) { throw new FileNameMissingException('the file name can not be empty'); } if (! is_readable($iniFile)) { - throw new FileNotFoundException('it was not possible to read the local file ' . $iniFile); + throw new FileNotFoundException( + sprintf('it was not possible to read the local file %s', $iniFile) + ); } $iniString = file_get_contents($iniFile); - if (false === $iniString) { + if ($iniString === false) { throw new ErrorReadingFileException('an error occured while converting the local file into the cache'); } @@ -109,9 +111,9 @@ public function convertFile(string $iniFile) : void /** * reads and parses an ini string and writes the results into the cache * - * @param string $iniString + * @throws void */ - public function convertString(string $iniString) : void + public function convertString(string $iniString): void { try { $cachedVersion = $this->cache->getItem('browscap.version', false, $success); @@ -121,6 +123,8 @@ public function convertString(string $iniString) : void return; } + assert($cachedVersion === null || is_int($cachedVersion)); + $converter = new Converter($this->logger, $this->cache); $this->storeContent($converter, $iniString, $cachedVersion); @@ -129,14 +133,14 @@ public function convertString(string $iniString) : void /** * fetches a remote file and stores it into a local folder * - * @param string $file The name of the file where to store the remote content + * @param string $file The name of the file where to store the remote content * @param string $remoteFile The code for the remote file to load * - * @throws \BrowscapPHP\Exception\FetcherException - * @throws \BrowscapPHP\Helper\Exception - * @throws \BrowscapPHP\Exception\ErrorCachedVersionException + * @throws FetcherException + * @throws Exception + * @throws ErrorCachedVersionException */ - public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP_INI) : void + public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP_INI): void { try { $cachedVersion = $this->checkUpdate(); @@ -154,9 +158,9 @@ public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP $uri = $loader->getRemoteIniUrl(); try { - /** @var \Psr\Http\Message\ResponseInterface $response */ $response = $this->client->request('get', $uri, ['connect_timeout' => $this->connectTimeout]); - } catch (\GuzzleHttp\Exception\GuzzleException $e) { + assert($response instanceof ResponseInterface); + } catch (GuzzleException $e) { throw new FetcherException( sprintf( 'an error occured while fetching remote data from URI %s', @@ -167,7 +171,7 @@ public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP ); } - if (200 !== $response->getStatusCode()) { + if ($response->getStatusCode() !== 200) { throw new FetcherException( sprintf( 'an error occured while fetching remote data from URI %s: StatusCode was %d', @@ -179,7 +183,7 @@ public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP try { $content = $response->getBody()->getContents(); - } catch (\Exception $e) { + } catch (Throwable $e) { throw new FetcherException('an error occured while fetching remote data', 0, $e); } @@ -201,12 +205,17 @@ public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP $content = $this->sanitizeContent($content); - $converter = new Converter($this->logger, $this->cache); + $converter = new Converter($this->logger, $this->cache); $iniVersion = $converter->getIniVersion($content); if ($iniVersion > $cachedVersion) { $fs = new Filesystem(); - $fs->dumpFile($file, $content); + + try { + $fs->dumpFile($file, $content); + } catch (IOException $exception) { + throw new FetcherException('an error occured while writing fetched data to local file', 0, $exception); + } } $this->logger->debug('finished storing remote file into local file'); @@ -219,11 +228,11 @@ public function fetch(string $file, string $remoteFile = IniLoaderInterface::PHP * * @param string $remoteFile The code for the remote file to load * - * @throws \BrowscapPHP\Exception\FetcherException - * @throws \BrowscapPHP\Helper\Exception - * @throws \BrowscapPHP\Exception\ErrorCachedVersionException + * @throws FetcherException + * @throws Exception + * @throws ErrorCachedVersionException */ - public function update(string $remoteFile = IniLoaderInterface::PHP_INI) : void + public function update(string $remoteFile = IniLoaderInterface::PHP_INI): void { $this->logger->debug('started fetching remote file'); @@ -241,9 +250,9 @@ public function update(string $remoteFile = IniLoaderInterface::PHP_INI) : void $uri = $loader->getRemoteIniUrl(); try { - /** @var \Psr\Http\Message\ResponseInterface $response */ $response = $this->client->request('get', $uri, ['connect_timeout' => $this->connectTimeout]); - } catch (\GuzzleHttp\Exception\GuzzleException $e) { + assert($response instanceof ResponseInterface); + } catch (GuzzleException $e) { throw new FetcherException( sprintf( 'an error occured while fetching remote data from URI %s', @@ -254,7 +263,7 @@ public function update(string $remoteFile = IniLoaderInterface::PHP_INI) : void ); } - if (200 !== $response->getStatusCode()) { + if ($response->getStatusCode() !== 200) { throw new FetcherException( sprintf( 'an error occured while fetching remote data from URI %s: StatusCode was %d', @@ -266,7 +275,7 @@ public function update(string $remoteFile = IniLoaderInterface::PHP_INI) : void try { $content = $response->getBody()->getContents(); - } catch (\Exception $e) { + } catch (Throwable $e) { throw new FetcherException('an error occured while fetching remote data', 0, $e); } @@ -288,14 +297,14 @@ public function update(string $remoteFile = IniLoaderInterface::PHP_INI) : void /** * checks if an update on a remote location for the local file or the cache * - * @throws \BrowscapPHP\Exception\FetcherException - * @throws \BrowscapPHP\Exception\NoCachedVersionException - * @throws \BrowscapPHP\Exception\ErrorCachedVersionException - * @throws \BrowscapPHP\Exception\NoNewVersionException - * * @return int|null The actual cached version if a newer version is available, null otherwise + * + * @throws FetcherException + * @throws NoCachedVersionException + * @throws ErrorCachedVersionException + * @throws NoNewVersionException */ - public function checkUpdate() : ?int + public function checkUpdate(): ?int { $success = null; @@ -305,6 +314,8 @@ public function checkUpdate() : ?int throw new ErrorCachedVersionException('an error occured while reading the data version from the cache', 0, $e); } + assert($cachedVersion === null || is_int($cachedVersion)); + if (! $cachedVersion) { // could not load version from cache throw new NoCachedVersionException('there is no cached version available, please update from remote'); @@ -313,9 +324,9 @@ public function checkUpdate() : ?int $uri = (new IniLoader())->getRemoteVersionUrl(); try { - /** @var \Psr\Http\Message\ResponseInterface $response */ $response = $this->client->request('get', $uri, ['connect_timeout' => $this->connectTimeout]); - } catch (\GuzzleHttp\Exception\GuzzleException $e) { + assert($response instanceof ResponseInterface); + } catch (GuzzleException $e) { throw new FetcherException( sprintf( 'an error occured while fetching version data from URI %s', @@ -326,7 +337,7 @@ public function checkUpdate() : ?int ); } - if (200 !== $response->getStatusCode()) { + if ($response->getStatusCode() !== 200) { throw new FetcherException( sprintf( 'an error occured while fetching version data from URI %s: StatusCode was %d', @@ -338,7 +349,7 @@ public function checkUpdate() : ?int try { $remoteVersion = $response->getBody()->getContents(); - } catch (\Throwable $e) { + } catch (Throwable $e) { throw new FetcherException( sprintf( 'an error occured while fetching version data from URI %s: StatusCode was %d', @@ -362,13 +373,20 @@ public function checkUpdate() : ?int } $this->logger->info( - 'a newer version is available, local version: ' . $cachedVersion . ', remote version: ' . $remoteVersion + sprintf( + 'a newer version is available, local version: %s, remote version: %s', + $cachedVersion, + $remoteVersion + ) ); return (int) $cachedVersion; } - private function sanitizeContent(string $content) : string + /** + * @throws void + */ + private function sanitizeContent(string $content): string { // replace everything between opening and closing php and asp tags $content = preg_replace('/<[?%].*[?%]>/', '', $content); @@ -380,18 +398,18 @@ private function sanitizeContent(string $content) : string /** * reads and parses an ini string and writes the results into the cache * - * @param \BrowscapPHP\Helper\ConverterInterface $converter - * @param string $content - * @param int|null $cachedVersion + * @throws void */ - private function storeContent(ConverterInterface $converter, string $content, ?int $cachedVersion) : void + private function storeContent(ConverterInterface $converter, string $content, ?int $cachedVersion): void { - $iniString = $this->sanitizeContent($content); + $iniString = $this->sanitizeContent($content); $iniVersion = $converter->getIniVersion($iniString); - if (! $cachedVersion || $iniVersion > $cachedVersion) { - $converter->storeVersion(); - $converter->convertString($iniString); + if ($cachedVersion && $iniVersion <= $cachedVersion) { + return; } + + $converter->storeVersion(); + $converter->convertString($iniString); } } diff --git a/src/BrowscapUpdaterInterface.php b/src/BrowscapUpdaterInterface.php index e2d5d03d..4a123e0d 100644 --- a/src/BrowscapUpdaterInterface.php +++ b/src/BrowscapUpdaterInterface.php @@ -1,9 +1,19 @@ cache = $adapter; + $this->cache = $adapter; $this->logger = $logger; } /** * Gets the version of the Browscap data * - * @return int + * @throws void */ - public function getVersion() : ?int + public function getVersion(): ?int { - if (null === $this->version) { + if ($this->version === null) { $success = null; try { - $version = $this->getItem('browscap.version', false, $success); + $cachedVersion = $this->getItem('browscap.version', false, $success); } catch (InvalidArgumentException $e) { $this->logger->error(new \InvalidArgumentException('an error occured while reading the data version from the cache', 0, $e)); - $version = null; + $cachedVersion = null; } - if (null !== $version && $success) { - $this->version = (int) $version; + assert($cachedVersion === null || is_int($cachedVersion)); + + if ($cachedVersion !== null && $success) { + $this->version = (int) $cachedVersion; } } @@ -86,11 +85,11 @@ public function getVersion() : ?int /** * Gets the release date of the Browscap data * - * @return string|null + * @throws void */ - public function getReleaseDate() : ?string + public function getReleaseDate(): ?string { - if (null === $this->releaseDate) { + if ($this->releaseDate === null) { $success = null; try { @@ -100,7 +99,9 @@ public function getReleaseDate() : ?string $releaseDate = null; } - if (null !== $releaseDate && $success) { + assert($releaseDate === null || is_string($releaseDate)); + + if ($releaseDate !== null && $success) { $this->releaseDate = $releaseDate; } } @@ -110,10 +111,12 @@ public function getReleaseDate() : ?string /** * Gets the type of the Browscap data + * + * @throws void */ - public function getType() : ?string + public function getType(): ?string { - if (null === $this->type) { + if ($this->type === null) { $success = null; try { @@ -123,7 +126,9 @@ public function getType() : ?string $type = null; } - if (null !== $type && $success) { + assert($type === null || is_string($type)); + + if ($type !== null && $success) { $this->type = $type; } } @@ -134,13 +139,9 @@ public function getType() : ?string /** * Get an item. * - * @param string $cacheId - * @param bool $withVersion - * @param bool $success - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * * @return mixed Data on success, null on failure + * + * @throws InvalidArgumentException */ public function getItem(string $cacheId, bool $withVersion = true, ?bool &$success = null) { @@ -170,15 +171,14 @@ public function getItem(string $cacheId, bool $withVersion = true, ?bool &$succe /** * save the content into an php file * - * @param string $cacheId The cache id - * @param mixed $content The content to store - * @param bool $withVersion - * - * @throws \Psr\SimpleCache\InvalidArgumentException + * @param string $cacheId The cache id + * @param mixed $content The content to store * * @return bool whether the file was correctly written to the disk + * + * @throws InvalidArgumentException */ - public function setItem(string $cacheId, $content, bool $withVersion = true) : bool + public function setItem(string $cacheId, $content, bool $withVersion = true): bool { // Get the whole PHP code $data = [ @@ -196,14 +196,9 @@ public function setItem(string $cacheId, $content, bool $withVersion = true) : b /** * Test if an item exists. * - * @param string $cacheId - * @param bool $withVersion - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * - * @return bool + * @throws InvalidArgumentException */ - public function hasItem(string $cacheId, bool $withVersion = true) : bool + public function hasItem(string $cacheId, bool $withVersion = true): bool { if ($withVersion) { $cacheId .= '.' . $this->getVersion(); @@ -215,14 +210,9 @@ public function hasItem(string $cacheId, bool $withVersion = true) : bool /** * Remove an item. * - * @param string $cacheId - * @param bool $withVersion - * - * @throws \Psr\SimpleCache\InvalidArgumentException - * - * @return bool + * @throws InvalidArgumentException */ - public function removeItem(string $cacheId, bool $withVersion = true) : bool + public function removeItem(string $cacheId, bool $withVersion = true): bool { if ($withVersion) { $cacheId .= '.' . $this->getVersion(); @@ -234,9 +224,9 @@ public function removeItem(string $cacheId, bool $withVersion = true) : bool /** * Flush the whole storage * - * @return bool + * @throws void */ - public function flush() : bool + public function flush(): bool { return $this->cache->clear(); } diff --git a/src/Cache/BrowscapCacheInterface.php b/src/Cache/BrowscapCacheInterface.php index e1f1c7f2..3f5793b1 100644 --- a/src/Cache/BrowscapCacheInterface.php +++ b/src/Cache/BrowscapCacheInterface.php @@ -1,102 +1,92 @@ defaultCacheFolder = $defaultCacheFolder; @@ -34,7 +49,10 @@ public function __construct(string $defaultCacheFolder) parent::__construct(); } - protected function configure() : void + /** + * @throws InvalidArgumentException + */ + protected function configure(): void { $this ->setName('browscap:check-update') @@ -49,19 +67,21 @@ protected function configure() : void } /** - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output - * - * @return int + * @throws InvalidArgumentException + * @throws \InvalidArgumentException */ - protected function execute(InputInterface $input, OutputInterface $output) : int + protected function execute(InputInterface $input, OutputInterface $output): int { $logger = LoggerHelper::createDefaultLogger($output); - /** @var string $cacheOption */ $cacheOption = $input->getOption('cache'); - $fileCache = new FilesystemCache($cacheOption); - $cache = new SimpleCacheAdapter($fileCache); + assert(is_string($cacheOption)); + + $adapter = new LocalFilesystemAdapter($cacheOption); + $filesystem = new Filesystem($adapter); + $cache = new SimpleCache( + new Flysystem($filesystem) + ); $logger->debug('started checking for new version of remote file'); @@ -70,28 +90,28 @@ protected function execute(InputInterface $input, OutputInterface $output) : int try { $browscap->checkUpdate(); } catch (NoCachedVersionException $e) { - return 1; + return self::NO_CACHED_VERSION; } catch (NoNewVersionException $e) { // no newer version available $logger->info('there is no newer version available'); - return 2; + return self::NO_NEWER_VERSION; } catch (ErrorCachedVersionException $e) { $logger->info($e); - return 3; + return self::ERROR_READING_CACHE; } catch (FetcherException $e) { $logger->info($e); - return 4; - } catch (\Throwable $e) { + return self::ERROR_READING_REMOTE_FILE; + } catch (Throwable $e) { $logger->info($e); - return 5; + return self::GENERIC_ERROR; } $logger->debug('finished checking for new version of remote file'); - return 0; + return self::SUCCESS; } } diff --git a/src/Command/ConvertCommand.php b/src/Command/ConvertCommand.php index 91f247ce..ed8e3403 100644 --- a/src/Command/ConvertCommand.php +++ b/src/Command/ConvertCommand.php @@ -1,43 +1,57 @@ defaultCacheFolder = $defaultCacheFolder; - $this->defaultIniFile = $defaultIniFile; + $this->defaultIniFile = $defaultIniFile; parent::__construct(); } - protected function configure() : void + /** + * @throws InvalidArgumentException + */ + protected function configure(): void { $this ->setName('browscap:convert') @@ -58,19 +72,21 @@ protected function configure() : void } /** - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output - * - * @return int + * @throws InvalidArgumentException + * @throws \InvalidArgumentException */ - protected function execute(InputInterface $input, OutputInterface $output) : int + protected function execute(InputInterface $input, OutputInterface $output): int { $logger = LoggerHelper::createDefaultLogger($output); - /** @var string $cacheOption */ $cacheOption = $input->getOption('cache'); - $fileCache = new FilesystemCache($cacheOption); - $cache = new SimpleCacheAdapter($fileCache); + assert(is_string($cacheOption)); + + $adapter = new LocalFilesystemAdapter($cacheOption); + $filesystem = new Filesystem($adapter); + $cache = new SimpleCache( + new Flysystem($filesystem) + ); $logger->info('initializing converting process'); @@ -78,12 +94,16 @@ protected function execute(InputInterface $input, OutputInterface $output) : int $logger->info('started converting local file'); - /** @var string $file */ $file = $input->getArgument('file'); + assert(is_string($file)); if (! $file) { $file = $this->defaultIniFile; } + if ($file === null) { + return self::FILENAME_MISSING; + } + $output->writeln(sprintf('converting file %s', $file)); try { @@ -91,19 +111,23 @@ protected function execute(InputInterface $input, OutputInterface $output) : int } catch (Exception\FileNameMissingException $e) { $logger->debug($e); - return 6; + return self::FILENAME_MISSING; } catch (Exception\FileNotFoundException $e) { $logger->debug($e); - return 7; + return self::FILE_NOT_FOUND; } catch (Exception\ErrorReadingFileException $e) { $logger->debug($e); - return 8; + return self::ERROR_READING_FILE; + } catch (Throwable $e) { + $logger->info($e); + + return CheckUpdateCommand::GENERIC_ERROR; } $logger->info('finished converting local file'); - return 0; + return self::SUCCESS; } } diff --git a/src/Command/FetchCommand.php b/src/Command/FetchCommand.php index 40588e78..ba5e1c35 100644 --- a/src/Command/FetchCommand.php +++ b/src/Command/FetchCommand.php @@ -1,46 +1,55 @@ defaultCacheFolder = $defaultCacheFolder; - $this->defaultIniFile = $defaultIniFile; + $this->defaultIniFile = $defaultIniFile; parent::__construct(); } - protected function configure() : void + /** + * @throws InvalidArgumentException + */ + protected function configure(): void { $this ->setName('browscap:fetch') @@ -55,8 +64,12 @@ protected function configure() : void 'remote-file', 'r', InputOption::VALUE_OPTIONAL, - 'browscap.ini file to download from remote location (possible values are: ' . IniLoaderInterface::PHP_INI_LITE - . ', ' . IniLoaderInterface::PHP_INI . ', ' . IniLoaderInterface::PHP_INI_FULL . ')', + sprintf( + 'browscap.ini file to download from remote location (possible values are: %s, %s, %s)', + IniLoaderInterface::PHP_INI_LITE, + IniLoaderInterface::PHP_INI, + IniLoaderInterface::PHP_INI_FULL + ), IniLoaderInterface::PHP_INI ) ->addOption( @@ -69,53 +82,59 @@ protected function configure() : void } /** - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output - * - * @return int + * @throws InvalidArgumentException + * @throws \InvalidArgumentException */ - protected function execute(InputInterface $input, OutputInterface $output) : int + protected function execute(InputInterface $input, OutputInterface $output): int { $logger = LoggerHelper::createDefaultLogger($output); - /** @var string $cacheOption */ $cacheOption = $input->getOption('cache'); - $fileCache = new FilesystemCache($cacheOption); - $cache = new SimpleCacheAdapter($fileCache); + assert(is_string($cacheOption)); + + $adapter = new LocalFilesystemAdapter($cacheOption); + $filesystem = new Filesystem($adapter); + $cache = new SimpleCache( + new Flysystem($filesystem) + ); - /** @var string $file */ $file = $input->getArgument('file'); + assert(is_string($file)); if (! $file) { $file = $this->defaultIniFile; } + if ($file === null) { + return ConvertCommand::FILENAME_MISSING; + } + $output->writeln(sprintf('write fetched file to %s', $file)); $logger->info('started fetching remote file'); $browscap = new BrowscapUpdater($cache, $logger); - /** @var string $remoteFileOption */ $remoteFileOption = $input->getOption('remote-file'); + assert(is_string($remoteFileOption)); try { $browscap->fetch($file, $remoteFileOption); } catch (ErrorCachedVersionException $e) { $logger->debug($e); - return 3; + return CheckUpdateCommand::ERROR_READING_CACHE; } catch (FetcherException $e) { $logger->debug($e); - return 9; - } catch (Exception $e) { - $logger->debug($e); + return CheckUpdateCommand::ERROR_READING_REMOTE_FILE; + } catch (Throwable $e) { + $logger->info($e); - return 10; + return CheckUpdateCommand::GENERIC_ERROR; } $logger->info('finished fetching remote file'); - return 0; + return self::SUCCESS; } } diff --git a/src/Command/ParserCommand.php b/src/Command/ParserCommand.php index d0b8bff5..8e9a5810 100644 --- a/src/Command/ParserCommand.php +++ b/src/Command/ParserCommand.php @@ -1,30 +1,44 @@ defaultCacheFolder = $defaultCacheFolder; @@ -32,7 +46,10 @@ public function __construct(string $defaultCacheFolder) parent::__construct(); } - protected function configure() : void + /** + * @throws InvalidArgumentException + */ + protected function configure(): void { $this ->setName('browscap:parse') @@ -53,41 +70,43 @@ protected function configure() : void } /** - * @param \Symfony\Component\Console\Input\InputInterface $input - * @param \Symfony\Component\Console\Output\OutputInterface $output - * - * @return int + * @throws InvalidArgumentException + * @throws \InvalidArgumentException */ - protected function execute(InputInterface $input, OutputInterface $output) : int + protected function execute(InputInterface $input, OutputInterface $output): int { $logger = LoggerHelper::createDefaultLogger($output); - /** @var string $cacheOption */ $cacheOption = $input->getOption('cache'); - $fileCache = new FilesystemCache($cacheOption); - $cache = new SimpleCacheAdapter($fileCache); + assert(is_string($cacheOption)); + + $adapter = new LocalFilesystemAdapter($cacheOption); + $filesystem = new Filesystem($adapter); + $cache = new SimpleCache( + new Flysystem($filesystem) + ); $browscap = new Browscap($cache, $logger); - /** @var string $uaArgument */ $uaArgument = $input->getArgument('user-agent'); + assert(is_string($uaArgument)); try { $result = $browscap->getBrowser($uaArgument); } catch (Exception $e) { $logger->debug($e); - return 11; + return self::PARSER_ERROR; } try { - $output->writeln(\ExceptionalJSON\encode($result, JSON_PRETTY_PRINT)); - } catch (EncodeErrorException $e) { + $output->writeln(json_encode($result, JSON_PRETTY_PRINT | JSON_THROW_ON_ERROR)); + } catch (JsonException $e) { $logger->error($e); - return 11; + return self::PARSER_ERROR; } - return 0; + return self::SUCCESS; } } diff --git a/src/Command/UpdateCommand.php b/src/Command/UpdateCommand.php index c5fa2d0b..6ad6c649 100644 --- a/src/Command/UpdateCommand.php +++ b/src/Command/UpdateCommand.php @@ -1,20 +1,29 @@ defaultCacheFolder = $defaultCacheFolder; @@ -34,7 +43,10 @@ public function __construct(string $defaultCacheFolder) parent::__construct(); } - protected function configure() : void + /** + * @throws InvalidArgumentException + */ + protected function configure(): void { $this ->setName('browscap:update') @@ -43,8 +55,12 @@ protected function configure() : void 'remote-file', 'r', InputOption::VALUE_OPTIONAL, - 'browscap.ini file to download from remote location (possible values are: ' . IniLoaderInterface::PHP_INI_LITE - . ', ' . IniLoaderInterface::PHP_INI . ', ' . IniLoaderInterface::PHP_INI_FULL . ')', + sprintf( + 'browscap.ini file to download from remote location (possible values are: %s, %s, %s)', + IniLoaderInterface::PHP_INI_LITE, + IniLoaderInterface::PHP_INI, + IniLoaderInterface::PHP_INI_FULL + ), IniLoaderInterface::PHP_INI ) ->addOption( @@ -62,40 +78,48 @@ protected function configure() : void ); } - protected function execute(InputInterface $input, OutputInterface $output) : int + /** + * @throws InvalidArgumentException + * @throws \InvalidArgumentException + */ + protected function execute(InputInterface $input, OutputInterface $output): int { $logger = LoggerHelper::createDefaultLogger($output); - /** @var string $cacheOption */ $cacheOption = $input->getOption('cache'); - $fileCache = new FilesystemCache($cacheOption); - $cache = new SimpleCacheAdapter($fileCache); + assert(is_string($cacheOption)); + + $adapter = new LocalFilesystemAdapter($cacheOption); + $filesystem = new Filesystem($adapter); + $cache = new SimpleCache( + new Flysystem($filesystem) + ); $logger->info('started updating cache with remote file'); $browscap = new BrowscapUpdater($cache, $logger); - /** @var string $remoteFileOption */ $remoteFileOption = $input->getOption('remote-file'); + assert(is_string($remoteFileOption)); try { $browscap->update($remoteFileOption); } catch (ErrorCachedVersionException $e) { $logger->debug($e); - return 3; + return CheckUpdateCommand::ERROR_READING_CACHE; } catch (FetcherException $e) { $logger->debug($e); - return 9; - } catch (Exception $e) { - $logger->debug($e); + return CheckUpdateCommand::ERROR_READING_REMOTE_FILE; + } catch (Throwable $e) { + $logger->info($e); - return 10; + return CheckUpdateCommand::GENERIC_ERROR; } $logger->info('finished updating cache with remote file'); - return 0; + return self::SUCCESS; } } diff --git a/src/Data/PropertyFormatter.php b/src/Data/PropertyFormatter.php index 6e9cdccf..28794882 100644 --- a/src/Data/PropertyFormatter.php +++ b/src/Data/PropertyFormatter.php @@ -1,19 +1,15 @@ propertyHolder->getPropertyType($property)) { - case PropertyHolder::TYPE_BOOLEAN: - if (true === $value || 'true' === $value || '1' === $value) { - return true; - } - - return false; - case PropertyHolder::TYPE_IN_ARRAY: - try { - return $this->propertyHolder->checkValueInArray($property, (string) $value); - } catch (\InvalidArgumentException $ex) { - // nothing to do here - } - - return ''; + if ($this->propertyHolder->getPropertyType($property) === PropertyHolder::TYPE_BOOLEAN) { + return $value === true || $value === 'true' || $value === '1'; } return $value; diff --git a/src/Data/PropertyHolder.php b/src/Data/PropertyHolder.php index 2105d542..2f9df110 100644 --- a/src/Data/PropertyHolder.php +++ b/src/Data/PropertyHolder.php @@ -1,24 +1,24 @@ 1, @@ -46,30 +46,6 @@ public function getPropertyType(string $propertyName) : string return self::TYPE_STRING; } - $arrayProperties = [ - 'Browser_Type' => 1, - 'Device_Type' => 1, - 'Device_Pointing_Method' => 1, - 'Browser_Bits' => 1, - 'Platform_Bits' => 1, - ]; - - if (array_key_exists($propertyName, $arrayProperties)) { - return self::TYPE_IN_ARRAY; - } - - $genericProperties = [ - 'Platform_Version' => 1, - 'RenderingEngine_Version' => 1, - 'Released' => 1, - 'Format' => 1, - 'Type' => 1, - ]; - - if (array_key_exists($propertyName, $genericProperties)) { - return self::TYPE_GENERIC; - } - $numericProperties = [ 'Version' => 1, 'CssVersion' => 1, @@ -116,90 +92,6 @@ public function getPropertyType(string $propertyName) : string return self::TYPE_BOOLEAN; } - throw new \InvalidArgumentException("Property {$propertyName} did not have a defined property type"); - } - - /** - * @param string $property - * @param string $value - * - * @throws \InvalidArgumentException - * - * @return string - */ - public function checkValueInArray(string $property, string $value) : string - { - switch ($property) { - case 'Browser_Type': - $allowedValues = [ - 'Useragent Anonymizer' => 1, - 'Browser' => 1, - 'Offline Browser' => 1, - 'Multimedia Player' => 1, - 'Library' => 1, - 'Feed Reader' => 1, - 'Email Client' => 1, - 'Bot/Crawler' => 1, - 'Application' => 1, - 'Tool' => 1, - 'unknown' => 1, - ]; - - break; - case 'Device_Type': - $allowedValues = [ - 'Console' => 1, - 'TV Device' => 1, - 'Tablet' => 1, - 'Mobile Phone' => 1, - 'Smartphone' => 1, // actual mobile phone with touchscreen - 'Feature Phone' => 1, // older mobile phone - 'Mobile Device' => 1, - 'FonePad' => 1, // Tablet sized device with the capability to make phone calls - 'Desktop' => 1, - 'Ebook Reader' => 1, - 'Car Entertainment System' => 1, - 'Digital Camera' => 1, - 'unknown' => 1, - ]; - - break; - case 'Device_Pointing_Method': - // This property is taken from http://www.scientiamobile.com/wurflCapability - $allowedValues = [ - 'joystick' => 1, - 'stylus' => 1, - 'touchscreen' => 1, - 'clickwheel' => 1, - 'trackpad' => 1, - 'trackball' => 1, - 'mouse' => 1, - 'unknown' => 1, - ]; - - break; - case 'Browser_Bits': - case 'Platform_Bits': - $allowedValues = [ - '0' => 1, - '8' => 1, - '16' => 1, - '32' => 1, - '64' => 1, - ]; - - break; - default: - throw new \InvalidArgumentException('Property "' . $property . '" is not defined to be validated'); - } - - if (array_key_exists($value, $allowedValues)) { - return $value; - } - - throw new \InvalidArgumentException( - 'invalid value given for Property "' . $property . '": given value "' . $value . '", allowed: ' - . \ExceptionalJSON\encode($allowedValues) - ); + return self::TYPE_GENERIC; } } diff --git a/src/Exception.php b/src/Exception.php index c6ea79b4..1531f51b 100644 --- a/src/Exception.php +++ b/src/Exception.php @@ -1,5 +1,6 @@ false, - ]; + private array $defaultOptions = ['lowercase' => false]; /** * Variable to save the settings in, type depends on implementation * - * @var array + * @var string[]|bool[]|null[] */ - private $data = []; + private array $data = []; /** - * LegacyFormatter constructor. + * @param bool[] $options Formatter options + * @phpstan-param array{lowercase?: bool} $options * - * @param array $options Formatter optioms + * @throws void */ public function __construct(array $options = []) { @@ -44,9 +52,11 @@ public function __construct(array $options = []) /** * Sets the data (done by the parser) * - * @param array $settings + * @param string[]|bool[]|null[] $settings + * + * @throws void */ - public function setData(array $settings) : void + public function setData(array $settings): void { $this->data = $settings; } @@ -54,14 +64,14 @@ public function setData(array $settings) : void /** * Gets the data (in the preferred format) * - * @return \stdClass + * @throws void */ - public function getData() : \stdClass + public function getData(): stdClass { - $output = new \stdClass(); + $output = new stdClass(); foreach ($this->data as $key => $property) { - if ($this->options['lowercase']) { + if (array_key_exists('lowercase', $this->options) && $this->options['lowercase']) { $key = strtolower($key); } diff --git a/src/Formatter/PhpGetBrowser.php b/src/Formatter/PhpGetBrowser.php index 5aecaee2..4fa1af3c 100644 --- a/src/Formatter/PhpGetBrowser.php +++ b/src/Formatter/PhpGetBrowser.php @@ -1,8 +1,15 @@ null, 'browser_name_pattern' => null, 'Parent' => null, @@ -76,9 +83,11 @@ final class PhpGetBrowser implements FormatterInterface /** * Sets the data (done by the parser) * - * @param array $settings + * @param string[]|bool[]|null[] $settings + * + * @throws void */ - public function setData(array $settings) : void + public function setData(array $settings): void { foreach ($settings as $key => $value) { $this->data[strtolower($key)] = $value; @@ -88,11 +97,11 @@ public function setData(array $settings) : void /** * Gets the data (in the preferred format) * - * @return \stdClass + * @throws void */ - public function getData() : \stdClass + public function getData(): stdClass { - $output = new \stdClass(); + $output = new stdClass(); $propertyNames = array_keys($this->defaultProperties); foreach ($propertyNames as $property) { @@ -100,7 +109,7 @@ public function getData() : \stdClass if (array_key_exists($key, $this->data)) { $output->{$key} = $this->data[$key]; - } elseif ('parent' !== $key) { + } elseif ($key !== 'parent') { $output->{$key} = $this->defaultProperties[$property]; } } diff --git a/src/Helper/Converter.php b/src/Helper/Converter.php index 43fbd31b..1d505027 100644 --- a/src/Helper/Converter.php +++ b/src/Helper/Converter.php @@ -1,5 +1,6 @@ logger = $logger; - $this->cache = $cache; + $this->logger = $logger; + $this->cache = $cache; $this->filessystem = new Filesystem(); } /** * Sets a filesystem instance * - * @param Filesystem $file + * @throws void */ - public function setFilesystem(Filesystem $file) : void + public function setFilesystem(Filesystem $file): void { $this->filessystem = $file; } @@ -72,12 +69,10 @@ public function setFilesystem(Filesystem $file) : void /** * converts a file * - * @param string $iniFile - * * @throws FileNotFoundException * @throws ErrorReadingFileException */ - public function convertFile(string $iniFile) : void + public function convertFile(string $iniFile): void { if (! $this->filessystem->exists($iniFile)) { throw FileNotFoundException::fileNotFound($iniFile); @@ -89,7 +84,7 @@ public function convertFile(string $iniFile) : void $this->logger->info('finished reading file'); - if (!is_string($iniString)) { + if (! is_string($iniString)) { throw new ErrorReadingFileException(sprintf('could not read file %s', $iniFile)); } @@ -99,16 +94,16 @@ public function convertFile(string $iniFile) : void /** * converts the string content * - * @param string $iniString + * @throws void */ - public function convertString(string $iniString) : void + public function convertString(string $iniString): void { $iniParser = new IniParser(); $this->logger->info('start creating patterns from the ini data'); foreach ($iniParser->createPatterns($iniString) as $subkey => $content) { - if ('' === $subkey) { + if ($subkey === '') { continue; } @@ -127,7 +122,7 @@ public function convertString(string $iniString) : void try { foreach ($iniParser->createIniParts($iniString) as $subkey => $content) { - if ('' === $subkey) { + if ($subkey === '') { continue; } @@ -139,7 +134,7 @@ public function convertString(string $iniString) : void $this->logger->error(new \InvalidArgumentException('an error occured while writing property data into the cache', 0, $e)); } } - } catch (\OutOfRangeException | \UnexpectedValueException $e) { + } catch (OutOfRangeException | UnexpectedValueException | JsonException | \InvalidArgumentException $e) { $this->logger->error(new \InvalidArgumentException('an error occured while writing property data into the cache', 0, $e)); } @@ -163,12 +158,12 @@ public function convertString(string $iniString) : void * * @param string $iniString The loaded ini data * - * @return int + * @throws void */ - public function getIniVersion(string $iniString) : int + public function getIniVersion(string $iniString): int { $quoterHelper = new Quoter(); - $key = $quoterHelper->pregQuote(self::BROWSCAP_VERSION_KEY); + $key = $quoterHelper->pregQuote(self::BROWSCAP_VERSION_KEY); if (preg_match('/\.*\[' . $key . '\][^\[]*Version=(\d+)\D.*/', $iniString, $matches)) { if (isset($matches[1])) { @@ -182,17 +177,19 @@ public function getIniVersion(string $iniString) : int /** * sets the version * - * @param int $version + * @throws void */ - public function setVersion(int $version) : void + public function setVersion(int $version): void { $this->iniVersion = $version; } /** * stores the version of the ini file into cache + * + * @throws void */ - public function storeVersion() : void + public function storeVersion(): void { try { $this->cache->setItem('browscap.version', $this->iniVersion, false); @@ -206,9 +203,9 @@ public function storeVersion() : void * * @param string $iniString The loaded ini data * - * @return string|null + * @throws void */ - private function getIniReleaseDate(string $iniString) : ?string + private function getIniReleaseDate(string $iniString): ?string { if (preg_match('/Released=(.*)/', $iniString, $matches)) { if (isset($matches[1])) { @@ -224,9 +221,9 @@ private function getIniReleaseDate(string $iniString) : ?string * * @param string $iniString The loaded ini data * - * @return string|null + * @throws void */ - private function getIniType(string $iniString) : ?string + private function getIniType(string $iniString): ?string { if (preg_match('/Type=(.*)/', $iniString, $matches)) { if (isset($matches[1])) { diff --git a/src/Helper/ConverterInterface.php b/src/Helper/ConverterInterface.php index 8f42d3c1..83ec7365 100644 --- a/src/Helper/ConverterInterface.php +++ b/src/Helper/ConverterInterface.php @@ -1,8 +1,12 @@ chmod($filename, $mode); + if ($mode === null) { + return; } + + $this->chmod($filename, $mode); } } diff --git a/src/Helper/IniLoader.php b/src/Helper/IniLoader.php index c3b0de58..d6ed87cf 100644 --- a/src/Helper/IniLoader.php +++ b/src/Helper/IniLoader.php @@ -1,8 +1,11 @@ remoteFilename, self::REMOTE_INI_URI); } @@ -64,9 +57,9 @@ public function getRemoteIniUrl() : string /** * returns the of the remote location for checking the version of the ini file * - * @return string + * @throws void */ - public function getRemoteTimeUrl() : string + public function getRemoteTimeUrl(): string { return self::REMOTE_TIME_URI; } @@ -74,9 +67,9 @@ public function getRemoteTimeUrl() : string /** * returns the of the remote location for checking the version of the ini file * - * @return string + * @throws void */ - public function getRemoteVersionUrl() : string + public function getRemoteVersionUrl(): string { return self::REMOTE_VERSION_URI; } diff --git a/src/Helper/IniLoaderInterface.php b/src/Helper/IniLoaderInterface.php index b433d2e2..e927b193 100644 --- a/src/Helper/IniLoaderInterface.php +++ b/src/Helper/IniLoaderInterface.php @@ -1,5 +1,6 @@ pushHandler($psrHandler); - /** @var callable $memoryProcessor */ $memoryProcessor = new MemoryUsageProcessor(true); + assert(is_callable($memoryProcessor)); $logger->pushProcessor($memoryProcessor); - /** @var callable $peakMemoryProcessor */ $peakMemoryProcessor = new MemoryPeakUsageProcessor(true); + assert(is_callable($peakMemoryProcessor)); $logger->pushProcessor($peakMemoryProcessor); ErrorHandler::register($logger); diff --git a/src/Helper/Quoter.php b/src/Helper/Quoter.php index c198a6fe..e236cc8a 100644 --- a/src/Helper/Quoter.php +++ b/src/Helper/Quoter.php @@ -1,8 +1,17 @@ ', '\\|', '\\:', '\\-', '\\.', '\\/', '\\#', + '\\\\', + '\\+', + '\\*', + '\\?', + '\\[', + '\\^', + '\\]', + '\\$', + '\\(', + '\\)', + '\\{', + '\\}', + '\\=', + '\\!', + '\\<', + '\\>', + '\\|', + '\\:', + '\\-', + '\\.', + '\\/', + '\\#', ], [ - '\\', '+', '*', '?', '[', '^', ']', '$', '(', ')', '{', '}', '=', - '!', '<', '>', '|', ':', '-', '.', '/', '#', + '\\', + '+', + '*', + '?', + '[', + '^', + ']', + '$', + '(', + ')', + '{', + '}', + '=', + '!', + '<', + '>', + '|', + ':', + '-', + '.', + '/', + '#', ], $pattern ); diff --git a/src/Helper/QuoterInterface.php b/src/Helper/QuoterInterface.php index c2c2a66e..3064672b 100644 --- a/src/Helper/QuoterInterface.php +++ b/src/Helper/QuoterInterface.php @@ -1,8 +1,11 @@ userAgentHeaders as $header) { - if (array_key_exists($header, $this->source) + if ( + array_key_exists($header, $this->source) && $this->source[$header] ) { $userAgent = $this->cleanParam($this->source[$header]); @@ -67,9 +74,9 @@ public function getUserAgent() : string * * @param string $param the value to be cleaned * - * @return string + * @throws void */ - private function cleanParam(string $param) : string + private function cleanParam(string $param): string { return strip_tags(trim(urldecode($param))); } diff --git a/src/Helper/SupportInterface.php b/src/Helper/SupportInterface.php index c8dff5b6..17ecdc00 100644 --- a/src/Helper/SupportInterface.php +++ b/src/Helper/SupportInterface.php @@ -1,5 +1,6 @@ $pattern) { - $pattern = strtolower($pattern); + $pattern = strtolower($pattern); $patternhash = Pattern::getHashForParts($pattern); - $subkey = SubKey::getIniPartCacheSubKey($patternhash); + $subkey = SubKey::getIniPartCacheSubKey($patternhash); if (! isset($contents[$subkey])) { $contents[$subkey] = []; } - if (!array_key_exists($position + 1, $iniParts)) { - throw new \OutOfRangeException(sprintf('could not find position %d inside iniparts', $position + 1)); + if (! array_key_exists($position + 1, $iniParts)) { + throw new OutOfRangeException(sprintf('could not find position %d inside iniparts', $position + 1)); } - $browserProperties = parse_ini_string($iniParts[($position + 1)], false, INI_SCANNER_RAW); + $browserProperties = parse_ini_string($iniParts[$position + 1], false, INI_SCANNER_RAW); - if (false === $browserProperties) { - throw new \UnexpectedValueException(sprintf('could ini parse position %d inside iniparts', $position + 1)); + if ($browserProperties === false) { + throw new UnexpectedValueException(sprintf('could ini parse position %d inside iniparts', $position + 1)); } foreach (array_keys($browserProperties) as $property) { @@ -83,12 +110,12 @@ public function createIniParts(string $content) : \Generator try { // the position has to be moved by one, because the header of the ini file // is also returned as a part - $contents[$subkey][] = $patternhash . "\t" . \ExceptionalJSON\encode( + $contents[$subkey][] = $patternhash . "\t" . json_encode( $browserProperties, - JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP + JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_THROW_ON_ERROR ); - } catch (EncodeErrorException $e) { - throw new \UnexpectedValueException('json encoding content failed', 0, $e); + } catch (JsonException $e) { + throw new UnexpectedValueException('json encoding content failed', 0, $e); } } @@ -111,11 +138,9 @@ public function createIniParts(string $content) : \Generator /** * Creates new pattern cache files * - * @param string $content - * - * @return \Generator + * @throws void */ - public function createPatterns($content) : \Generator + public function createPatterns(string $content): Generator { // get all relevant patterns from the INI file // - containing "*" or "?" @@ -133,7 +158,7 @@ public function createPatterns($content) : \Generator } $quoterHelper = new Quoter(); - $matches = $matches[0]; + $matches = $matches[0]; usort($matches, [$this, 'compareBcStrings']); // build an array to structure the data. this requires some memory, but we need this step to be able to @@ -141,16 +166,16 @@ public function createPatterns($content) : \Generator $data = []; foreach ($matches as $pattern) { - if ('GJK_Browscap_Version' === $pattern) { + if ($pattern === 'GJK_Browscap_Version') { continue; } - $pattern = strtolower($pattern); + $pattern = strtolower($pattern); $patternhash = Pattern::getHashForPattern($pattern, false)[0]; - $tmpLength = Pattern::getPatternLength($pattern); + $tmpLength = Pattern::getPatternLength($pattern); // special handling of default entry - if (0 === $tmpLength) { + if ($tmpLength === 0) { $patternhash = str_repeat('z', 32); } @@ -167,7 +192,7 @@ public function createPatterns($content) : \Generator // Check if the pattern contains digits - in this case we replace them with a digit regular expression, // so that very similar patterns (e.g. only with different browser version numbers) can be compressed. // This helps to speed up the first (and most expensive) part of the pattern search a lot. - if (false !== strpbrk($pattern, '0123456789')) { + if (strpbrk($pattern, '0123456789') !== false) { $compressedPattern = preg_replace('/\d/', '[\d]', $pattern); if (! in_array($compressedPattern, $data[$patternhash][$tmpLength])) { @@ -238,32 +263,29 @@ public function createPatterns($content) : \Generator } /** - * @param string $a - * @param string $b - * - * @return int + * @throws void */ - private function compareBcStrings(string $a, string $b) : int + private function compareBcStrings(string $a, string $b): int { - $a_len = strlen($a); - $b_len = strlen($b); + $aLength = strlen($a); + $bLength = strlen($b); - if ($a_len > $b_len) { + if ($aLength > $bLength) { return -1; } - if ($a_len < $b_len) { + if ($aLength < $bLength) { return 1; } - $a_len = strlen(str_replace(['*', '?'], '', $a)); - $b_len = strlen(str_replace(['*', '?'], '', $b)); + $aLength = strlen(str_replace(['*', '?'], '', $a)); + $bLength = strlen(str_replace(['*', '?'], '', $b)); - if ($a_len > $b_len) { + if ($aLength > $bLength) { return -1; } - if ($a_len < $b_len) { + if ($aLength < $bLength) { return 1; } diff --git a/src/IniParser/ParserInterface.php b/src/IniParser/ParserInterface.php index e7b13ca4..3dd701cf 100644 --- a/src/IniParser/ParserInterface.php +++ b/src/IniParser/ParserInterface.php @@ -1,9 +1,14 @@ cache = $cache; + $this->cache = $cache; $this->logger = $logger; $this->quoter = $quoter; } @@ -53,14 +56,13 @@ public function __construct(BrowscapCacheInterface $cache, LoggerInterface $logg * Gets the settings for a given pattern (method calls itself to * get the data from the parent patterns) * - * @param string $pattern - * @param array $settings + * @param string[] $settings * - * @throws \UnexpectedValueException + * @return string[] * - * @return array + * @throws UnexpectedValueException */ - public function getSettings(string $pattern, array $settings = []) : array + public function getSettings(string $pattern, array $settings = []): array { // The pattern has been pre-quoted on generation to speed up the pattern search, // but for this check we need the unquoted version @@ -70,14 +72,14 @@ public function getSettings(string $pattern, array $settings = []) : array $addedSettings = $this->getIniPart($unquotedPattern); // set some additional data - if (0 === count($settings)) { + if (count($settings) === 0) { // The optimization with replaced digits get can now result in setting searches, for which we // won't find a result - so only add the pattern information, is settings have been found. // // If not an empty array will be returned and the calling function can easily check if a pattern // has been found. if (0 < count($addedSettings)) { - $settings['browser_name_regex'] = '/^' . $pattern . '$/'; + $settings['browser_name_regex'] = '/^' . $pattern . '$/'; $settings['browser_name_pattern'] = $unquotedPattern; } } @@ -106,24 +108,39 @@ public function getSettings(string $pattern, array $settings = []) : array /** * Gets the relevant part (array of settings) of the ini file for a given pattern. * - * @param string $pattern + * @return string[] * - * @return array + * @throws void */ - private function getIniPart(string $pattern) : array + private function getIniPart(string $pattern): array { - $pattern = strtolower($pattern); + $pattern = strtolower($pattern); $patternhash = Pattern::getHashForParts($pattern); - $subkey = SubKey::getIniPartCacheSubKey($patternhash); + $subkey = SubKey::getIniPartCacheSubKey($patternhash); try { if (! $this->cache->hasItem('browscap.iniparts.' . $subkey, true)) { - $this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" not found'); + $this->logger->debug( + sprintf( + 'cache key "browscap.iniparts.%s" for pattern "%s" not found', + $subkey, + $pattern + ) + ); return []; } } catch (InvalidArgumentException $e) { - $this->logger->error(new \InvalidArgumentException('an error occured while checking a inipart in the cache', 0, $e)); + $this->logger->error( + new \InvalidArgumentException( + sprintf( + 'an error occured while checking inipart "browscap.iniparts.%s" in the cache', + $subkey + ), + 0, + $e + ) + ); return []; } @@ -133,38 +150,67 @@ private function getIniPart(string $pattern) : array try { $file = $this->cache->getItem('browscap.iniparts.' . $subkey, true, $success); } catch (InvalidArgumentException $e) { - $this->logger->error(new \InvalidArgumentException('an error occured while reading a inipart from the cache', 0, $e)); + $this->logger->error( + new \InvalidArgumentException( + sprintf( + 'an error occured while reading inipart "browscap.iniparts.%s" from the cache', + $subkey + ), + 0, + $e + ) + ); return []; } if (! $success) { - $this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" not found'); + $this->logger->debug( + sprintf( + 'cache key "browscap.iniparts.%s" for pattern "%s" not found', + $subkey, + $pattern + ) + ); return []; } if (! is_array($file) || ! count($file)) { - $this->logger->debug('cache key "browscap.iniparts.' . $subkey . '" was empty'); + $this->logger->debug( + sprintf( + 'cache key "browscap.iniparts.%s" for pattern "%s" was empty', + $subkey, + $pattern + ) + ); return []; } $propertyFormatter = new PropertyFormatter(new PropertyHolder()); - $return = []; + $return = []; foreach ($file as $buffer) { [$tmpBuffer, $patterns] = explode("\t", $buffer, 2); if ($tmpBuffer === $patternhash) { try { - $return = \ExceptionalJSON\decode($patterns, true); - } catch (DecodeErrorException $e) { - $this->logger->error('data for cache key "browscap.iniparts.' . $subkey . '" are not valid json'); + $return = json_decode($patterns, true, 512, JSON_THROW_ON_ERROR); + } catch (JsonException $e) { + $this->logger->error( + sprintf( + 'data for cache key "browscap.iniparts.%s" for pattern "%s" are not valid json', + $subkey, + $pattern + ) + ); return []; } + assert(is_array($return)); + foreach (array_keys($return) as $property) { $return[$property] = $propertyFormatter->formatPropertyValue( $return[$property], diff --git a/src/Parser/Helper/GetDataInterface.php b/src/Parser/Helper/GetDataInterface.php index 917f9756..eb34513a 100644 --- a/src/Parser/Helper/GetDataInterface.php +++ b/src/Parser/Helper/GetDataInterface.php @@ -1,36 +1,27 @@ cache = $cache; + $this->cache = $cache; $this->logger = $logger; } @@ -45,11 +48,9 @@ public function __construct(BrowscapCacheInterface $cache, LoggerInterface $logg * - We compare the length of the pattern with the length of the user agent * (the pattern cannot be longer than the user agent!) * - * @param string $userAgent - * - * @return \Generator + * @throws void */ - public function getPatterns(string $userAgent) : \Generator + public function getPatterns(string $userAgent): Generator { $starts = Pattern::getHashForPattern($userAgent, true); $length = strlen($userAgent); @@ -64,12 +65,27 @@ public function getPatterns(string $userAgent) : \Generator try { if (! $this->cache->hasItem('browscap.patterns.' . $tmpSubkey, true)) { - $this->logger->debug('cache key "browscap.patterns.' . $tmpSubkey . '" not found'); + $this->logger->debug( + sprintf( + 'cache key "browscap.patterns.%s" for useragent "%s" not found', + $tmpSubkey, + $userAgent + ) + ); continue; } } catch (InvalidArgumentException $e) { - $this->logger->error(new \InvalidArgumentException('an error occured while checking a pattern in the cache', 0, $e)); + $this->logger->error( + new \InvalidArgumentException( + sprintf( + 'an error occured while checking pattern "browscap.patterns.%s" in the cache', + $tmpSubkey + ), + 0, + $e + ) + ); continue; } @@ -79,19 +95,40 @@ public function getPatterns(string $userAgent) : \Generator try { $file = $this->cache->getItem('browscap.patterns.' . $tmpSubkey, true, $success); } catch (InvalidArgumentException $e) { - $this->logger->error(new \InvalidArgumentException('an error occured while reading the pattern data data from the cache', 0, $e)); + $this->logger->error( + new \InvalidArgumentException( + sprintf( + 'an error occured while reading pattern "browscap.patterns.%s" from the cache', + $tmpSubkey + ), + 0, + $e + ) + ); continue; } if (! $success) { - $this->logger->debug('cache key "browscap.patterns.' . $tmpSubkey . '" not found'); + $this->logger->debug( + sprintf( + 'cache key "browscap.patterns.%s" for useragent "%s" not found', + $tmpSubkey, + $userAgent + ) + ); continue; } if (! is_array($file) || ! count($file)) { - $this->logger->debug('cache key "browscap.patterns.' . $tmpSubkey . '" was empty'); + $this->logger->debug( + sprintf( + 'cache key "browscap.patterns.%s" for useragent "%s" was empty', + $tmpSubkey, + $userAgent + ) + ); continue; } @@ -107,7 +144,7 @@ public function getPatterns(string $userAgent) : \Generator } $found = true; - } elseif (true === $found) { + } elseif ($found === true) { break; } } diff --git a/src/Parser/Helper/GetPatternInterface.php b/src/Parser/Helper/GetPatternInterface.php index 99b4badf..76b82ffc 100644 --- a/src/Parser/Helper/GetPatternInterface.php +++ b/src/Parser/Helper/GetPatternInterface.php @@ -1,24 +1,16 @@ patternHelper = $patternHelper; - $this->dataHelper = $dataHelper; - $this->formatter = $formatter; + $this->dataHelper = $dataHelper; + $this->formatter = $formatter; } /** * Gets the browser data formatr for the given user agent * (or null if no data avaailble, no even the default browser) * - * @param string $userAgent - * - * @throws \UnexpectedValueException - * - * @return FormatterInterface|null + * @throws UnexpectedValueException */ - public function getBrowser(string $userAgent) : ?FormatterInterface + public function getBrowser(string $userAgent): ?FormatterInterface { $userAgent = strtolower($userAgent); $formatter = null; @@ -71,17 +66,17 @@ public function getBrowser(string $userAgent) : ?FormatterInterface // strtok() requires less memory than explode() $pattern = strtok($patterns, "\t"); - while (false !== $pattern) { - $pattern = str_replace('[\d]', '(\d)', $pattern); + while ($pattern !== false) { + $pattern = str_replace('[\d]', '(\d)', $pattern); $quotedPattern = '/^' . $pattern . '$/i'; - $matches = []; + $matches = []; if (preg_match($quotedPattern, $userAgent, $matches)) { // Insert the digits back into the pattern, so that we can search the settings for it if (1 < count($matches)) { array_shift($matches); foreach ($matches as $oneMatch) { - $numPos = (int) strpos($pattern, '(\d)'); + $numPos = (int) strpos($pattern, '(\d)'); $pattern = substr_replace($pattern, $oneMatch, $numPos, 4); } } diff --git a/src/Parser/ParserInterface.php b/src/Parser/ParserInterface.php index 3500bbe7..851a5b8b 100644 --- a/src/Parser/ParserInterface.php +++ b/src/Parser/ParserInterface.php @@ -1,9 +1,11 @@ createMock(CacheInterface::class); - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); $this->object = new Browscap($cache, $logger); } - public function testSetGetFormatter() : void + /** + * @throws ReflectionException + */ + public function testSetGetFormatter(): void { - /** @var FormatterInterface|\PHPUnit_Framework_MockObject_MockObject $formatter */ $formatter = $this->createMock(FormatterInterface::class); $this->object->setFormatter($formatter); - $property = new \ReflectionProperty($this->object, 'formatter'); + $property = new ReflectionProperty($this->object, 'formatter'); $property->setAccessible(true); self::assertSame($formatter, $property->getValue($this->object)); } - public function testGetParser() : void + /** + * @throws InvalidArgumentException + * @throws ExpectationFailedException + */ + public function testGetParser(): void { self::assertInstanceOf(Ini::class, $this->object->getParser()); } - public function testSetGetParser() : void + /** + * @throws InvalidArgumentException + * @throws ExpectationFailedException + */ + public function testSetGetParser(): void { - /** @var ParserInterface|\PHPUnit_Framework_MockObject_MockObject $parser */ $parser = $this->createMock(ParserInterface::class); $this->object->setParser($parser); self::assertSame($parser, $this->object->getParser()); } - public function testGetBrowserWithoutCache() : void + /** + * @throws Exception + */ + public function testGetBrowserWithoutCache(): void { $this->expectException(Exception::class); $this->expectExceptionMessage('there is no active cache available, please use the BrowscapUpdater and run the update command'); $this->object->getBrowser(); } - public function testGetBrowserWithoutUa() : void + /** + * @throws Exception + * @throws ReflectionException + */ + public function testGetBrowserWithoutUa(): void { - $expectedResult = new \stdClass(); - $expectedResult->parent = 'something'; + $expectedResult = new stdClass(); + $expectedResult->parent = 'something'; $expectedResult->comment = 'an comment'; - /** @var FormatterInterface|\PHPUnit_Framework_MockObject_MockObject $formatter */ $formatter = $this->createMock(FormatterInterface::class); $formatter->expects(self::once())->method('getData')->willReturn($expectedResult); - /** @var ParserInterface|\PHPUnit_Framework_MockObject_MockObject $parser */ $parser = $this->createMock(ParserInterface::class); $parser->expects(self::once())->method('getBrowser')->willReturn($formatter); - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getVersion')->willReturn(1); $this->object->setFormatter($formatter); $this->object->setParser($parser); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -98,28 +117,29 @@ public function testGetBrowserWithoutUa() : void self::assertSame($expectedResult, $result); } - public function testGetBrowserWithUa() : void + /** + * @throws Exception + * @throws ReflectionException + */ + public function testGetBrowserWithUa(): void { - $expectedResult = new \stdClass(); - $expectedResult->parent = 'something'; + $expectedResult = new stdClass(); + $expectedResult->parent = 'something'; $expectedResult->comment = 'an comment'; - /** @var FormatterInterface|\PHPUnit_Framework_MockObject_MockObject $formatter */ $formatter = $this->createMock(FormatterInterface::class); $formatter->expects(self::once())->method('getData')->willReturn($expectedResult); - /** @var ParserInterface|\PHPUnit_Framework_MockObject_MockObject $parser */ $parser = $this->createMock(ParserInterface::class); $parser->expects(self::once())->method('getBrowser')->willReturn($formatter); - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getVersion')->willReturn(1); $this->object->setFormatter($formatter); $this->object->setParser($parser); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -129,26 +149,27 @@ public function testGetBrowserWithUa() : void self::assertSame($expectedResult, $result); } - public function testGetBrowserWithDefaultResult() : void + /** + * @throws Exception + * @throws ReflectionException + */ + public function testGetBrowserWithDefaultResult(): void { - $expectedResult = new \stdClass(); + $expectedResult = new stdClass(); - /** @var FormatterInterface|\PHPUnit_Framework_MockObject_MockObject $formatter */ $formatter = $this->createMock(FormatterInterface::class); $formatter->expects(self::once())->method('getData')->willReturn($expectedResult); - /** @var ParserInterface|\PHPUnit_Framework_MockObject_MockObject $parser */ $parser = $this->createMock(ParserInterface::class); $parser->expects(self::once())->method('getBrowser')->willReturn(null); - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getVersion')->willReturn(1); $this->object->setFormatter($formatter); $this->object->setParser($parser); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); diff --git a/tests/BrowscapUpdaterTest.php b/tests/BrowscapUpdaterTest.php index 343f447a..a93bb6be 100644 --- a/tests/BrowscapUpdaterTest.php +++ b/tests/BrowscapUpdaterTest.php @@ -1,5 +1,6 @@ createMock(CacheInterface::class); - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); $this->object = new BrowscapUpdater($cache, $logger); } /** - * @throws \BrowscapPHP\Exception\FileNameMissingException - * @throws \BrowscapPHP\Exception\FileNotFoundException + * @throws FileNameMissingException + * @throws FileNotFoundException + * @throws ErrorReadingFileException */ - public function testConvertEmptyFile() : void + public function testConvertEmptyFile(): void { $this->expectException(BrowscapException\FileNameMissingException::class); $this->expectExceptionMessage('the file name can not be empty'); @@ -52,19 +66,26 @@ public function testConvertEmptyFile() : void } /** - * @throws \BrowscapPHP\Exception\FileNameMissingException - * @throws \BrowscapPHP\Exception\FileNotFoundException + * @throws FileNameMissingException + * @throws FileNotFoundException + * @throws ErrorReadingFileException */ - public function testConvertNotReadableFile() : void + public function testConvertNotReadableFile(): void { $this->expectException(BrowscapException\FileNotFoundException::class); $this->expectExceptionMessage('it was not possible to read the local file /this/file/does/not/exist'); $this->object->convertFile('/this/file/does/not/exist'); } - public function testConvertFile() : void + /** + * @throws FileNameMissingException + * @throws FileNotFoundException + * @throws ReflectionException + * @throws ErrorReadingFileException + */ + public function testConvertFile(): void { - $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version + $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version [GJK_Browscap_Version] Version=5031 @@ -168,29 +189,31 @@ public function testConvertFile() : void CssVersion=0 AolVersion=0 '; - $structure = [ - 'test.ini' => $content, - ]; + $structure = ['test.ini' => $content]; vfsStream::setup(self::STORAGE_DIR, null, $structure); - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); - $memoryCache = new ArrayCache(); - $cache = new BrowscapCache(new SimpleCacheAdapter($memoryCache), $logger); + $adapter = new SimpleCache( + new MemoryStore() + ); + $cache = new BrowscapCache($adapter, $logger); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); - $this->object->convertFile(vfsStream::url(self::STORAGE_DIR . \DIRECTORY_SEPARATOR . 'test.ini')); + $this->object->convertFile(vfsStream::url(self::STORAGE_DIR . DIRECTORY_SEPARATOR . 'test.ini')); self::assertSame(5031, $cache->getVersion()); } - public function testConvertString() : void + /** + * @throws ReflectionException + */ + public function testConvertString(): void { $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version @@ -297,13 +320,14 @@ public function testConvertString() : void AolVersion=0 '; - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); - $memoryCache = new ArrayCache(); - $cache = new BrowscapCache(new SimpleCacheAdapter($memoryCache), $logger); + $adapter = new SimpleCache( + new MemoryStore() + ); + $cache = new BrowscapCache($adapter, $logger); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -313,16 +337,21 @@ public function testConvertString() : void self::assertSame(5031, $cache->getVersion()); } - public function testFetchFail() : void + /** + * @throws \BrowscapPHP\Helper\Exception + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testFetchFail(): void { $response = $this->createMock(Response::class); $response->expects(self::exactly(2))->method('getStatusCode')->willReturn(500); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -342,12 +371,11 @@ public function testFetchFail() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -359,7 +387,13 @@ public function testFetchFail() : void $this->object->fetch(IniLoaderInterface::PHP_INI); } - public function testFetchOK() : void + /** + * @throws \BrowscapPHP\Helper\Exception + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testFetchOK(): void { $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version @@ -473,11 +507,10 @@ public function testFetchOK() : void $response->expects(self::once())->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -497,12 +530,11 @@ public function testFetchOK() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -514,7 +546,13 @@ public function testFetchOK() : void self::assertStringEqualsFile($file, $content); } - public function testFetchSanitizeOK() : void + /** + * @throws \BrowscapPHP\Helper\Exception + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testFetchSanitizeOK(): void { $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version @@ -733,11 +771,10 @@ public function testFetchSanitizeOK() : void $response->expects(self::once())->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -757,12 +794,11 @@ public function testFetchSanitizeOK() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -772,7 +808,13 @@ public function testFetchSanitizeOK() : void self::assertStringEqualsFile(IniLoaderInterface::PHP_INI, $expected); } - public function testUpdateFailException() : void + /** + * @throws \BrowscapPHP\Helper\Exception + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testUpdateFailException(): void { $body = $this->createMock(StreamInterface::class); $body->expects(self::once())->method('getContents')->willReturn(false); @@ -781,11 +823,10 @@ public function testUpdateFailException() : void $response->expects(self::once())->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -805,12 +846,11 @@ public function testUpdateFailException() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -820,7 +860,13 @@ public function testUpdateFailException() : void $this->object->update(); } - public function testUpdateOk() : void + /** + * @throws \BrowscapPHP\Helper\Exception + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testUpdateOk(): void { $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version @@ -934,11 +980,10 @@ public function testUpdateOk() : void $response->expects(self::once())->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -958,12 +1003,11 @@ public function testUpdateOk() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::exactly(4355))->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -971,7 +1015,14 @@ public function testUpdateOk() : void $this->object->update(); } - public function testCheckUpdateWithCacheFail() : void + /** + * @throws NoNewVersionException + * @throws NoCachedVersionException + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testCheckUpdateWithCacheFail(): void { $body = $this->createMock(StreamInterface::class); $body->expects(self::never())->method('getContents'); @@ -980,11 +1031,10 @@ public function testCheckUpdateWithCacheFail() : void $response->expects(self::never())->method('getStatusCode'); $response->expects(self::never())->method('getBody'); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::never())->method('request'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -1004,12 +1054,11 @@ public function testCheckUpdateWithCacheFail() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -1022,20 +1071,26 @@ public function testCheckUpdateWithCacheFail() : void $this->object->checkUpdate(); } - public function testCheckUpdateWithException() : void + /** + * @throws NoNewVersionException + * @throws NoCachedVersionException + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testCheckUpdateWithException(): void { $body = $this->createMock(StreamInterface::class); - $body->expects(self::once())->method('getContents')->willThrowException(new \Exception()); + $body->expects(self::once())->method('getContents')->willThrowException(new Exception()); $response = $this->createMock(Response::class); $response->expects(self::exactly(2))->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -1055,12 +1110,11 @@ public function testCheckUpdateWithException() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -1073,10 +1127,14 @@ public function testCheckUpdateWithException() : void } /** - * @throws \GuzzleHttp\Exception\GuzzleException - * @throws \ReflectionException + * @throws NoNewVersionException + * @throws NoCachedVersionException + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws GuzzleException + * @throws ReflectionException */ - public function testCheckUpdateWithoutNewerVersion() : void + public function testCheckUpdateWithoutNewerVersion(): void { $version = 6000; @@ -1087,11 +1145,10 @@ public function testCheckUpdateWithoutNewerVersion() : void $response->expects(self::once())->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -1111,12 +1168,11 @@ public function testCheckUpdateWithoutNewerVersion() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::once())->method('getItem')->willReturnMap($map); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); @@ -1129,7 +1185,14 @@ public function testCheckUpdateWithoutNewerVersion() : void $this->object->checkUpdate(); } - public function testCheckUpdateWithNewerVersion() : void + /** + * @throws NoNewVersionException + * @throws NoCachedVersionException + * @throws FetcherException + * @throws ErrorCachedVersionException + * @throws ReflectionException + */ + public function testCheckUpdateWithNewerVersion(): void { $body = $this->createMock(StreamInterface::class); $body->expects(self::once())->method('getContents')->willReturn(6001); @@ -1138,11 +1201,10 @@ public function testCheckUpdateWithNewerVersion() : void $response->expects(self::once())->method('getStatusCode')->willReturn(200); $response->expects(self::once())->method('getBody')->willReturn($body); - /** @var ClientInterface|\PHPUnit_Framework_MockObject_MockObject $client */ $client = $this->createMock(ClientInterface::class); $client->expects(self::once())->method('request')->willReturn($response); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('client'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $client); @@ -1162,13 +1224,12 @@ public function testCheckUpdateWithNewerVersion() : void ], ]; - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::any())->method('getItem')->willReturnMap($map); $cache->expects(self::any())->method('hasItem')->willReturn(true); $cache->expects(self::never())->method('setItem'); - $reflection = new \ReflectionClass($this->object); + $reflection = new ReflectionClass($this->object); $reflectionAttrbute = $reflection->getProperty('cache'); $reflectionAttrbute->setAccessible(true); $reflectionAttrbute->setValue($this->object, $cache); diff --git a/tests/Cache/.gitkeep b/tests/Cache/.gitkeep deleted file mode 100644 index e69de29b..00000000 diff --git a/tests/Cache/BrowscapCacheTest.php b/tests/Cache/BrowscapCacheTest.php index 4af8371f..8666df4a 100644 --- a/tests/Cache/BrowscapCacheTest.php +++ b/tests/Cache/BrowscapCacheTest.php @@ -1,38 +1,49 @@ createMock(LoggerInterface::class); - $memoryCache = new ArrayCache(); - $adapter = new SimpleCacheAdapter($memoryCache); - $cache = new BrowscapCache($adapter, $logger); + $adapter = new SimpleCache( + new MemoryStore() + ); + $cache = new BrowscapCache($adapter, $logger); self::assertInstanceOf(BrowscapCache::class, $cache); } - public function testVersion() : void + /** + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function testVersion(): void { - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); - $memoryCache = new ArrayCache(); - $adapter = new SimpleCacheAdapter($memoryCache); - $cache = new BrowscapCache($adapter, $logger); + $adapter = new SimpleCache( + new MemoryStore() + ); + $cache = new BrowscapCache($adapter, $logger); self::assertNull($cache->getVersion()); @@ -40,14 +51,17 @@ public function testVersion() : void self::assertSame(6012, $cache->getVersion()); } - public function testReleaseDate() : void + /** + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function testReleaseDate(): void { - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); - $memoryCache = new ArrayCache(); - $adapter = new SimpleCacheAdapter($memoryCache); - $cache = new BrowscapCache($adapter, $logger); + $adapter = new SimpleCache( + new MemoryStore() + ); + $cache = new BrowscapCache($adapter, $logger); self::assertNull($cache->getVersion()); @@ -55,14 +69,17 @@ public function testReleaseDate() : void self::assertSame('Thu, 04 Feb 2016 12:59:23 +0000', $cache->getReleaseDate()); } - public function testType() : void + /** + * @throws \Psr\SimpleCache\InvalidArgumentException + */ + public function testType(): void { - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); - $memoryCache = new ArrayCache(); - $adapter = new SimpleCacheAdapter($memoryCache); - $cache = new BrowscapCache($adapter, $logger); + $adapter = new SimpleCache( + new MemoryStore() + ); + $cache = new BrowscapCache($adapter, $logger); self::assertNull($cache->getType()); diff --git a/tests/Command/CheckUpdateCommandTest.php b/tests/Command/CheckUpdateCommandTest.php index 3cfac4ce..72479e6f 100644 --- a/tests/Command/CheckUpdateCommandTest.php +++ b/tests/Command/CheckUpdateCommandTest.php @@ -1,17 +1,24 @@ getMockBuilder(CheckUpdateCommand::class) ->disableOriginalConstructor() - ->setMethods(['setName', 'setDescription', 'addArgument', 'addOption']) + ->onlyMethods(['setName', 'setDescription', 'addArgument', 'addOption']) ->getMock(); $object ->expects(self::once()) @@ -30,7 +37,7 @@ public function testConfigure() : void ->method('addOption') ->willReturnSelf(); - $class = new \ReflectionClass(CheckUpdateCommand::class); + $class = new ReflectionClass(CheckUpdateCommand::class); $method = $class->getMethod('configure'); $method->setAccessible(true); diff --git a/tests/Command/ConvertCommandTest.php b/tests/Command/ConvertCommandTest.php index 8e9b546c..19432327 100644 --- a/tests/Command/ConvertCommandTest.php +++ b/tests/Command/ConvertCommandTest.php @@ -1,20 +1,27 @@ getMockBuilder(ConvertCommand::class) ->disableOriginalConstructor() - ->setMethods(['setName', 'setDescription', 'addArgument', 'addOption']) + ->onlyMethods(['setName', 'setDescription', 'addArgument', 'addOption']) ->getMock(); $object ->expects(self::once()) @@ -33,7 +40,7 @@ public function testConfigure() : void ->method('addOption') ->willReturnSelf(); - $class = new \ReflectionClass(ConvertCommand::class); + $class = new ReflectionClass(ConvertCommand::class); $method = $class->getMethod('configure'); $method->setAccessible(true); diff --git a/tests/Command/FetchCommandTest.php b/tests/Command/FetchCommandTest.php index fece1c79..aad97699 100644 --- a/tests/Command/FetchCommandTest.php +++ b/tests/Command/FetchCommandTest.php @@ -1,20 +1,27 @@ getMockBuilder(FetchCommand::class) ->disableOriginalConstructor() - ->setMethods(['setName', 'setDescription', 'addArgument', 'addOption']) + ->onlyMethods(['setName', 'setDescription', 'addArgument', 'addOption']) ->getMock(); $object ->expects(self::once()) @@ -33,7 +40,7 @@ public function testConfigure() : void ->method('addOption') ->willReturnSelf(); - $class = new \ReflectionClass(FetchCommand::class); + $class = new ReflectionClass(FetchCommand::class); $method = $class->getMethod('configure'); $method->setAccessible(true); diff --git a/tests/Command/ParserCommandTest.php b/tests/Command/ParserCommandTest.php index 4a9eda7e..7cc852c8 100644 --- a/tests/Command/ParserCommandTest.php +++ b/tests/Command/ParserCommandTest.php @@ -1,17 +1,24 @@ getMockBuilder(ParserCommand::class) ->disableOriginalConstructor() - ->setMethods(['setName', 'setDescription', 'addArgument', 'addOption']) + ->onlyMethods(['setName', 'setDescription', 'addArgument', 'addOption']) ->getMock(); $object ->expects(self::once()) @@ -30,7 +37,7 @@ public function testConfigure() : void ->method('addOption') ->willReturnSelf(); - $class = new \ReflectionClass(ParserCommand::class); + $class = new ReflectionClass(ParserCommand::class); $method = $class->getMethod('configure'); $method->setAccessible(true); diff --git a/tests/Command/UpdateCommandTest.php b/tests/Command/UpdateCommandTest.php index 6ed7a60e..cf877708 100644 --- a/tests/Command/UpdateCommandTest.php +++ b/tests/Command/UpdateCommandTest.php @@ -1,20 +1,27 @@ getMockBuilder(UpdateCommand::class) ->disableOriginalConstructor() - ->setMethods(['setName', 'setDescription', 'addArgument', 'addOption']) + ->onlyMethods(['setName', 'setDescription', 'addArgument', 'addOption']) ->getMock(); $object ->expects(self::once()) @@ -33,7 +40,7 @@ public function testConfigure() : void ->method('addOption') ->willReturnSelf(); - $class = new \ReflectionClass(UpdateCommand::class); + $class = new ReflectionClass(UpdateCommand::class); $method = $class->getMethod('configure'); $method->setAccessible(true); diff --git a/tests/CompareBrowscapWithOriginalTest.php b/tests/CompareBrowscapWithOriginalTest.php index 332f5803..6b8c56d6 100644 --- a/tests/CompareBrowscapWithOriginalTest.php +++ b/tests/CompareBrowscapWithOriginalTest.php @@ -1,13 +1,38 @@ null, 'browser_name_pattern' => null, 'Parent' => null, @@ -80,20 +100,22 @@ final class CompareBrowscapWithOriginalTest extends \PHPUnit\Framework\TestCase ]; /** - * @throws \BrowscapPHP\Exception\FileNameMissingException - * @throws \BrowscapPHP\Exception\FileNotFoundException - * @throws \PHPUnit\Framework\SkippedTestError + * @throws FileNameMissingException + * @throws FileNotFoundException + * @throws SkippedTestError + * @throws ErrorReadingFileException */ - public static function setUpBeforeClass() : void + public static function setUpBeforeClass(): void { $objectIniPath = ini_get('browscap'); - if (false === $objectIniPath || ! is_file($objectIniPath)) { + if ($objectIniPath === false || ! is_file($objectIniPath)) { self::markTestSkipped('browscap not defined in php.ini'); } - $memoryCache = new ArrayCache(); - $cache = new SimpleCacheAdapter($memoryCache); + $cache = new SimpleCache( + new MemoryStore() + ); $logger = new NullLogger(); @@ -105,21 +127,28 @@ public static function setUpBeforeClass() : void } /** - * @group compare + * @throws Exception * - * @throws \BrowscapPHP\Exception + * @group compare */ - public function testCheckProperties() : void + public function testCheckProperties(): void { - /** @var object $libBrowserObject */ $libBrowserObject = get_browser('x', false); + assert(is_object($libBrowserObject)); $libProperties = get_object_vars($libBrowserObject); + + if (self::$object === null) { + self::fail( + 'the Browscap Lib ist not set properly' + ); + } + $bcProperties = get_object_vars(self::$object->getBrowser('x')); unset($libProperties['parent'], $bcProperties['parent']); $libPropertyKeys = array_keys($libProperties); - $bcPropertyKeys = array_keys($bcProperties); + $bcPropertyKeys = array_keys($bcProperties); $diff = array_diff($libPropertyKeys, $bcPropertyKeys); @@ -142,8 +171,10 @@ public function testCheckProperties() : void self::assertArrayHasKey( $bcProp, $libProperties, - 'Property `' . $bcProp . '` from Browscap doesn\'t match anything in get_browser. ' - . 'You may have an outdated browscap.ini file for your tests' + sprintf( + 'Property `%s` from Browscap doesn\'t match anything in get_browser. You may have an outdated browscap.ini file for your tests', + $bcProp + ) ); unset($libProperties[$bcProp]); @@ -152,29 +183,34 @@ public function testCheckProperties() : void self::assertCount( 0, $libProperties, - 'There are ' . count($libProperties) . '(' . implode( - ', ', - array_keys($libProperties) - ) . ') properties in get_browser that do not match those in Browscap.' + sprintf( + 'There are %d(%s) properties in get_browser that do not match those in Browscap.', + count($libProperties), + implode(', ', array_keys($libProperties)) + ) ); } /** + * @throws Exception + * * @dataProvider providerUserAgent * @depends testCheckProperties * @group compare - * - * @param string $userAgent - * - * @throws \BrowscapPHP\Exception */ - public function testCompare(string $userAgent) : void + public function testCompare(string $userAgent): void { - /** @var object $libResult */ $libResult = get_browser($userAgent, false); + assert(is_object($libResult)); // Mainly for static analysis: assert(property_exists($libResult, 'browser_name_pattern')); + if (self::$object === null) { + self::fail( + 'the Browscap Lib ist not set properly' + ); + } + $bcResult = self::$object->getBrowser($userAgent); foreach (array_keys($this->properties) as $bcProp) { @@ -187,33 +223,40 @@ public function testCompare(string $userAgent) : void self::assertObjectHasAttribute( $bcProp, $libResult, - 'Actual library result does not have "' . $bcProp . '" property' + sprintf('Actual library result does not have "%s" property', $bcProp) ); self::assertObjectHasAttribute( $bcProp, $bcResult, - 'Actual browscap result does not have "' . $bcProp . '" property' + sprintf('Actual browscap result does not have "%s" property', $bcProp) ); $libValue = strtolower((string) $libResult->{$bcProp}); - $bcValue = strtolower((string) $bcResult->{$bcProp}); + $bcValue = strtolower((string) $bcResult->{$bcProp}); self::assertSame( $libValue, $bcValue, - 'Expected actual "' . $bcProp . '" to be "' . $libValue . '" ' - . '(was "' . $bcValue . '"); ' . PHP_EOL - . 'used pattern [\BrowscapPHP\Browscap::getBrowser()]:' . strtolower($bcResult->browser_name_pattern) . PHP_EOL - . 'expected pattern [get_browser]: ' . strtolower($libResult->browser_name_pattern) + sprintf( + 'Expected actual "%s" to be "%s" (was "%s");%sused pattern [\BrowscapPHP\Browscap::getBrowser()]:%sexpected pattern [get_browser]: %s', + $bcProp, + $libValue, + $bcValue, + PHP_EOL, + strtolower($bcResult->browser_name_pattern) . PHP_EOL, + strtolower($libResult->browser_name_pattern) + ) ); } } /** - * @return array[] + * @return string[][] + * + * @throws void */ - public function providerUserAgent() : array + public function providerUserAgent(): array { return [ ['BlackBerry7100i/4.1.0 Profile/MIDP-2.0 Configuration/CLDC-1.1 VendorID/103'], diff --git a/tests/Exception/FetcherExceptionTest.php b/tests/Exception/FetcherExceptionTest.php index ed034df3..5b6fce11 100644 --- a/tests/Exception/FetcherExceptionTest.php +++ b/tests/Exception/FetcherExceptionTest.php @@ -1,16 +1,18 @@ + */ + public function formatterOptionsProvider(): array { return [ [ @@ -31,12 +38,12 @@ public function formatterOptionsProvider() : array } /** - * @dataProvider formatterOptionsProvider + * @param bool[] $options + * @phpstan-param array{lowercase?: bool} $options * - * @param array $options - * @param \stdClass $expectedResult + * @dataProvider formatterOptionsProvider */ - public function testSetGetData(array $options, \stdClass $expectedResult) : void + public function testSetGetData(array $options, stdClass $expectedResult): void { $data = [ 'Browser' => 'test', diff --git a/tests/Formatter/PhpGetBrowserTest.php b/tests/Formatter/PhpGetBrowserTest.php index 492fa530..f82d8a96 100644 --- a/tests/Formatter/PhpGetBrowserTest.php +++ b/tests/Formatter/PhpGetBrowserTest.php @@ -1,26 +1,26 @@ object = new PhpGetBrowser(); } - public function testSetGetData() : void + public function testSetGetData(): void { $data = [ 'Browser' => 'test', @@ -29,13 +29,13 @@ public function testSetGetData() : void $this->object->setData($data); $return = $this->object->getData(); - self::assertInstanceOf(\stdClass::class, $return); + self::assertInstanceOf(stdClass::class, $return); self::assertSame('test', $return->browser); self::assertSame('TestComment', $return->comment); self::assertObjectHasAttribute('browser_type', $return); } - public function testPatternIdIsReturned() : void + public function testPatternIdIsReturned(): void { $data = [ 'Browser' => 'test', @@ -49,11 +49,9 @@ public function testPatternIdIsReturned() : void self::assertSame('test.json::u0::c1', $return->patternid); } - public function testPatternIdIsNotReturned() : void + public function testPatternIdIsNotReturned(): void { - $data = [ - 'Browser' => 'test', - ]; + $data = ['Browser' => 'test']; $this->object->setData($data); $return = $this->object->getData(); diff --git a/tests/Helper/Converter/ConverterConvertStringTest.php b/tests/Helper/Converter/ConverterConvertStringTest.php index 5feaf49b..c4d954a9 100644 --- a/tests/Helper/Converter/ConverterConvertStringTest.php +++ b/tests/Helper/Converter/ConverterConvertStringTest.php @@ -1,24 +1,27 @@ createMock(LoggerInterface::class); $logger->expects(self::exactly(4)) @@ -28,7 +31,6 @@ protected function setUp() : void ->method('error') ->willReturn(false); - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::any()) ->method('setItem') @@ -37,11 +39,14 @@ protected function setUp() : void $this->object = new Converter($logger, $cache); } - public function testConvertString() : void + /** + * @throws Exception + */ + public function testConvertString(): void { $file = $this->getMockBuilder(Filesystem::class) ->disableOriginalConstructor() - ->setMethods(['exists']) + ->onlyMethods(['exists']) ->getMock(); $file->expects(self::never()) ->method('exists') @@ -157,12 +162,14 @@ public function testConvertString() : void $this->object->convertString($content); } - public function testConvertStringWithoutPatternFound() : void + /** + * @throws Exception + */ + public function testConvertStringWithoutPatternFound(): void { - /** @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $file */ $file = $this->getMockBuilder(Filesystem::class) ->disableOriginalConstructor() - ->setMethods(['exists']) + ->onlyMethods(['exists']) ->getMock(); $file->expects(self::never()) ->method('exists') diff --git a/tests/Helper/Converter/ConverterTest.php b/tests/Helper/Converter/ConverterTest.php index c48d82e0..fbb780fe 100644 --- a/tests/Helper/Converter/ConverterTest.php +++ b/tests/Helper/Converter/ConverterTest.php @@ -1,41 +1,43 @@ createMock(LoggerInterface::class); $logger->expects(self::never()) ->method('info') ->willReturn(false); - /** @var BrowscapCacheInterface|\PHPUnit_Framework_MockObject_MockObject $cache */ $cache = $this->createMock(BrowscapCacheInterface::class); $cache->expects(self::any()) ->method('setItem') @@ -44,22 +46,30 @@ protected function setUp() : void $this->object = new Converter($logger, $cache); } - public function testSetGetFilesystem() : void + /** + * @throws ReflectionException + * @throws InvalidArgumentException + * @throws Exception + */ + public function testSetGetFilesystem(): void { - /** @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $file */ $file = $this->createMock(Filesystem::class); $this->object->setFilesystem($file); - $property = new \ReflectionProperty($this->object, 'filessystem'); + $property = new ReflectionProperty($this->object, 'filessystem'); $property->setAccessible(true); self::assertSame($file, $property->getValue($this->object)); } - public function testConvertMissingFile() : void + /** + * @throws FileNotFoundException + * @throws Exception + * @throws ErrorReadingFileException + */ + public function testConvertMissingFile(): void { - /** @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $file */ $file = $this->createMock(Filesystem::class); $file->expects(self::once()) ->method('exists') @@ -72,9 +82,14 @@ public function testConvertMissingFile() : void $this->object->convertFile('testFile'); } - public function testConvertFile() : void + /** + * @throws FileNotFoundException + * @throws Exception + * @throws ErrorReadingFileException + */ + public function testConvertFile(): void { - $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version + $content = ';;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; Browscap Version [GJK_Browscap_Version] Version=5031 @@ -179,14 +194,11 @@ public function testConvertFile() : void AolVersion=0 '; $structure = [ - self::STORAGE_DIR => [ - 'test.ini' => $content, - ], + self::STORAGE_DIR => ['test.ini' => $content], ]; - $this->root = vfsStream::setup(self::STORAGE_DIR, null, $structure); + vfsStream::setup(self::STORAGE_DIR, null, $structure); - /** @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $file */ $file = $this->createMock(Filesystem::class); $file->expects(self::once()) ->method('exists') @@ -196,12 +208,15 @@ public function testConvertFile() : void $this->expectException(FileNotFoundException::class); $this->expectExceptionMessage('File "vfs://storage/test.ini" does not exist'); - $this->object->convertFile(vfsStream::url(self::STORAGE_DIR . \DIRECTORY_SEPARATOR . 'test.ini')); + $this->object->convertFile(vfsStream::url(self::STORAGE_DIR . DIRECTORY_SEPARATOR . 'test.ini')); } - public function testGetIniVersion() : void + /** + * @throws InvalidArgumentException + * @throws Exception + */ + public function testGetIniVersion(): void { - /** @var Filesystem|\PHPUnit_Framework_MockObject_MockObject $file */ $file = $this->createMock(Filesystem::class); $file->expects(self::never()) ->method('exists') diff --git a/tests/Helper/IniLoaderTest.php b/tests/Helper/IniLoaderTest.php index 2e5cdbfb..377873d8 100644 --- a/tests/Helper/IniLoaderTest.php +++ b/tests/Helper/IniLoaderTest.php @@ -1,35 +1,44 @@ object = new IniLoader(); } - public function testSetMissingRemoteFilename() : void + /** + * @throws Exception + */ + public function testSetMissingRemoteFilename(): void { $this->expectException(Exception::class); $this->expectExceptionMessage('the filename can not be empty'); $this->object->setRemoteFilename(''); } - public function testGetRemoteIniUrl() : void + /** + * @throws Exception + */ + public function testGetRemoteIniUrl(): void { $this->object->setRemoteFilename(IniLoaderInterface::PHP_INI_LITE); self::assertSame('http://browscap.org/stream?q=Lite_PHP_BrowscapINI', $this->object->getRemoteIniUrl()); @@ -41,7 +50,11 @@ public function testGetRemoteIniUrl() : void self::assertSame('http://browscap.org/stream?q=Full_PHP_BrowscapINI', $this->object->getRemoteIniUrl()); } - public function testGetRemoteVerUrl() : void + /** + * @throws InvalidArgumentException + * @throws \PHPUnit\Framework\Exception + */ + public function testGetRemoteVerUrl(): void { self::assertSame('http://browscap.org/version', $this->object->getRemoteTimeUrl()); } diff --git a/tests/Helper/LoggerHelperTest.php b/tests/Helper/LoggerHelperTest.php index 49c2f718..7d60870d 100644 --- a/tests/Helper/LoggerHelperTest.php +++ b/tests/Helper/LoggerHelperTest.php @@ -1,20 +1,27 @@ createMock(OutputInterface::class); self::assertInstanceOf(Logger::class, LoggerHelper::createDefaultLogger($output)); diff --git a/tests/Helper/QuoterTest.php b/tests/Helper/QuoterTest.php index 9774a833..72279a39 100644 --- a/tests/Helper/QuoterTest.php +++ b/tests/Helper/QuoterTest.php @@ -1,26 +1,34 @@ quoter = new Quoter(); } - public function testPregQuote() : void + /** + * @throws InvalidArgumentException + * @throws Exception + */ + public function testPregQuote(): void { $expected = 'Mozilla\/.\.0 \(compatible; Ask Jeeves\/Teoma.*\)'; diff --git a/tests/Helper/SupportTest.php b/tests/Helper/SupportTest.php index fc1fd939..b4c69c53 100644 --- a/tests/Helper/SupportTest.php +++ b/tests/Helper/SupportTest.php @@ -1,16 +1,24 @@ 'testUA']; $object = new Support($source); @@ -18,7 +26,11 @@ public function testUserAgentIsTakenFromServerArray() : void self::assertSame('testUA', $object->getUserAgent()); } - public function testThatAnEmptyUserAgentIsReturnedWithoutSource() : void + /** + * @throws InvalidArgumentException + * @throws Exception + */ + public function testThatAnEmptyUserAgentIsReturnedWithoutSource(): void { $object = new Support(); diff --git a/tests/Parser/Helper/GetPatternTest.php b/tests/Parser/Helper/GetPatternTest.php index 959a725c..7094cf32 100644 --- a/tests/Parser/Helper/GetPatternTest.php +++ b/tests/Parser/Helper/GetPatternTest.php @@ -1,23 +1,30 @@ createMock(BrowscapCacheInterface::class); $cache ->expects(self::never()) ->method('getItem') ->willReturnMap($map); - /** @var LoggerInterface|\PHPUnit_Framework_MockObject_MockObject $logger */ $logger = $this->createMock(LoggerInterface::class); $this->object = new GetPattern($cache, $logger); } - public function testGetPatterns() : void + /** + * @throws InvalidArgumentException + * @throws Exception + */ + public function testGetPatterns(): void { $result = $this->object->getPatterns('Mozilla/5.0 (compatible; Ask Jeeves/Teoma*)'); - self::assertInstanceOf(\Generator::class, $result); + self::assertInstanceOf(Generator::class, $result); } } diff --git a/tests/Parser/Helper/PatternTest.php b/tests/Parser/Helper/PatternTest.php index 91fd3218..a6bdb651 100644 --- a/tests/Parser/Helper/PatternTest.php +++ b/tests/Parser/Helper/PatternTest.php @@ -1,30 +1,42 @@ 'aaa556aeec36ac3edfe2f5deea5f1d28', 1 => '31d050fd7a4ea6c972063ef30d18991a', @@ -42,17 +54,23 @@ public function testGetPatternStartWithVariants() : void } /** + * @throws InvalidArgumentException + * @throws Exception + * * @group pattern */ - public function testGetPatternLength() : void + public function testGetPatternLength(): void { self::assertSame(4, Pattern::getPatternLength('abcd')); } /** + * @throws InvalidArgumentException + * @throws Exception + * * @group pattern */ - public function testGetHashForParts() : void + public function testGetHashForParts(): void { self::assertSame( '529f1ddb64ea27d5cc6fc8ce8048d9e7', diff --git a/tests/Parser/Helper/SubKeyTest.php b/tests/Parser/Helper/SubKeyTest.php index a3dc96f3..f49fd904 100644 --- a/tests/Parser/Helper/SubKeyTest.php +++ b/tests/Parser/Helper/SubKeyTest.php @@ -1,21 +1,33 @@