From c9d4e36533f8fc99e66b21c4b5b186cb57deee5a Mon Sep 17 00:00:00 2001 From: Ivan Bochkarev Date: Wed, 2 Sep 2026 11:58:10 +0600 Subject: [PATCH 1/4] test: Add PHPUnit harness and require PHP 8.1 Stand testing is slow. Add Fenom-style unit tests and skippable MODX integration, plus CI on 8.1 through 8.4. PHP 8.1 is the floor so we can depend on current MODX 3.2. --- .github/workflows/phpunit.yml | 159 + .github/workflows/release.yml | 6 +- .gitignore | 3 + README.md | 26 +- _build/build.transport.php | 2 +- _build/ci-install-package.php | 14 + core/components/pdotools/composer.json | 31 +- core/components/pdotools/composer.lock | 3709 ++++++++++++++--- core/components/pdotools/docs/changelog.txt | 3 + core/components/pdotools/phpunit.xml.dist | 29 + .../pdotools/src/Parsing/Fenom/Fenom.php | 5 +- .../tests/Integration/ModxTestCase.php | 56 + .../tests/Integration/PluginPdoToolsTest.php | 27 + .../Integration/SnippetPdoArchiveTest.php | 19 + .../Integration/SnippetPdoCrumbsTest.php | 22 + .../tests/Integration/SnippetPdoFieldTest.php | 19 + .../tests/Integration/SnippetPdoMenuTest.php | 23 + .../Integration/SnippetPdoNeighborsTest.php | 18 + .../tests/Integration/SnippetPdoPageTest.php | 23 + .../Integration/SnippetPdoResourcesTest.php | 22 + .../Integration/SnippetPdoSitemapTest.php | 20 + .../tests/Integration/SnippetPdoTitleTest.php | 18 + .../tests/Integration/SnippetPdoUsersTest.php | 18 + .../pdotools/tests/Stubs/ModxStub.php | 263 ++ .../tests/Support/CoreToolsHarness.php | 28 + core/components/pdotools/tests/TestCase.php | 90 + .../tests/Unit/CoreTools/BuildTreeTest.php | 33 + .../tests/Unit/CoreTools/CacheKeyTest.php | 28 + .../Unit/CoreTools/ConfigAndTimingsTest.php | 37 + .../tests/Unit/CoreTools/FlattenArrayTest.php | 26 + .../Unit/CoreTools/MakePlaceholdersTest.php | 30 + .../tests/Unit/Fetch/DisableMs3Test.php | 42 + .../tests/Unit/Fetch/WhereContextTest.php | 87 + .../tests/Unit/Parsing/ErrorLogTest.php | 46 + .../tests/Unit/Parsing/FenomCompileTest.php | 32 + .../tests/Unit/Parsing/FenomModifiersTest.php | 42 + .../tests/Unit/Parsing/FenomSupportTest.php | 34 + .../tests/Unit/Parsing/ParserIgnoreTest.php | 46 + .../tests/Unit/Parsing/ProvidersTest.php | 37 + .../pdotools/tests/Unit/Parsing/TagTest.php | 23 + .../pdotools/tests/Unit/SourceMapTest.php | 69 + .../tests/Unit/Support/CacheKeyTest.php | 39 + .../Unit/Support/MenuBuilderParentsTest.php | 50 + .../Unit/Support/PaginatorPageCompareTest.php | 47 + .../Unit/Support/ParentsNormalizeTest.php | 49 + core/components/pdotools/tests/bootstrap.php | 55 + 46 files changed, 4876 insertions(+), 629 deletions(-) create mode 100644 .github/workflows/phpunit.yml create mode 100644 _build/ci-install-package.php create mode 100644 core/components/pdotools/phpunit.xml.dist create mode 100644 core/components/pdotools/tests/Integration/ModxTestCase.php create mode 100644 core/components/pdotools/tests/Integration/PluginPdoToolsTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoArchiveTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoCrumbsTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoFieldTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoMenuTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoNeighborsTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoPageTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoResourcesTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoSitemapTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoTitleTest.php create mode 100644 core/components/pdotools/tests/Integration/SnippetPdoUsersTest.php create mode 100644 core/components/pdotools/tests/Stubs/ModxStub.php create mode 100644 core/components/pdotools/tests/Support/CoreToolsHarness.php create mode 100644 core/components/pdotools/tests/TestCase.php create mode 100644 core/components/pdotools/tests/Unit/CoreTools/BuildTreeTest.php create mode 100644 core/components/pdotools/tests/Unit/CoreTools/CacheKeyTest.php create mode 100644 core/components/pdotools/tests/Unit/CoreTools/ConfigAndTimingsTest.php create mode 100644 core/components/pdotools/tests/Unit/CoreTools/FlattenArrayTest.php create mode 100644 core/components/pdotools/tests/Unit/CoreTools/MakePlaceholdersTest.php create mode 100644 core/components/pdotools/tests/Unit/Fetch/DisableMs3Test.php create mode 100644 core/components/pdotools/tests/Unit/Fetch/WhereContextTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/ErrorLogTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/FenomCompileTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/FenomModifiersTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/FenomSupportTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/ParserIgnoreTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/ProvidersTest.php create mode 100644 core/components/pdotools/tests/Unit/Parsing/TagTest.php create mode 100644 core/components/pdotools/tests/Unit/SourceMapTest.php create mode 100644 core/components/pdotools/tests/Unit/Support/CacheKeyTest.php create mode 100644 core/components/pdotools/tests/Unit/Support/MenuBuilderParentsTest.php create mode 100644 core/components/pdotools/tests/Unit/Support/PaginatorPageCompareTest.php create mode 100644 core/components/pdotools/tests/Unit/Support/ParentsNormalizeTest.php create mode 100644 core/components/pdotools/tests/bootstrap.php diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml new file mode 100644 index 0000000..aa43520 --- /dev/null +++ b/.github/workflows/phpunit.yml @@ -0,0 +1,159 @@ +name: Tests + +on: + push: + branches: [master] + pull_request: + +permissions: + contents: read + +jobs: + lint: + name: PHP lint + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ["8.1", "8.2", "8.3", "8.4"] + steps: + - uses: actions/checkout@v5 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + - name: Lint sources + run: find core/components/pdotools/src core/components/pdotools/elements -name '*.php' -exec php -l {} + + + unit: + name: Unit + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ["8.1", "8.2", "8.3", "8.4"] + steps: + - uses: actions/checkout@v5 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + coverage: none + tools: composer + - name: Install + working-directory: core/components/pdotools + run: composer install --no-interaction --prefer-dist + - name: Unit tests + working-directory: core/components/pdotools + run: composer test + + integration: + name: Integration + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + php: ["8.1", "8.2", "8.3", "8.4"] + services: + mysql: + image: mysql:8.0 + env: + MYSQL_ROOT_PASSWORD: root + MYSQL_DATABASE: modx + ports: + - 3306:3306 + options: >- + --health-cmd="mysqladmin ping -h 127.0.0.1 -uroot -proot" + --health-interval=10s + --health-timeout=5s + --health-retries=10 + steps: + - uses: actions/checkout@v5 + - uses: shivammathur/setup-php@v2 + with: + php-version: ${{ matrix.php }} + extensions: pdo_mysql, mysqli, gd, zip, json, xml, mbstring, curl, tokenizer + coverage: none + tools: composer + - name: Install package deps + working-directory: core/components/pdotools + run: composer install --no-interaction --prefer-dist + - name: Download MODX 3.2.4-pl + run: | + curl -fsSL -o modx.zip https://modx.s3.amazonaws.com/releases/3.2.4/modx-3.2.4-pl.zip + unzip -q modx.zip + mv modx-3.2.4-pl modx + rm modx.zip + - name: Install MODX (CLI) + working-directory: modx + run: | + MODX_ROOT="${GITHUB_WORKSPACE}/modx" + cat > setup/config.xml < + mysql + 127.0.0.1 + modx + root + root + utf8mb4 + utf8mb4 + utf8mb4_unicode_ci + modx_ + 443 + localhost + 0 + 0 + en + admin + AdminAdmin1 + admin@example.com + ${MODX_ROOT}/core/ + ${MODX_ROOT}/manager/ + /manager/ + ${MODX_ROOT}/connectors/ + /connectors/ + ${MODX_ROOT}/ + / + 0 + + XML + sed -i 's/^[[:space:]]*//' setup/config.xml + php setup/index.php --installmode=new --config="${MODX_ROOT}/setup/config.xml" + test -f core/config/config.inc.php + test -f config.core.php + - name: Enable package auto-install + run: sed -i "s/const PKG_AUTO_INSTALL = false;/const PKG_AUTO_INSTALL = true;/" _build/build.config.php + - name: Build and install transport + run: php _build/ci-install-package.php + - name: Integration tests + working-directory: core/components/pdotools + env: + MODX_TEST_BASE: ${{ github.workspace }}/modx/ + run: composer test:integration + + coverage: + name: Coverage + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v5 + - uses: shivammathur/setup-php@v2 + with: + php-version: "8.2" + coverage: pcov + tools: composer + - name: Install + working-directory: core/components/pdotools + run: composer install --no-interaction --prefer-dist + - name: Unit coverage + working-directory: core/components/pdotools + run: composer test:coverage + - name: Upload HTML report + uses: actions/upload-artifact@v4 + with: + name: coverage-html + path: core/components/pdotools/coverage/html + - name: Upload to Codecov + uses: codecov/codecov-action@v5 + with: + files: core/components/pdotools/coverage/clover.xml + fail_ci_if_error: false + token: ${{ secrets.CODECOV_TOKEN }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 448d384..93d350c 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -61,11 +61,11 @@ jobs: working-directory: core/components/pdotools run: composer install --no-dev --no-interaction --prefer-dist - - name: Download MODX 3.0.5-pl + - name: Download MODX 3.2.4-pl run: | - curl -fsSL -o modx.zip https://modx.s3.amazonaws.com/releases/3.0.5/modx-3.0.5-pl.zip + curl -fsSL -o modx.zip https://modx.s3.amazonaws.com/releases/3.2.4/modx-3.2.4-pl.zip unzip -q modx.zip - mv modx-3.0.5-pl modx + mv modx-3.2.4-pl modx rm modx.zip - name: Install MODX (CLI) diff --git a/.gitignore b/.gitignore index f737578..f4c15fd 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,6 @@ config.core.php .idea node_modules /core/components/pdotools/vendor/ +/core/components/pdotools/.phpunit.cache +/core/components/pdotools/coverage/ +/core/components/pdotools/tests/tmp/ diff --git a/README.md b/README.md index e49fd6f..3f7464b 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,33 @@ ## pdoTools -pdoTools 3 is a set of everyday [MODX Revolution](https://modx.com/) 3 snippets plus a small library that keeps them fast. Queries are built with xPDO and run through PDO. Elements can live in the database or in files. Tickets and [MiniShop3](https://github.com/modx-pro/MiniShop3) use it. +[![Tests](https://github.com/modx-pro/pdoTools3/actions/workflows/phpunit.yml/badge.svg)](https://github.com/modx-pro/pdoTools3/actions/workflows/phpunit.yml) +[![PHP](https://img.shields.io/badge/php-8.1%20%7C%208.2%20%7C%208.3%20%7C%208.4-777BB4)](https://github.com/modx-pro/pdoTools3/actions/workflows/phpunit.yml) +[![Coverage](https://img.shields.io/codecov/c/github/modx-pro/pdoTools3)](https://codecov.io/gh/modx-pro/pdoTools3) -This branch requires **MODX 3** and **PHP 7.2+**. For MODX 2 use [pdoTools 2.x](https://github.com/modx-pro/pdoTools). +pdoTools 3 is a set of everyday [MODX Revolution](https://modx.com/) 3 snippets plus a small library that keeps them fast. Queries are built with xPDO and run through PDO. Elements can live in the database or in files. [MiniShop3](https://github.com/modx-pro/MiniShop3) use it. + +This branch requires **MODX 3** and **PHP 8.1+**. For MODX 2 use [pdoTools 2.x](https://github.com/modx-pro/pdoTools). **Documentation:** [docs.modx.pro/components/pdotools](https://docs.modx.pro/components/pdotools/) +### Tests + +From `core/components/pdotools`: + +```bash +composer install +composer test +``` + +Integration tests need a live MODX 3 tree (CI installs 3.2.4-pl and the transport with `PKG_AUTO_INSTALL=true`): + +```bash +export MODX_TEST_BASE=/path/to/modx/ +composer test:integration +``` + +Coverage (pcov or xdebug): `composer test:coverage`. HTML report lands in `coverage/html`. + ### Advantages Every pdoTools snippet shares the same core: diff --git a/_build/build.transport.php b/_build/build.transport.php index bae94c8..7a98378 100644 --- a/_build/build.transport.php +++ b/_build/build.transport.php @@ -165,7 +165,7 @@ 'license' => file_get_contents($sources['docs'] . 'license.txt'), 'readme' => file_get_contents($sources['docs'] . 'readme.txt'), 'requires' => [ - 'php' => '>=7.2.0', + 'php' => '>=8.1.0', 'modx' => '>=3.0.0-beta', ], ]); diff --git a/_build/ci-install-package.php b/_build/ci-install-package.php new file mode 100644 index 0000000..31664bb --- /dev/null +++ b/_build/ci-install-package.php @@ -0,0 +1,14 @@ +=7.2", + "php": ">=8.1", "fenom/fenom": "^2.11" }, "require-dev": { - "modx/revolution": "3.x-dev" + "phpunit/phpunit": "^9.6", + "modx/revolution": "3.2.4-pl" + }, + "config": { + "platform": { + "php": "8.1.31" + }, + "audit": { + "block-insecure": false, + "ignore": [ + "PKSA-7k8y-pxvq-y5kc", + "GHSA-674v-3g2w-84gx" + ] + } + }, + "scripts": { + "test": "phpunit --configuration phpunit.xml.dist --testsuite Unit", + "test:integration": "phpunit --configuration phpunit.xml.dist --testsuite Integration", + "test:all": "phpunit --configuration phpunit.xml.dist", + "test:coverage": "phpunit --configuration phpunit.xml.dist --testsuite Unit --coverage-clover coverage/clover.xml --coverage-html coverage/html" } } diff --git a/core/components/pdotools/composer.lock b/core/components/pdotools/composer.lock index af2252e..96e658f 100644 --- a/core/components/pdotools/composer.lock +++ b/core/components/pdotools/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "5c8260f278f96c8e278aea72e57de818", + "content-hash": "97ed7a43e10bfcd3bf273d1ce017b774", "packages": [ { "name": "fenom/fenom", @@ -64,23 +64,27 @@ "packages-dev": [ { "name": "aws/aws-crt-php", - "version": "v1.0.2", + "version": "v1.2.7", "source": { "type": "git", "url": "https://github.com/awslabs/aws-crt-php.git", - "reference": "3942776a8c99209908ee0b287746263725685732" + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/3942776a8c99209908ee0b287746263725685732", - "reference": "3942776a8c99209908ee0b287746263725685732", + "url": "https://api.github.com/repos/awslabs/aws-crt-php/zipball/d71d9906c7bb63a28295447ba12e74723bd3730e", + "reference": "d71d9906c7bb63a28295447ba12e74723bd3730e", "shasum": "" }, "require": { "php": ">=5.5" }, "require-dev": { - "phpunit/phpunit": "^4.8.35|^5.4.3" + "phpunit/phpunit": "^4.8.35||^5.6.3||^9.5", + "yoast/phpunit-polyfills": "^1.0" + }, + "suggest": { + "ext-awscrt": "Make sure you install awscrt native extension to use any of the functionality." }, "type": "library", "autoload": { @@ -99,7 +103,7 @@ } ], "description": "AWS Common Runtime for PHP", - "homepage": "http://aws.amazon.com/sdkforphp", + "homepage": "https://github.com/awslabs/aws-crt-php", "keywords": [ "amazon", "aws", @@ -108,56 +112,59 @@ ], "support": { "issues": "https://github.com/awslabs/aws-crt-php/issues", - "source": "https://github.com/awslabs/aws-crt-php/tree/v1.0.2" + "source": "https://github.com/awslabs/aws-crt-php/tree/v1.2.7" }, - "time": "2021-09-03T22:57:30+00:00" + "time": "2024-10-18T22:15:13+00:00" }, { "name": "aws/aws-sdk-php", - "version": "3.208.3", + "version": "3.394.6", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "c9ccf6705fe41e53f23dac7e0573e3f79d70bcde" + "reference": "860a8b13413adcef698afa0770f0d85f85777a78" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/c9ccf6705fe41e53f23dac7e0573e3f79d70bcde", - "reference": "c9ccf6705fe41e53f23dac7e0573e3f79d70bcde", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/860a8b13413adcef698afa0770f0d85f85777a78", + "reference": "860a8b13413adcef698afa0770f0d85f85777a78", "shasum": "" }, "require": { - "aws/aws-crt-php": "^1.0.2", + "aws/aws-crt-php": "^1.2.3", "ext-json": "*", "ext-pcre": "*", "ext-simplexml": "*", - "guzzlehttp/guzzle": "^5.3.3|^6.2.1|^7.0", - "guzzlehttp/promises": "^1.4.0", - "guzzlehttp/psr7": "^1.7.0|^2.0", - "mtdowling/jmespath.php": "^2.6", - "php": ">=5.5" + "guzzlehttp/guzzle": "^7.8.2 || ^8.0", + "guzzlehttp/promises": "^2.0.3 || ^3.0", + "guzzlehttp/psr7": "^2.6.3 || ^3.0", + "mtdowling/jmespath.php": "^2.9.1", + "php": ">=8.1", + "psr/http-message": "^1.0 || ^2.0", + "symfony/filesystem": "^v5.4.45 || ^v6.4.3 || ^v7.1.0 || ^v8.0.0" }, "require-dev": { "andrewsville/php-token-reflection": "^1.4", "aws/aws-php-sns-message-validator": "~1.0", "behat/behat": "~3.0", + "composer/composer": "^2.7.8", + "dms/phpunit-arraysubset-asserts": "^v0.5.0", "doctrine/cache": "~1.4", "ext-dom": "*", "ext-openssl": "*", - "ext-pcntl": "*", "ext-sockets": "*", - "nette/neon": "^2.3", - "paragonie/random_compat": ">= 2", - "phpunit/phpunit": "^4.8.35|^5.4.3", - "psr/cache": "^1.0", - "psr/simple-cache": "^1.0", - "sebastian/comparator": "^1.2.3" + "phpunit/phpunit": "^10.0", + "psr/cache": "^2.0 || ^3.0", + "psr/simple-cache": "^2.0 || ^3.0", + "sebastian/comparator": "^1.2.3 || ^4.0 || ^5.0", + "yoast/phpunit-polyfills": "^2.0" }, "suggest": { "aws/aws-php-sns-message-validator": "To validate incoming SNS notifications", "doctrine/cache": "To use the DoctrineCacheAdapter", "ext-curl": "To send requests using cURL", "ext-openssl": "Allows working with CloudFront private distributions and verifying received SNS messages", + "ext-pcntl": "To use client-side monitoring", "ext-sockets": "To use client-side monitoring" }, "type": "library", @@ -167,11 +174,14 @@ } }, "autoload": { + "files": [ + "src/functions.php" + ], "psr-4": { "Aws\\": "src/" }, - "files": [ - "src/functions.php" + "exclude-from-classmap": [ + "src/data/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -181,11 +191,11 @@ "authors": [ { "name": "Amazon Web Services", - "homepage": "http://aws.amazon.com" + "homepage": "https://aws.amazon.com" } ], "description": "AWS SDK for PHP - Use Amazon Web Services in your PHP project", - "homepage": "http://aws.amazon.com/sdkforphp", + "homepage": "https://aws.amazon.com/sdk-for-php", "keywords": [ "amazon", "aws", @@ -197,32 +207,102 @@ "sdk" ], "support": { - "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", + "forum": "https://github.com/aws/aws-sdk-php/discussions", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.208.3" + "source": "https://github.com/aws/aws-sdk-php/tree/3.394.6" + }, + "time": "2026-09-01T18:09:58+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "reference": "c6222283fa3f4ac679f8b9ced9a4e23f163e80d0", + "shasum": "" + }, + "require": { + "php": "^8.1" + }, + "require-dev": { + "doctrine/coding-standard": "^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^1.2", + "phpstan/phpstan": "^1.9.4", + "phpstan/phpstan-phpunit": "^1.3", + "phpunit/phpunit": "^9.5.27", + "vimeo/psalm": "^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/2.0.0" }, - "time": "2021-12-08T19:30:07+00:00" + "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%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:23:10+00:00" }, { "name": "erusev/parsedown", - "version": "1.8.0-beta-7", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/erusev/parsedown.git", - "reference": "fe7a50eceb4a3c867cc9fa9c0aa906b1067d1955" + "reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/erusev/parsedown/zipball/fe7a50eceb4a3c867cc9fa9c0aa906b1067d1955", - "reference": "fe7a50eceb4a3c867cc9fa9c0aa906b1067d1955", + "url": "https://api.github.com/repos/erusev/parsedown/zipball/96baaad00f71ba04d76e45b4620f54d3beabd6f7", + "reference": "96baaad00f71ba04d76e45b4620f54d3beabd6f7", "shasum": "" }, "require": { "ext-mbstring": "*", - "php": ">=5.3.0" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35" + "phpunit/phpunit": "^7.5|^8.5|^9.6" }, "type": "library", "autoload": { @@ -249,40 +329,49 @@ ], "support": { "issues": "https://github.com/erusev/parsedown/issues", - "source": "https://github.com/erusev/parsedown/tree/1.8.0-beta-7" + "source": "https://github.com/erusev/parsedown/tree/1.8.0" }, - "time": "2019-03-17T18:47:21+00:00" + "funding": [ + { + "url": "https://github.com/erusev", + "type": "github" + } + ], + "time": "2026-02-16T11:41:01+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "dev-master", + "version": "7.15.5", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79" + "reference": "ee80339fd9177ba44c49cdb653ff02a4d1106b9a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee0a041b1760e6a53d2a39c8c34115adc2af2c79", - "reference": "ee0a041b1760e6a53d2a39c8c34115adc2af2c79", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/ee80339fd9177ba44c49cdb653ff02a4d1106b9a", + "reference": "ee80339fd9177ba44c49cdb653ff02a4d1106b9a", "shasum": "" }, "require": { "ext-json": "*", - "guzzlehttp/promises": "^1.5", - "guzzlehttp/psr7": "^1.8.3 || ^2.1", + "guzzlehttp/promises": "^2.5.3", + "guzzlehttp/psr7": "^2.13.1", "php": "^7.2.5 || ^8.0", "psr/http-client": "^1.0", - "symfony/deprecation-contracts": "^2.2 || ^3.0" + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.25" }, "provide": { "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.2", "ext-curl": "*", - "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "guzzle/client-integration-tests": "3.0.3", + "guzzlehttp/test-server": "^0.7", + "php-http/message-factory": "^1.1", + "phpunit/phpunit": "^8.5.52 || ^9.6.34", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -290,20 +379,20 @@ "ext-intl": "Required for Internationalized Domain Name (IDN) support", "psr/log": "Required for using the Log middleware" }, - "default-branch": true, "type": "library", "extra": { - "branch-alias": { - "dev-master": "7.4-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { - "psr-4": { - "GuzzleHttp\\": "src/" - }, "files": [ "src/functions_include.php" - ] + ], + "psr-4": { + "GuzzleHttp\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -360,7 +449,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.1" + "source": "https://github.com/guzzle/guzzle/tree/7.15.5" }, "funding": [ { @@ -376,42 +465,41 @@ "type": "tidelift" } ], - "time": "2021-12-06T18:43:05+00:00" + "time": "2026-08-24T09:21:06+00:00" }, { "name": "guzzlehttp/promises", - "version": "dev-master", + "version": "2.5.3", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + "reference": "cde49999552d185d64715fe9c1f77a2aadd2f9f1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "url": "https://api.github.com/repos/guzzle/promises/zipball/cde49999552d185d64715fe9c1f77a2aadd2f9f1", + "reference": "cde49999552d185d64715fe9c1f77a2aadd2f9f1", "shasum": "" }, "require": { - "php": ">=5.5" + "php": "^7.2.5 || ^8.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0" }, "require-dev": { - "symfony/phpunit-bridge": "^4.4 || ^5.1" + "bamarni/composer-bin-plugin": "^1.8.2", + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, - "default-branch": true, "type": "library", "extra": { - "branch-alias": { - "dev-master": "1.5-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { "psr-4": { "GuzzleHttp\\Promise\\": "src/" - }, - "files": [ - "src/functions_include.php" - ] + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -445,7 +533,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.1" + "source": "https://github.com/guzzle/promises/tree/2.5.3" }, "funding": [ { @@ -461,45 +549,48 @@ "type": "tidelift" } ], - "time": "2021-10-22T20:56:57+00:00" + "time": "2026-08-24T09:11:28+00:00" }, { "name": "guzzlehttp/psr7", - "version": "dev-master", + "version": "2.13.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "53b1962090d84f02980bdfd4cd5c5fe35b54e2a6" + "reference": "95e7828100de18b4e269fb1703be530082d5166d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/53b1962090d84f02980bdfd4cd5c5fe35b54e2a6", - "reference": "53b1962090d84f02980bdfd4cd5c5fe35b54e2a6", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/95e7828100de18b4e269fb1703be530082d5166d", + "reference": "95e7828100de18b4e269fb1703be530082d5166d", "shasum": "" }, "require": { "php": "^7.2.5 || ^8.0", "psr/http-factory": "^1.0", - "psr/http-message": "^1.0", - "ralouphie/getallheaders": "^3.0" + "psr/http-message": "^1.1 || ^2.0", + "ralouphie/getallheaders": "^3.0", + "symfony/deprecation-contracts": "^2.5 || ^3.0", + "symfony/polyfill-php80": "^1.25" }, "provide": { "psr/http-factory-implementation": "1.0", "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.8 || ^9.3.10" + "bamarni/composer-bin-plugin": "^1.8.2", + "http-interop/http-factory-tests": "1.1.0", + "jshttp/mime-db": "1.54.0.1", + "phpunit/phpunit": "^8.5.52 || ^9.6.34" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, - "default-branch": true, "type": "library", "extra": { - "branch-alias": { - "dev-master": "2.1-dev" + "bamarni-bin": { + "bin-links": true, + "forward-command": false } }, "autoload": { @@ -561,7 +652,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/master" + "source": "https://github.com/guzzle/psr7/tree/2.13.1" }, "funding": [ { @@ -577,7 +668,7 @@ "type": "tidelift" } ], - "time": "2021-12-06T18:35:34+00:00" + "time": "2026-08-24T09:13:11+00:00" }, { "name": "inlinestyle/inlinestyle", @@ -632,16 +723,16 @@ }, { "name": "james-heinrich/phpthumb", - "version": "v1.7.17", + "version": "v1.7.24", "source": { "type": "git", "url": "https://github.com/JamesHeinrich/phpThumb.git", - "reference": "1ef2db62e8d4a4e391159653b200144a37462de3" + "reference": "4b26e5414c533120ade285a0350425f70b93cf54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/JamesHeinrich/phpThumb/zipball/1ef2db62e8d4a4e391159653b200144a37462de3", - "reference": "1ef2db62e8d4a4e391159653b200144a37462de3", + "url": "https://api.github.com/repos/JamesHeinrich/phpThumb/zipball/4b26e5414c533120ade285a0350425f70b93cf54", + "reference": "4b26e5414c533120ade285a0350425f70b93cf54", "shasum": "" }, "require": { @@ -683,22 +774,22 @@ ], "support": { "issues": "https://github.com/JamesHeinrich/phpThumb/issues", - "source": "https://github.com/JamesHeinrich/phpThumb/tree/v1.7.17" + "source": "https://github.com/JamesHeinrich/phpThumb/tree/v1.7.24" }, - "time": "2021-09-22T15:40:00+00:00" + "time": "2025-09-03T16:25:10+00:00" }, { "name": "league/flysystem", - "version": "2.x-dev", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem.git", - "reference": "4b6da3e75b5e8eee53bb5ee46ded15a532843f80" + "reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/4b6da3e75b5e8eee53bb5ee46ded15a532843f80", - "reference": "4b6da3e75b5e8eee53bb5ee46ded15a532843f80", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/8aaffb653c5777781b0f7f69a5d937baf7ab6cdb", + "reference": "8aaffb653c5777781b0f7f69a5d937baf7ab6cdb", "shasum": "" }, "require": { @@ -715,6 +806,7 @@ "aws/aws-sdk-php": "^3.132.4", "composer/semver": "^3.0", "ext-fileinfo": "*", + "ext-ftp": "*", "friendsofphp/php-cs-fixer": "^3.2", "google/cloud-storage": "^1.23", "phpseclib/phpseclib": "^2.0", @@ -722,7 +814,6 @@ "phpunit/phpunit": "^8.5 || ^9.4", "sabre/dav": "^4.1" }, - "default-branch": true, "type": "library", "autoload": { "psr-4": { @@ -755,11 +846,11 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem/issues", - "source": "https://github.com/thephpleague/flysystem/tree/2.3.2" + "source": "https://github.com/thephpleague/flysystem/tree/2.5.0" }, "funding": [ { - "url": "https://offset.earth/frankdejonge", + "url": "https://ecologi.com/frankdejonge", "type": "custom" }, { @@ -771,20 +862,20 @@ "type": "tidelift" } ], - "time": "2021-11-28T20:19:08+00:00" + "time": "2022-09-17T21:02:32+00:00" }, { "name": "league/flysystem-aws-s3-v3", - "version": "2.x-dev", + "version": "2.5.0", "source": { "type": "git", "url": "https://github.com/thephpleague/flysystem-aws-s3-v3.git", - "reference": "8d8edfe2541d94e6607808e3dd8484734c86eb2a" + "reference": "2ae435f7177fd5d3afc0090bc7f849093d8361e8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/8d8edfe2541d94e6607808e3dd8484734c86eb2a", - "reference": "8d8edfe2541d94e6607808e3dd8484734c86eb2a", + "url": "https://api.github.com/repos/thephpleague/flysystem-aws-s3-v3/zipball/2ae435f7177fd5d3afc0090bc7f849093d8361e8", + "reference": "2ae435f7177fd5d3afc0090bc7f849093d8361e8", "shasum": "" }, "require": { @@ -824,32 +915,110 @@ ], "support": { "issues": "https://github.com/thephpleague/flysystem-aws-s3-v3/issues", - "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/2.x" + "source": "https://github.com/thephpleague/flysystem-aws-s3-v3/tree/2.5.0" + }, + "funding": [ + { + "url": "https://ecologi.com/frankdejonge", + "type": "custom" + }, + { + "url": "https://github.com/frankdejonge", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/league/flysystem", + "type": "tidelift" + } + ], + "time": "2022-09-09T19:33:51+00:00" + }, + { + "name": "league/flysystem-ftp", + "version": "2.4.2", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem-ftp.git", + "reference": "a49dd4c4f0b7af88fe118218a6995609d1570f93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem-ftp/zipball/a49dd4c4f0b7af88fe118218a6995609d1570f93", + "reference": "a49dd4c4f0b7af88fe118218a6995609d1570f93", + "shasum": "" + }, + "require": { + "ext-ftp": "*", + "league/flysystem": "^2.0.0", + "league/mime-type-detection": "^1.0.0", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "League\\Flysystem\\Ftp\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frankdejonge.nl" + } + ], + "description": "FTP filesystem adapter for Flysystem.", + "keywords": [ + "Flysystem", + "file", + "files", + "filesystem", + "ftp", + "ftpd" + ], + "support": { + "source": "https://github.com/thephpleague/flysystem-ftp/tree/2.4.2" }, - "time": "2021-05-24T15:37:00+00:00" + "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": "2022-01-31T19:07:20+00:00" }, { "name": "league/mime-type-detection", - "version": "1.9.0", + "version": "1.17.0", "source": { "type": "git", "url": "https://github.com/thephpleague/mime-type-detection.git", - "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69" + "reference": "f5f47eff7c48ed1003069a2ca67f316fb4021c76" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/aa70e813a6ad3d1558fc927863d47309b4c23e69", - "reference": "aa70e813a6ad3d1558fc927863d47309b4c23e69", + "url": "https://api.github.com/repos/thephpleague/mime-type-detection/zipball/f5f47eff7c48ed1003069a2ca67f316fb4021c76", + "reference": "f5f47eff7c48ed1003069a2ca67f316fb4021c76", "shasum": "" }, "require": { "ext-fileinfo": "*", - "php": "^7.2 || ^8.0" + "php": "^7.4 || ^8.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "^3.2", "phpstan/phpstan": "^0.12.68", - "phpunit/phpunit": "^8.5.8 || ^9.3" + "phpunit/phpunit": "^8.5.8 || ^9.3 || ^10.0 || ^11.0 || ^12.0" }, "type": "library", "autoload": { @@ -870,7 +1039,7 @@ "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" + "source": "https://github.com/thephpleague/mime-type-detection/tree/1.17.0" }, "funding": [ { @@ -882,20 +1051,20 @@ "type": "tidelift" } ], - "time": "2021-11-21T11:48:40+00:00" + "time": "2026-07-09T11:49:27+00:00" }, { "name": "modx/revolution", - "version": "3.x-dev", + "version": "v3.2.4-pl", "source": { "type": "git", "url": "https://github.com/modxcms/revolution.git", - "reference": "d96badf40a7c6bc550dc90305c802bbdd8d2adae" + "reference": "c7c38028e81022285a2f2aab9fd076bb9e2d89f4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/modxcms/revolution/zipball/d96badf40a7c6bc550dc90305c802bbdd8d2adae", - "reference": "d96badf40a7c6bc550dc90305c802bbdd8d2adae", + "url": "https://api.github.com/repos/modxcms/revolution/zipball/c7c38028e81022285a2f2aab9fd076bb9e2d89f4", + "reference": "c7c38028e81022285a2f2aab9fd076bb9e2d89f4", "shasum": "" }, "require": { @@ -917,7 +1086,8 @@ "james-heinrich/phpthumb": "^1.7", "league/flysystem": "^2.0", "league/flysystem-aws-s3-v3": "^2.0", - "php": ">=7.2", + "league/flysystem-ftp": "^2.0", + "php": ">=8.1", "phpmailer/phpmailer": "^6.0", "pimple/pimple": "^3.0", "psr/http-client": "^1.0", @@ -925,18 +1095,27 @@ "psr/http-message": "^1.0", "simplepie/simplepie": "^1.5", "smarty/smarty": "^4.0", - "xpdo/xpdo": "^3.0@dev" + "symfony/polyfill-php82": "^1.33", + "xpdo/xpdo": "~3.1.0" }, "require-dev": { + "phpcompatibility/php-compatibility": "^9.3", + "squizlabs/php_codesniffer": "3.*", "yoast/phpunit-polyfills": "^0.2.0" }, "suggest": { "ext-iconv": "Needed if you want to use the built-in transliteration service", "ext-imagick": "To process images in a more advanced way", + "ext-intl": "", "ext-mbstring": "Needed when use_multibyte is enabled or when using some extras like Gallery", "ext-xmlwriter": "To use the export functionalities" }, "type": "project", + "extra": { + "aws/aws-sdk-php": [ + "S3" + ] + }, "autoload": { "psr-4": { "MODX\\": "core/src/" @@ -983,53 +1162,63 @@ "issues": "https://github.com/modxcms/revolution/issues/", "source": "https://github.com/modxcms/revolution/" }, - "time": "2021-11-23T19:21:54+00:00" + "funding": [ + { + "url": "https://opencollective.com/modx", + "type": "opencollective" + } + ], + "time": "2026-08-26T13:53:52+00:00" }, { "name": "mtdowling/jmespath.php", - "version": "dev-master", + "version": "2.9.2", "source": { "type": "git", "url": "https://github.com/jmespath/jmespath.php.git", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb" + "reference": "2157c5e50e813ec6a96c1eed3be7f64a20fb32a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/9b87907a81b87bc76d19a7fb2d61e61486ee9edb", - "reference": "9b87907a81b87bc76d19a7fb2d61e61486ee9edb", + "url": "https://api.github.com/repos/jmespath/jmespath.php/zipball/2157c5e50e813ec6a96c1eed3be7f64a20fb32a8", + "reference": "2157c5e50e813ec6a96c1eed3be7f64a20fb32a8", "shasum": "" }, "require": { - "php": "^5.4 || ^7.0 || ^8.0", + "php": "^7.2.5 || ^8.0", "symfony/polyfill-mbstring": "^1.17" }, "require-dev": { - "composer/xdebug-handler": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^7.5.15" + "composer/xdebug-handler": "^3.0.3", + "phpunit/phpunit": "^8.5.52" }, - "default-branch": true, "bin": [ "bin/jp.php" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.6-dev" + "dev-master": "2.9-dev" } }, "autoload": { - "psr-4": { - "JmesPath\\": "src/" - }, "files": [ "src/JmesPath.php" - ] + ], + "psr-4": { + "JmesPath\\": "src/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], "authors": [ + { + "name": "Graham Campbell", + "email": "hello@gjcampbell.co.uk", + "homepage": "https://github.com/GrahamCampbell" + }, { "name": "Michael Dowling", "email": "mtdowling@gmail.com", @@ -1043,632 +1232,2811 @@ ], "support": { "issues": "https://github.com/jmespath/jmespath.php/issues", - "source": "https://github.com/jmespath/jmespath.php/tree/2.6.1" + "source": "https://github.com/jmespath/jmespath.php/tree/2.9.2" }, - "time": "2021-06-14T00:11:39+00:00" + "time": "2026-07-06T18:56:19+00:00" }, { - "name": "phpmailer/phpmailer", - "version": "v6.5.3", + "name": "myclabs/deep-copy", + "version": "1.14.0", "source": { "type": "git", - "url": "https://github.com/PHPMailer/PHPMailer.git", - "reference": "baeb7cde6b60b1286912690ab0693c7789a31e71" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/baeb7cde6b60b1286912690ab0693c7789a31e71", - "reference": "baeb7cde6b60b1286912690ab0693c7789a31e71", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae", + "reference": "8680aa248f8e07bc8fb43f56f0f5fc77a0c96aae", "shasum": "" }, "require": { - "ext-ctype": "*", - "ext-filter": "*", - "ext-hash": "*", - "php": ">=5.5.0" + "php": "^8.0" }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", - "doctrine/annotations": "^1.2", - "php-parallel-lint/php-console-highlighter": "^0.5.0", - "php-parallel-lint/php-parallel-lint": "^1.3", - "phpcompatibility/php-compatibility": "^9.3.5", - "roave/security-advisories": "dev-latest", - "squizlabs/php_codesniffer": "^3.6.0", - "yoast/phpunit-polyfills": "^1.0.0" + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3 <3.2.2" }, - "suggest": { - "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", - "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", - "league/oauth2-google": "Needed for Google XOAUTH2 authentication", - "psr/log": "For optional PSR-3 debug logging", - "stevenmaguire/oauth2-microsoft": "Needed for Microsoft XOAUTH2 authentication", - "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)" + "require-dev": { + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpspec/prophecy": "^1.10", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, "type": "library", "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], "psr-4": { - "PHPMailer\\PHPMailer\\": "src/" + "DeepCopy\\": "src/DeepCopy/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-2.1-only" + "MIT" ], - "authors": [ - { - "name": "Marcus Bointon", - "email": "phpmailer@synchromedia.co.uk" - }, - { - "name": "Jim Jagielski", - "email": "jimjag@gmail.com" - }, - { - "name": "Andy Prevost", - "email": "codeworxtech@users.sourceforge.net" - }, - { - "name": "Brent R. Matzelle" - } + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" ], - "description": "PHPMailer is a full-featured email creation and transfer class for PHP", "support": { - "issues": "https://github.com/PHPMailer/PHPMailer/issues", - "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.5.3" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.14.0" }, "funding": [ { - "url": "https://github.com/Synchro", + "url": "https://github.com/mnapoli", "type": "github" } ], - "time": "2021-11-25T16:34:11+00:00" + "time": "2026-08-11T10:17:44+00:00" }, { - "name": "pimple/pimple", - "version": "v3.5.0", + "name": "nikic/php-parser", + "version": "v5.8.0", "source": { "type": "git", - "url": "https://github.com/silexphp/Pimple.git", - "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/silexphp/Pimple/zipball/a94b3a4db7fb774b3d78dad2315ddc07629e1bed", - "reference": "a94b3a4db7fb774b3d78dad2315ddc07629e1bed", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/044a6a392ff8ad0d61f14370a5fbbd0a0107152f", + "reference": "044a6a392ff8ad0d61f14370a5fbbd0a0107152f", "shasum": "" }, "require": { - "php": ">=7.2.5", - "psr/container": "^1.1 || ^2.0" + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "symfony/phpunit-bridge": "^5.4@dev" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^9.0" }, + "bin": [ + "bin/php-parse" + ], "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4.x-dev" + "dev-master": "5.x-dev" } }, "autoload": { - "psr-0": { - "Pimple": "src/" + "psr-4": { + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nikita Popov" } ], - "description": "Pimple, a simple Dependency Injection Container", - "homepage": "https://pimple.symfony.com", + "description": "A PHP parser written in PHP", "keywords": [ - "container", - "dependency injection" + "parser", + "php" ], "support": { - "source": "https://github.com/silexphp/Pimple/tree/v3.5.0" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.8.0" }, - "time": "2021-10-28T11:13:42+00:00" + "time": "2026-07-04T14:30:18+00:00" }, { - "name": "psr/container", - "version": "1.x-dev", + "name": "phar-io/manifest", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/php-fig/container.git", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea" + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/513e0666f7216c7459170d56df27dfcefe1689ea", - "reference": "513e0666f7216c7459170d56df27dfcefe1689ea", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", "shasum": "" }, "require": { - "php": ">=7.4.0" + "ext-dom": "*", + "ext-libxml": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" }, "type": "library", - "autoload": { - "psr-4": { - "Psr\\Container\\": "src/" + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Common Container Interface (PHP FIG PSR-11)", - "homepage": "https://github.com/php-fig/container", - "keywords": [ - "PSR-11", - "container", - "container-interface", - "container-interop", - "psr" - ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", "support": { - "issues": "https://github.com/php-fig/container/issues", - "source": "https://github.com/php-fig/container/tree/1.1.2" + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" }, - "time": "2021-11-05T16:50:12+00:00" + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" }, { - "name": "psr/http-client", - "version": "dev-master", + "name": "phar-io/version", + "version": "3.2.1", "source": { "type": "git", - "url": "https://github.com/php-fig/http-client.git", - "reference": "22b2ef5687f43679481615605d7a15c557ce85b1" + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-client/zipball/22b2ef5687f43679481615605d7a15c557ce85b1", - "reference": "22b2ef5687f43679481615605d7a15c557ce85b1", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "psr/http-message": "^1.0" + "php": "^7.2 || ^8.0" }, - "default-branch": true, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { - "psr-4": { - "Psr\\Http\\Client\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" } ], - "description": "Common interface for HTTP clients", - "homepage": "https://github.com/php-fig/http-client", - "keywords": [ - "http", - "http-client", - "psr", - "psr-18" - ], + "description": "Library for handling version information and constraints", "support": { - "source": "https://github.com/php-fig/http-client/tree/master" + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" }, - "time": "2020-09-19T09:12:31+00:00" + "time": "2022-02-21T01:04:05+00:00" }, { - "name": "psr/http-factory", - "version": "dev-master", + "name": "phpmailer/phpmailer", + "version": "v6.12.0", "source": { "type": "git", - "url": "https://github.com/php-fig/http-factory.git", - "reference": "36fa03d50ff82abcae81860bdaf4ed9a1510c7cd" + "url": "https://github.com/PHPMailer/PHPMailer.git", + "reference": "d1ac35d784bf9f5e61b424901d5a014967f15b12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-factory/zipball/36fa03d50ff82abcae81860bdaf4ed9a1510c7cd", - "reference": "36fa03d50ff82abcae81860bdaf4ed9a1510c7cd", + "url": "https://api.github.com/repos/PHPMailer/PHPMailer/zipball/d1ac35d784bf9f5e61b424901d5a014967f15b12", + "reference": "d1ac35d784bf9f5e61b424901d5a014967f15b12", "shasum": "" }, "require": { - "php": ">=7.0.0", - "psr/http-message": "^1.0" + "ext-ctype": "*", + "ext-filter": "*", + "ext-hash": "*", + "php": ">=5.5.0" }, - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "doctrine/annotations": "^1.2.6 || ^1.13.3", + "php-parallel-lint/php-console-highlighter": "^1.0.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcompatibility/php-compatibility": "^9.3.5", + "roave/security-advisories": "dev-latest", + "squizlabs/php_codesniffer": "^3.7.2", + "yoast/phpunit-polyfills": "^1.0.4" + }, + "suggest": { + "decomplexity/SendOauth2": "Adapter for using XOAUTH2 authentication", + "ext-mbstring": "Needed to send email in multibyte encoding charset or decode encoded addresses", + "ext-openssl": "Needed for secure SMTP sending and DKIM signing", + "greew/oauth2-azure-provider": "Needed for Microsoft Azure XOAUTH2 authentication", + "hayageek/oauth2-yahoo": "Needed for Yahoo XOAUTH2 authentication", + "league/oauth2-google": "Needed for Google XOAUTH2 authentication", + "psr/log": "For optional PSR-3 debug logging", + "symfony/polyfill-mbstring": "To support UTF-8 if the Mbstring PHP extension is not enabled (^1.2)", + "thenetworg/oauth2-azure": "Needed for Microsoft XOAUTH2 authentication" }, + "type": "library", "autoload": { "psr-4": { - "Psr\\Http\\Message\\": "src/" + "PHPMailer\\PHPMailer\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "LGPL-2.1-only" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Marcus Bointon", + "email": "phpmailer@synchromedia.co.uk" + }, + { + "name": "Jim Jagielski", + "email": "jimjag@gmail.com" + }, + { + "name": "Andy Prevost", + "email": "codeworxtech@users.sourceforge.net" + }, + { + "name": "Brent R. Matzelle" } ], - "description": "Common interfaces for PSR-7 HTTP message factories", - "keywords": [ - "factory", - "http", - "message", - "psr", - "psr-17", - "psr-7", - "request", - "response" - ], + "description": "PHPMailer is a full-featured email creation and transfer class for PHP", "support": { - "source": "https://github.com/php-fig/http-factory/tree/master" + "issues": "https://github.com/PHPMailer/PHPMailer/issues", + "source": "https://github.com/PHPMailer/PHPMailer/tree/v6.12.0" }, - "time": "2020-09-17T16:52:55+00:00" + "funding": [ + { + "url": "https://github.com/Synchro", + "type": "github" + } + ], + "time": "2025-10-15T16:49:08+00:00" }, { - "name": "psr/http-message", - "version": "dev-master", + "name": "phpunit/php-code-coverage", + "version": "9.2.32", "source": { "type": "git", - "url": "https://github.com/php-fig/http-message.git", - "reference": "efd67d1dc14a7ef4fc4e518e7dee91c271d524e4" + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/http-message/zipball/efd67d1dc14a7ef4fc4e518e7dee91c271d524e4", - "reference": "efd67d1dc14a7ef4fc4e518e7dee91c271d524e4", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/85402a822d1ecf1db1096959413d35e1c37cf1a5", + "reference": "85402a822d1ecf1db1096959413d35e1c37cf1a5", "shasum": "" }, "require": { - "php": ">=5.3.0" + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.19.1 || ^5.1.0", + "php": ">=7.3", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-text-template": "^2.0.4", + "sebastian/code-unit-reverse-lookup": "^2.0.3", + "sebastian/complexity": "^2.0.3", + "sebastian/environment": "^5.1.5", + "sebastian/lines-of-code": "^1.0.4", + "sebastian/version": "^3.0.2", + "theseer/tokenizer": "^1.2.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.6" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-main": "9.2.x-dev" } }, "autoload": { - "psr-4": { - "Psr\\Http\\Message\\": "src/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "http://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for HTTP messages", - "homepage": "https://github.com/php-fig/http-message", + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", "keywords": [ - "http", - "http-message", - "psr", - "psr-7", - "request", - "response" + "coverage", + "testing", + "xunit" ], "support": { - "source": "https://github.com/php-fig/http-message/tree/master" + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.32" }, - "time": "2019-08-29T13:16:46+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-08-22T04:23:01+00:00" }, { - "name": "psr/log", - "version": "1.1.4", + "name": "phpunit/php-file-iterator", + "version": "3.0.6", "source": { "type": "git", - "url": "https://github.com/php-fig/log.git", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11" + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/log/zipball/d49695b909c3b7628b6289db5479a1c204601f11", - "reference": "d49695b909c3b7628b6289db5479a1c204601f11", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { - "php": ">=5.3.0" + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.1.x-dev" + "dev-master": "3.0-dev" } }, "autoload": { - "psr-4": { - "Psr\\Log\\": "Psr/Log/" - } + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "PHP-FIG", - "homepage": "https://www.php-fig.org/" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "Common interface for logging libraries", - "homepage": "https://github.com/php-fig/log", + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", "keywords": [ - "log", - "psr", - "psr-3" + "filesystem", + "iterator" ], "support": { - "source": "https://github.com/php-fig/log/tree/1.1.4" + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, - "time": "2021-05-03T11:20:27+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2021-12-02T12:48:52+00:00" }, { - "name": "ralouphie/getallheaders", - "version": "3.0.3", + "name": "phpunit/php-invoker", + "version": "3.1.1", "source": { "type": "git", - "url": "https://github.com/ralouphie/getallheaders.git", - "reference": "120b605dfeb996808c31b6477290a714d356e822" + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", - "reference": "120b605dfeb996808c31b6477290a714d356e822", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5a10147d0aaf65b58940a0b72f71c9ac0423cc67", + "reference": "5a10147d0aaf65b58940a0b72f71c9ac0423cc67", "shasum": "" }, "require": { - "php": ">=5.6" + "php": ">=7.3" }, "require-dev": { - "php-coveralls/php-coveralls": "^2.1", - "phpunit/phpunit": "^5 || ^6.5" + "ext-pcntl": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcntl": "*" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, "autoload": { - "files": [ - "src/getallheaders.php" + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Ralph Khattar", - "email": "ralph.khattar@gmail.com" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "A polyfill for getallheaders.", + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], "support": { - "issues": "https://github.com/ralouphie/getallheaders/issues", - "source": "https://github.com/ralouphie/getallheaders/tree/develop" + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/3.1.1" }, - "time": "2019-03-08T08:55:37+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-09-28T05:58:55+00:00" }, { - "name": "simplepie/simplepie", - "version": "1.5.6", + "name": "phpunit/php-text-template", + "version": "2.0.4", "source": { "type": "git", - "url": "https://github.com/simplepie/simplepie.git", - "reference": "1c68e14ca3ac84346b6e6fe3c5eedf725d0f92c6" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/simplepie/simplepie/zipball/1c68e14ca3ac84346b6e6fe3c5eedf725d0f92c6", - "reference": "1c68e14ca3ac84346b6e6fe3c5eedf725d0f92c6", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", + "reference": "5da5f67fc95621df9ff4c4e5a84d6a8a2acf7c28", "shasum": "" }, "require": { - "ext-pcre": "*", - "ext-xml": "*", - "ext-xmlreader": "*", - "php": ">=5.6.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "~5.4.3 || ~6.5" - }, - "suggest": { - "ext-curl": "", - "ext-iconv": "", - "ext-intl": "", - "ext-mbstring": "", - "mf2/mf2": "Microformat module that allows for parsing HTML for microformats" + "phpunit/phpunit": "^9.3" }, "type": "library", - "autoload": { - "psr-0": { - "SimplePie": "library" + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" } }, + "autoload": { + "classmap": [ + "src/" + ] + }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" ], "authors": [ { - "name": "Ryan Parman", - "homepage": "http://ryanparman.com/", - "role": "Creator, alumnus developer" - }, - { - "name": "Sam Sneddon", - "homepage": "https://gsnedders.com/", - "role": "Alumnus developer" - }, - { - "name": "Ryan McCue", - "email": "me@ryanmccue.info", - "homepage": "http://ryanmccue.info/", - "role": "Developer" + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "description": "A simple Atom/RSS parsing library for PHP", - "homepage": "http://simplepie.org/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "atom", - "feeds", - "rss" + "template" ], "support": { - "issues": "https://github.com/simplepie/simplepie/issues", - "source": "https://github.com/simplepie/simplepie/tree/1.5.6" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/2.0.4" }, - "time": "2020-10-14T07:17:22+00:00" + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-10-26T05:33:50+00:00" }, { - "name": "smarty/smarty", - "version": "dev-master", + "name": "phpunit/php-timer", + "version": "5.0.3", "source": { "type": "git", - "url": "https://github.com/smarty-php/smarty.git", - "reference": "cd962280ce9af71e35d64248f85d4fe4b6cf7db5" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/smarty-php/smarty/zipball/cd962280ce9af71e35d64248f85d4fe4b6cf7db5", - "reference": "cd962280ce9af71e35d64248f85d4fe4b6cf7db5", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", + "reference": "5a63ce20ed1b5bf577850e2c4e87f4aa902afbd2", "shasum": "" }, "require": { - "php": "^7.1 || ^8.0" + "php": ">=7.3" }, "require-dev": { - "phpunit/phpunit": "^8.5 || ^7.5", - "smarty/smarty-lexer": "^3.1" + "phpunit/phpunit": "^9.3" }, - "default-branch": true, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "5.0-dev" } }, "autoload": { "classmap": [ - "libs/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0" + "BSD-3-Clause" ], "authors": [ { - "name": "Monte Ohrt", - "email": "monte@ohrt.com" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "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", + "type": "github" + } + ], + "time": "2020-10-26T13:16:10+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.6.36", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "abab27ed286d3e1246fbbfe6b56bfd732d945ec9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/abab27ed286d3e1246fbbfe6b56bfd732d945ec9", + "reference": "abab27ed286d3e1246fbbfe6b56bfd732d945ec9", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.5.0 || ^2", + "ext-dom": "*", + "ext-filter": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.13.4", + "phar-io/manifest": "^2.0.4", + "phar-io/version": "^3.2.1", + "php": ">=7.3", + "phpunit/php-code-coverage": "^9.2.32", + "phpunit/php-file-iterator": "^3.0.6", + "phpunit/php-invoker": "^3.1.1", + "phpunit/php-text-template": "^2.0.4", + "phpunit/php-timer": "^5.0.3", + "sebastian/cli-parser": "^1.0.2", + "sebastian/code-unit": "^1.0.8", + "sebastian/comparator": "^4.0.10", + "sebastian/diff": "^4.0.6", + "sebastian/environment": "^5.1.5", + "sebastian/exporter": "^4.0.9", + "sebastian/global-state": "^5.0.8", + "sebastian/object-enumerator": "^4.0.4", + "sebastian/resource-operations": "^3.0.4", + "sebastian/type": "^3.2.1", + "sebastian/version": "^3.0.2" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.6-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.6.36" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsoring.html", + "type": "other" + } + ], + "time": "2026-08-11T06:25:15+00:00" + }, + { + "name": "pimple/pimple", + "version": "v3.6.2", + "source": { + "type": "git", + "url": "https://github.com/silexphp/Pimple.git", + "reference": "8cfe7f74ac22a433d303914eba9ea4c2a834edce" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/silexphp/Pimple/zipball/8cfe7f74ac22a433d303914eba9ea4c2a834edce", + "reference": "8cfe7f74ac22a433d303914eba9ea4c2a834edce", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "psr/container": "^1.1 || ^2.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.x-dev" + } + }, + "autoload": { + "psr-0": { + "Pimple": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + } + ], + "description": "Pimple, a simple Dependency Injection Container", + "homepage": "https://pimple.symfony.com", + "keywords": [ + "container", + "dependency injection" + ], + "support": { + "source": "https://github.com/silexphp/Pimple/tree/v3.6.2" + }, + "time": "2026-02-26T08:23:44+00:00" + }, + { + "name": "psr/container", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "reference": "c71ecc56dfe541dbd90c5360474fbc405f8d5963", + "shasum": "" + }, + "require": { + "php": ">=7.4.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "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.3", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-client.git", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-client/zipball/bb5906edc1c324c9a05aa0873d40117941e5fa90", + "reference": "bb5906edc1c324c9a05aa0873d40117941e5fa90", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Client\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP clients", + "homepage": "https://github.com/php-fig/http-client", + "keywords": [ + "http", + "http-client", + "psr", + "psr-18" + ], + "support": { + "source": "https://github.com/php-fig/http-client" + }, + "time": "2023-09-23T14:17:50+00:00" + }, + { + "name": "psr/http-factory", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-factory.git", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-factory/zipball/2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "reference": "2b4765fddfe3b508ac62f829e852b1501d3f6e8a", + "shasum": "" + }, + "require": { + "php": ">=7.1", + "psr/http-message": "^1.0 || ^2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "https://www.php-fig.org/" + } + ], + "description": "PSR-17: Common interfaces for PSR-7 HTTP message factories", + "keywords": [ + "factory", + "http", + "message", + "psr", + "psr-17", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-factory" + }, + "time": "2024-04-15T12:06:14+00:00" + }, + { + "name": "psr/http-message", + "version": "1.1", + "source": { + "type": "git", + "url": "https://github.com/php-fig/http-message.git", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/http-message/zipball/cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "reference": "cb6ce4845ce34a8ad9e68117c10ee90a29919eba", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Http\\Message\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://www.php-fig.org/" + } + ], + "description": "Common interface for HTTP messages", + "homepage": "https://github.com/php-fig/http-message", + "keywords": [ + "http", + "http-message", + "psr", + "psr-7", + "request", + "response" + ], + "support": { + "source": "https://github.com/php-fig/http-message/tree/1.1" + }, + "time": "2023-04-04T09:50:52+00:00" + }, + { + "name": "ralouphie/getallheaders", + "version": "3.0.3", + "source": { + "type": "git", + "url": "https://github.com/ralouphie/getallheaders.git", + "reference": "120b605dfeb996808c31b6477290a714d356e822" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/120b605dfeb996808c31b6477290a714d356e822", + "reference": "120b605dfeb996808c31b6477290a714d356e822", + "shasum": "" + }, + "require": { + "php": ">=5.6" + }, + "require-dev": { + "php-coveralls/php-coveralls": "^2.1", + "phpunit/phpunit": "^5 || ^6.5" + }, + "type": "library", + "autoload": { + "files": [ + "src/getallheaders.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ralph Khattar", + "email": "ralph.khattar@gmail.com" + } + ], + "description": "A polyfill for getallheaders.", + "support": { + "issues": "https://github.com/ralouphie/getallheaders/issues", + "source": "https://github.com/ralouphie/getallheaders/tree/develop" + }, + "time": "2019-03-08T08:55:37+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "1.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "reference": "2b56bea83a09de3ac06bb18b92f068e60cc6f50b", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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.2" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:27:43+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/1fc9f64c0927627ef78ba436c9b17d967e68e120", + "reference": "1fc9f64c0927627ef78ba436c9b17d967e68e120", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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", + "type": "github" + } + ], + "time": "2020-10-26T13:08:54+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "reference": "ac91f01ccec49fb77bdc6fd1e548bc70f7faa3e5", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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", + "type": "github" + } + ], + "time": "2020-09-28T05:30:19+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.10", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/e4df00b9b3571187db2831ae9aada2c6efbd715d", + "reference": "e4df00b9b3571187db2831ae9aada2c6efbd715d", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "source": "https://github.com/sebastianbergmann/comparator/tree/4.0.10" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/comparator", + "type": "tidelift" + } + ], + "time": "2026-01-24T09:22:56+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/25f207c40d62b8b7aa32f5ab026c53561964053a", + "reference": "25f207c40d62b8b7aa32f5ab026c53561964053a", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:19:30+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.6", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ba01945089c3a293b01ba9badc29ad55b106b0bc", + "reference": "ba01945089c3a293b01ba9badc29ad55b106b0bc", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "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" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "source": "https://github.com/sebastianbergmann/diff/tree/4.0.6" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T06:30:58+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "reference": "830c43a844f1f8d5b7a1f6d6076b784454d8b7ed", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "source": "https://github.com/sebastianbergmann/environment/tree/5.1.5" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:03:51+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.9", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "4352c1a3df741a7ba9e61af6fed51d1fee41cbf7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/4352c1a3df741a7ba9e61af6fed51d1fee41cbf7", + "reference": "4352c1a3df741a7ba9e61af6fed51d1fee41cbf7", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "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.9" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/exporter", + "type": "tidelift" + } + ], + "time": "2026-08-11T04:55:59+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.8", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "reference": "b6781316bdcd28260904e7cc18ec983d0d2ef4f6", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.8" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/global-state", + "type": "tidelift" + } + ], + "time": "2025-08-10T07:10:35+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "reference": "e1e4a170560925c26d424b6a03aed157e7dcc5c5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.18 || ^5.0", + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-12-22T06:20:34+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/5c9eeac41b290a3712d88851518825ad78f45c71", + "reference": "5c9eeac41b290a3712d88851518825ad78f45c71", + "shasum": "" + }, + "require": { + "php": ">=7.3", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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", + "type": "github" + } + ], + "time": "2020-10-26T13:12:34+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "reference": "b4f479ebdbf63ac605d183ece17d8d7fe49c15c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "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", + "type": "github" + } + ], + "time": "2020-10-26T13:14:26+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "c85be6922b7fd365942b986b9a50397d65407611" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/c85be6922b7fd365942b986b9a50397d65407611", + "reference": "c85be6922b7fd365942b986b9a50397d65407611", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/4.0.7" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://liberapay.com/sebastianbergmann", + "type": "liberapay" + }, + { + "url": "https://thanks.dev/u/gh/sebastianbergmann", + "type": "thanks_dev" + }, + { + "url": "https://tidelift.com/funding/github/packagist/sebastian/recursion-context", + "type": "tidelift" + } + ], + "time": "2026-08-11T05:25:24+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "reference": "05d5692a7993ecccd56a03e40cd7e5b09b1d404e", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "support": { + "source": "https://github.com/sebastianbergmann/resource-operations/tree/3.0.4" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-14T16:00:52+00:00" + }, + { + "name": "sebastian/type", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "reference": "75e2c2a32f5e0b3aef905b9ed0b179b953b3d7c7", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "require-dev": { + "phpunit/phpunit": "^9.5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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/3.2.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2023-02-03T06:13:03+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "c6c1022351a901512170118436c764e473f6de8c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/c6c1022351a901512170118436c764e473f6de8c", + "reference": "c6c1022351a901512170118436c764e473f6de8c", + "shasum": "" + }, + "require": { + "php": ">=7.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "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", + "type": "github" + } + ], + "time": "2020-09-28T06:39:44+00:00" + }, + { + "name": "simplepie/simplepie", + "version": "1.9.0", + "source": { + "type": "git", + "url": "https://github.com/simplepie/simplepie.git", + "reference": "76cccb1b2c5dcaf44f304c925ab30c0f48643992" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/simplepie/simplepie/zipball/76cccb1b2c5dcaf44f304c925ab30c0f48643992", + "reference": "76cccb1b2c5dcaf44f304c925ab30c0f48643992", + "shasum": "" + }, + "require": { + "ext-pcre": "*", + "ext-xml": "*", + "ext-xmlreader": "*", + "php": ">=7.2.0" + }, + "require-dev": { + "donatj/mock-webserver": "^2.7", + "friendsofphp/php-cs-fixer": "^2.19 || ^3.8", + "mf2/mf2": "^0.5.0", + "phpstan/phpstan": "~1.12.2", + "phpunit/phpunit": "^8 || ^9 || ^10", + "psr/http-client": "^1.0", + "psr/http-factory": "^1.0", + "psr/simple-cache": "^1 || ^2 || ^3" + }, + "suggest": { + "ext-curl": "", + "ext-iconv": "", + "ext-intl": "", + "ext-mbstring": "", + "mf2/mf2": "Microformat module that allows for parsing HTML for microformats" + }, + "type": "library", + "autoload": { + "psr-0": { + "SimplePie": "library" + }, + "psr-4": { + "SimplePie\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Ryan Parman", + "homepage": "http://ryanparman.com/", + "role": "Creator, alumnus developer" + }, + { + "name": "Sam Sneddon", + "homepage": "https://gsnedders.com/", + "role": "Alumnus developer" + }, + { + "name": "Ryan McCue", + "email": "me@ryanmccue.info", + "homepage": "http://ryanmccue.info/", + "role": "Developer" + } + ], + "description": "A simple Atom/RSS parsing library for PHP", + "homepage": "http://simplepie.org/", + "keywords": [ + "atom", + "feeds", + "rss" + ], + "support": { + "issues": "https://github.com/simplepie/simplepie/issues", + "source": "https://github.com/simplepie/simplepie/tree/1.9.0" + }, + "time": "2025-09-12T06:34:27+00:00" + }, + { + "name": "smarty/smarty", + "version": "v4.5.7", + "source": { + "type": "git", + "url": "https://github.com/smarty-php/smarty.git", + "reference": "838d6ad1c635f8a6bafc08d791b8af18d8304b3a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/smarty-php/smarty/zipball/838d6ad1c635f8a6bafc08d791b8af18d8304b3a", + "reference": "838d6ad1c635f8a6bafc08d791b8af18d8304b3a", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^7.5", + "smarty/smarty-lexer": "^3.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "libs/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0" + ], + "authors": [ + { + "name": "Monte Ohrt", + "email": "monte@ohrt.com" + }, + { + "name": "Uwe Tews", + "email": "uwe.tews@googlemail.com" + }, + { + "name": "Rodney Rehm", + "email": "rodney.rehm@medialize.de" + }, + { + "name": "Simon Wisselink", + "homepage": "https://www.iwink.nl/" + } + ], + "description": "Smarty - the compiling PHP template engine", + "homepage": "https://smarty-php.github.io/smarty/", + "keywords": [ + "templating" + ], + "support": { + "forum": "https://github.com/smarty-php/smarty/discussions", + "issues": "https://github.com/smarty-php/smarty/issues", + "source": "https://github.com/smarty-php/smarty/tree/v4.5.7" + }, + "funding": [ + { + "url": "https://github.com/wisskid", + "type": "github" + } + ], + "time": "2026-06-29T08:48:56+00:00" + }, + { + "name": "symfony/console", + "version": "v5.4.47", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "reference": "c4ba980ca61a9eb18ee6bcc73f28e475852bb1ed", + "shasum": "" + }, + "require": { + "php": ">=7.2.5", + "symfony/deprecation-contracts": "^2.1|^3", + "symfony/polyfill-mbstring": "~1.0", + "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", + "symfony/lock": "<4.4", + "symfony/process": "<4.4" + }, + "provide": { + "psr/log-implementation": "1.0|2.0" + }, + "require-dev": { + "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", + "symfony/event-dispatcher": "", + "symfony/lock": "", + "symfony/process": "" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Console\\": "" + }, + "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": "Eases the creation of beautiful and testable command line interfaces", + "homepage": "https://symfony.com", + "keywords": [ + "cli", + "command-line", + "console", + "terminal" + ], + "support": { + "source": "https://github.com/symfony/console/tree/v5.4.47" + }, + "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": "2024-11-06T11:30:55+00:00" + }, + { + "name": "symfony/css-selector", + "version": "v6.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/css-selector.git", + "reference": "5484e316cd8125f5215bbf829151e2211aa6d101" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/5484e316cd8125f5215bbf829151e2211aa6d101", + "reference": "5484e316cd8125f5215bbf829151e2211aa6d101", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\CssSelector\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Jean-François Simon", + "email": "jeanfrancois.simon@sensiolabs.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Converts CSS selectors to XPath expressions", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/css-selector/tree/v6.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-08-23T07:35:46+00:00" + }, + { + "name": "symfony/deprecation-contracts", + "version": "v3.7.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/deprecation-contracts.git", + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/f3202fa1b5097b0af062dc978b32ecf63404e31d", + "reference": "f3202fa1b5097b0af062dc978b32ecf63404e31d", + "shasum": "" + }, + "require": { + "php": ">=8.1" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" + } + }, + "autoload": { + "files": [ + "function.php" + ] + }, + "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": "A generic function and convention to trigger deprecation notices", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/deprecation-contracts/tree/v3.7.1" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, { - "name": "Uwe Tews", - "email": "uwe.tews@googlemail.com" + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "name": "Rodney Rehm", - "email": "rodney.rehm@medialize.de" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-06-05T06:23:12+00:00" + }, + { + "name": "symfony/filesystem", + "version": "v6.4.45", + "source": { + "type": "git", + "url": "https://github.com/symfony/filesystem.git", + "reference": "6dabf41c21957a2060f101bd7bf7e322989866bd" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/6dabf41c21957a2060f101bd7bf7e322989866bd", + "reference": "6dabf41c21957a2060f101bd7bf7e322989866bd", + "shasum": "" + }, + "require": { + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-mbstring": "~1.8" + }, + "require-dev": { + "symfony/process": "^5.4|^6.4|^7.0" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Filesystem\\": "" + }, + "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 basic utilities for the filesystem", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/filesystem/tree/v6.4.45" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-08-23T07:59:31+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.37.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/141046a8f9477948ff284fa65be2095baafb94f2", + "reference": "141046a8f9477948ff284fa65be2095baafb94f2", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "provide": { + "ext-ctype": "*" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "support": { + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.37.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-04-10T16:19:22+00:00" + }, + { + "name": "symfony/polyfill-intl-grapheme", + "version": "v1.41.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-grapheme.git", + "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-grapheme/zipball/bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", + "reference": "bb899c1db0aa8127dc3afe8cda4a67eb24915f8d", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Grapheme\\": "" + } + }, + "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 for intl's grapheme_* functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "grapheme", + "intl", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-grapheme/tree/v1.41.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2026-07-28T08:25:59+00:00" + }, + { + "name": "symfony/polyfill-intl-normalizer", + "version": "v1.42.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-intl-normalizer.git", + "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-intl-normalizer/zipball/aa20edea75bd9c48cfecc8360922e5a6e5c44502", + "reference": "aa20edea75bd9c48cfecc8360922e5a6e5c44502", + "shasum": "" + }, + "require": { + "php": ">=7.2" + }, + "suggest": { + "ext-intl": "For best performance" + }, + "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, + "autoload": { + "files": [ + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Intl\\Normalizer\\": "" + }, + "classmap": [ + "Resources/stubs" + ] + }, + "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 for intl's Normalizer class and related functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "intl", + "normalizer", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-intl-normalizer/tree/v1.42.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" }, { - "name": "Simon Wisselink", - "homepage": "https://www.iwink.nl/" + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" } ], - "description": "Smarty - the compiling PHP template engine", - "homepage": "https://smarty-php.github.io/smarty/", - "keywords": [ - "templating" - ], - "support": { - "forum": "https://github.com/smarty-php/smarty/discussions", - "issues": "https://github.com/smarty-php/smarty/issues", - "source": "https://github.com/smarty-php/smarty/tree/master" - }, - "time": "2021-12-03T16:13:52+00:00" + "time": "2026-08-07T06:33:24+00:00" }, { - "name": "symfony/console", - "version": "3.4.x-dev", + "name": "symfony/polyfill-mbstring", + "version": "v1.38.2", "source": { "type": "git", - "url": "https://github.com/symfony/console.git", - "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81" + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/a10b1da6fc93080c180bba7219b5ff5b7518fe81", - "reference": "a10b1da6fc93080c180bba7219b5ff5b7518fe81", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", + "reference": "d3d318bad5e7a1bfbd026009c8bfb8d8f99ae6b6", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", - "symfony/debug": "~2.8|~3.0|~4.0", - "symfony/polyfill-mbstring": "~1.0" - }, - "conflict": { - "symfony/dependency-injection": "<3.4", - "symfony/process": "<3.3" + "ext-iconv": "*", + "php": ">=7.2" }, "provide": { - "psr/log-implementation": "1.0" - }, - "require-dev": { - "psr/log": "~1.0", - "symfony/config": "~3.3|~4.0", - "symfony/dependency-injection": "~3.4|~4.0", - "symfony/event-dispatcher": "~2.8|~3.0|~4.0", - "symfony/lock": "~3.4|~4.0", - "symfony/process": "~3.3|~4.0" + "ext-mbstring": "*" }, "suggest": { - "psr/log": "For using the console logger", - "symfony/event-dispatcher": "", - "symfony/lock": "", - "symfony/process": "" + "ext-mbstring": "For best performance" }, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Console\\": "" - }, - "exclude-from-classmap": [ - "/Tests/" - ] + "Symfony\\Polyfill\\Mbstring\\": "" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -1676,18 +4044,25 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony Console Component", + "description": "Symfony polyfill for the Mbstring extension", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/console/tree/3.4" + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.38.2" }, "funding": [ { @@ -1698,39 +4073,50 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2020-10-24T10:57:07+00:00" + "time": "2026-05-27T06:59:30+00:00" }, { - "name": "symfony/css-selector", - "version": "5.4.x-dev", + "name": "symfony/polyfill-php73", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/css-selector.git", - "reference": "44b933f98bb4b5220d10bed9ce5662f8c2d13dcc" + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/44b933f98bb4b5220d10bed9ce5662f8c2d13dcc", - "reference": "44b933f98bb4b5220d10bed9ce5662f8c2d13dcc", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/0f68c03565dcaaf25a890667542e8bd75fe7e5bb", + "reference": "0f68c03565dcaaf25a890667542e8bd75fe7e5bb", "shasum": "" }, "require": { - "php": ">=7.2.5", - "symfony/polyfill-php80": "^1.16" + "php": ">=7.2" }, - "default-branch": true, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\CssSelector\\": "" + "Symfony\\Polyfill\\Php73\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1739,22 +4125,24 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" - }, - { - "name": "Jean-François Simon", - "email": "jeanfrancois.simon@sensiolabs.com" + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Converts CSS selectors to XPath expressions", + "description": "Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.0" + "source": "https://github.com/symfony/polyfill-php73/tree/v1.37.0" }, "funding": [ { @@ -1765,45 +4153,50 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-09-09T08:06:01+00:00" + "time": "2024-09-09T11:45:10+00:00" }, { - "name": "symfony/debug", - "version": "4.4.x-dev", + "name": "symfony/polyfill-php80", + "version": "v1.37.0", "source": { "type": "git", - "url": "https://github.com/symfony/debug.git", - "reference": "346e1507eeb3f566dcc7a116fefaa407ee84691b" + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/346e1507eeb3f566dcc7a116fefaa407ee84691b", - "reference": "346e1507eeb3f566dcc7a116fefaa407ee84691b", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/dfb55726c3a76ea3b6459fcfda1ec2d80a682411", + "reference": "dfb55726c3a76ea3b6459fcfda1ec2d80a682411", "shasum": "" }, "require": { - "php": ">=7.1.3", - "psr/log": "^1|^2|^3" - }, - "conflict": { - "symfony/http-kernel": "<3.4" - }, - "require-dev": { - "symfony/http-kernel": "^3.4|^4.0|^5.0" + "php": ">=7.2" }, - "default-branch": true, "type": "library", + "extra": { + "thanks": { + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" + } + }, "autoload": { + "files": [ + "bootstrap.php" + ], "psr-4": { - "Symfony\\Component\\Debug\\": "" + "Symfony\\Polyfill\\Php80\\": "" }, - "exclude-from-classmap": [ - "/Tests/" + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1812,18 +4205,28 @@ ], "authors": [ { - "name": "Fabien Potencier", - "email": "fabien@symfony.com" + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" }, { "name": "Symfony Community", "homepage": "https://symfony.com/contributors" } ], - "description": "Provides tools to ease debugging PHP code", + "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/debug/tree/4.4" + "source": "https://github.com/symfony/polyfill-php80/tree/v1.37.0" }, "funding": [ { @@ -1834,43 +4237,50 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-11-29T08:40:48+00:00" + "time": "2026-04-10T16:19:22+00:00" }, { - "name": "symfony/deprecation-contracts", - "version": "2.5.x-dev", + "name": "symfony/polyfill-php82", + "version": "v1.38.1", "source": { "type": "git", - "url": "https://github.com/symfony/deprecation-contracts.git", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8" + "url": "https://github.com/symfony/polyfill-php82.git", + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/deprecation-contracts/zipball/6f981ee24cf69ee7ce9736146d1c57c2780598a8", - "reference": "6f981ee24cf69ee7ce9736146d1c57c2780598a8", + "url": "https://api.github.com/repos/symfony/polyfill-php82/zipball/002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", + "reference": "002dc0cfe5fd4ed6033d48f27d4f19a486c4b04b", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=7.2" }, "type": "library", "extra": { - "branch-alias": { - "dev-main": "2.5-dev" - }, "thanks": { - "name": "symfony/contracts", - "url": "https://github.com/symfony/contracts" + "url": "https://github.com/symfony/polyfill", + "name": "symfony/polyfill" } }, "autoload": { "files": [ - "function.php" + "bootstrap.php" + ], + "psr-4": { + "Symfony\\Polyfill\\Php82\\": "" + }, + "classmap": [ + "Resources/stubs" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1887,10 +4297,16 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "A generic function and convention to trigger deprecation notices", + "description": "Symfony polyfill backporting some PHP 8.2+ features to lower PHP versions", "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "polyfill", + "portable", + "shim" + ], "support": { - "source": "https://github.com/symfony/deprecation-contracts/tree/main" + "source": "https://github.com/symfony/polyfill-php82/tree/v1.38.1" }, "funding": [ { @@ -1901,53 +4317,55 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-07-12T14:48:14+00:00" + "time": "2026-05-26T12:45:58+00:00" }, { - "name": "symfony/polyfill-mbstring", - "version": "dev-main", + "name": "symfony/service-contracts", + "version": "v3.7.3", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825" + "url": "https://github.com/symfony/service-contracts.git", + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/0abb51d2f102e00a4eefcf46ba7fec406d245825", - "reference": "0abb51d2f102e00a4eefcf46ba7fec406d245825", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", + "reference": "15e6a07ec2a2c75ceb1b21dd98105ee8456d2257", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "psr/container": "^1.1|^2.0", + "symfony/deprecation-contracts": "^2.5|^3" }, - "provide": { - "ext-mbstring": "*" - }, - "suggest": { - "ext-mbstring": "For best performance" + "conflict": { + "ext-psr": "<1.1|>=2" }, - "default-branch": true, "type": "library", "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" + "url": "https://github.com/symfony/contracts", + "name": "symfony/contracts" + }, + "branch-alias": { + "dev-main": "3.7-dev" } }, "autoload": { "psr-4": { - "Symfony\\Polyfill\\Mbstring\\": "" + "Symfony\\Contracts\\Service\\": "" }, - "files": [ - "bootstrap.php" + "exclude-from-classmap": [ + "/Test/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1964,17 +4382,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill for the Mbstring extension", + "description": "Generic abstractions related to writing services", "homepage": "https://symfony.com", "keywords": [ - "compatibility", - "mbstring", - "polyfill", - "portable", - "shim" + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" ], "support": { - "source": "https://github.com/symfony/polyfill-mbstring/tree/main" + "source": "https://github.com/symfony/service-contracts/tree/v3.7.3" }, "funding": [ { @@ -1985,50 +4404,57 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-11-30T18:21:41+00:00" + "time": "2026-07-27T15:39:01+00:00" }, { - "name": "symfony/polyfill-php80", - "version": "dev-main", + "name": "symfony/string", + "version": "v6.4.43", "source": { "type": "git", - "url": "https://github.com/symfony/polyfill-php80.git", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9" + "url": "https://github.com/symfony/string.git", + "reference": "2a8d515c3eaa5d33cf76d5fa277cdadd0a4e5b49" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/57b712b08eddb97c762a8caa32c84e037892d2e9", - "reference": "57b712b08eddb97c762a8caa32c84e037892d2e9", + "url": "https://api.github.com/repos/symfony/string/zipball/2a8d515c3eaa5d33cf76d5fa277cdadd0a4e5b49", + "reference": "2a8d515c3eaa5d33cf76d5fa277cdadd0a4e5b49", "shasum": "" }, "require": { - "php": ">=7.1" + "php": ">=8.1", + "symfony/polyfill-ctype": "~1.8", + "symfony/polyfill-intl-grapheme": "~1.0", + "symfony/polyfill-intl-normalizer": "~1.0", + "symfony/polyfill-mbstring": "~1.0" }, - "default-branch": true, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "1.23-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } + "conflict": { + "symfony/translation-contracts": "<2.5" + }, + "require-dev": { + "symfony/http-client": "^5.4|^6.0|^7.0", + "symfony/intl": "^6.2|^7.0", + "symfony/translation-contracts": "^2.5|^3.0", + "symfony/var-exporter": "^5.4|^6.0|^7.0" }, + "type": "library", "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Php80\\": "" - }, "files": [ - "bootstrap.php" + "Resources/functions.php" ], - "classmap": [ - "Resources/stubs" + "psr-4": { + "Symfony\\Component\\String\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2036,10 +4462,6 @@ "MIT" ], "authors": [ - { - "name": "Ion Bazan", - "email": "ion.bazan@gmail.com" - }, { "name": "Nicolas Grekas", "email": "p@tchwork.com" @@ -2049,16 +4471,18 @@ "homepage": "https://symfony.com/contributors" } ], - "description": "Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions", + "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": [ - "compatibility", - "polyfill", - "portable", - "shim" + "grapheme", + "i18n", + "string", + "unicode", + "utf-8", + "utf8" ], "support": { - "source": "https://github.com/symfony/polyfill-php80/tree/main" + "source": "https://github.com/symfony/string/tree/v6.4.43" }, "funding": [ { @@ -2069,51 +4493,99 @@ "url": "https://github.com/fabpot", "type": "github" }, + { + "url": "https://github.com/nicolas-grekas", + "type": "github" + }, { "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", "type": "tidelift" } ], - "time": "2021-09-13T13:58:33+00:00" + "time": "2026-07-28T07:28:15+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/b7489ce515e168639d17feec34b8847c326b0b3c", + "reference": "b7489ce515e168639d17feec34b8847c326b0b3c", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "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.3.1" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2025-11-17T20:03:58+00:00" }, { "name": "xpdo/xpdo", - "version": "3.x-dev", + "version": "v3.1.7", "source": { "type": "git", "url": "https://github.com/modxcms/xpdo.git", - "reference": "c4f7bc6aa6a3f83b12615d07c171d3b97f40328d" + "reference": "70a3046b7aff11ac8fff540e60d9750ebbd8fab9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/modxcms/xpdo/zipball/c4f7bc6aa6a3f83b12615d07c171d3b97f40328d", - "reference": "c4f7bc6aa6a3f83b12615d07c171d3b97f40328d", + "url": "https://api.github.com/repos/modxcms/xpdo/zipball/70a3046b7aff11ac8fff540e60d9750ebbd8fab9", + "reference": "70a3046b7aff11ac8fff540e60d9750ebbd8fab9", "shasum": "" }, "require": { "ext-json": "*", "ext-pdo": "*", "ext-simplexml": "*", - "php": ">=5.6", - "psr/container": "^1.0", - "symfony/console": "~2.8|~3.4" + "php": ">=7.2.5", + "psr/container": "^1.1 || ^2.0.1", + "symfony/console": "^5.4" }, "require-dev": { - "yoast/phpunit-polyfills": "^0.2.0" + "yoast/phpunit-polyfills": "^1.0" }, "suggest": { "ext-redis": "Allows caching using Redis" }, - "default-branch": true, "bin": [ "bin/xpdo" ], "type": "library", - "extra": { - "branch-alias": { - "dev-develop": "3.0.x-dev" - } - }, "autoload": { "psr-0": { "xPDO": [ @@ -2138,21 +4610,22 @@ "homepage": "http://www.xpdo.org/", "support": { "issues": "https://github.com/modxcms/xpdo/issues", - "source": "https://github.com/modxcms/xpdo/tree/3.x" + "source": "https://github.com/modxcms/xpdo/tree/v3.1.7" }, - "time": "2021-04-25T18:24:20+00:00" + "time": "2025-12-04T21:07:35+00:00" } ], "aliases": [], - "minimum-stability": "dev", - "stability-flags": { - "modx/revolution": 20 - }, - "prefer-stable": false, + "minimum-stability": "stable", + "stability-flags": {}, + "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=7.2" + "php": ">=8.1" + }, + "platform-dev": {}, + "platform-overrides": { + "php": "8.1.31" }, - "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.9.0" } diff --git a/core/components/pdotools/docs/changelog.txt b/core/components/pdotools/docs/changelog.txt index 18682ff..0668304 100644 --- a/core/components/pdotools/docs/changelog.txt +++ b/core/components/pdotools/docs/changelog.txt @@ -7,6 +7,7 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) ### Added +- PHPUnit 9.6 harness (Unit + Integration) and GitHub Actions on PHP 8.1, 8.2, 8.3, 8.4. - [#306] [pdoMenu] Added the "children" placeholder to tplInner. - [#355] [Fenom] Added type cast modifiers: boolval, doubleval, floatval, intval, strval. - [#356] [Fenom] Enabled the array_merge modifier by default. @@ -16,6 +17,8 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) ### Changed +- PHP requirement is now 8.1+. Unit and integration tests run on 8.1, 8.2, 8.3 and 8.4. +- [Fenom] Skip json_decode() when pdotools_fenom_options is empty (PHP 8.3). - [pdoTools3#9] [pdoFetch] Extra categories use MiniShop3 (`MiniShop3\Model\msCategoryMember`). miniShop2 class names and `&disableMS2` are removed. Use `&disableMS3` to skip extra categories. - [#377] [pdoPage] Mark AJAX requests as connector mode via MODX_CONNECTOR_INCLUDED. diff --git a/core/components/pdotools/phpunit.xml.dist b/core/components/pdotools/phpunit.xml.dist new file mode 100644 index 0000000..01c7674 --- /dev/null +++ b/core/components/pdotools/phpunit.xml.dist @@ -0,0 +1,29 @@ + + + + + tests/Unit + + + tests/Integration + + + + + src + + + + + + + diff --git a/core/components/pdotools/src/Parsing/Fenom/Fenom.php b/core/components/pdotools/src/Parsing/Fenom/Fenom.php index 4574cfa..386c7a4 100644 --- a/core/components/pdotools/src/Parsing/Fenom/Fenom.php +++ b/core/components/pdotools/src/Parsing/Fenom/Fenom.php @@ -48,7 +48,8 @@ public function __construct(modX $modx, CoreTools $pdoTools) 'force_include' => !$pdoTools->config('useFenomCache'), 'auto_reload' => $pdoTools->config('useFenomCache'), ]; - if ($options = json_decode($modx->getOption('pdotools_fenom_options'), true)) { + $rawOptions = $modx->getOption('pdotools_fenom_options'); + if (is_string($rawOptions) && $rawOptions !== '' && ($options = json_decode($rawOptions, true))) { $options = array_merge($default_options, $options); } else { $options = $default_options; @@ -243,7 +244,7 @@ protected function _addDefaultModifiers() 'number' => 'number_format', 'reset' => 'reset', 'end' => 'end', - + // Casts 'boolval' => 'boolval', 'doubleval' => 'doubleval', diff --git a/core/components/pdotools/tests/Integration/ModxTestCase.php b/core/components/pdotools/tests/Integration/ModxTestCase.php new file mode 100644 index 0000000..68d7b15 --- /dev/null +++ b/core/components/pdotools/tests/Integration/ModxTestCase.php @@ -0,0 +1,56 @@ +initialize('web'); + $siteStart = (int)$modx->getOption('site_start', null, 1); + $resource = $modx->getObject(modResource::class, $siteStart); + if ($resource) { + $modx->resource = $resource; + } + self::$modx = $modx; + } + + protected function setUp(): void + { + parent::setUp(); + if (!self::$modx instanceof modX) { + $this->markTestSkipped('Set MODX_TEST_BASE to a live MODX 3 root to run integration tests.'); + } + $this->assertNotEmpty( + self::$modx->getObject(modSnippet::class, ['name' => 'pdoResources']), + 'pdoTools snippets are not installed' + ); + } + + /** + * @param array $properties + * @return mixed + */ + protected function runPdoSnippet(string $name, array $properties = []) + { + return self::$modx->runSnippet($name, $properties); + } +} diff --git a/core/components/pdotools/tests/Integration/PluginPdoToolsTest.php b/core/components/pdotools/tests/Integration/PluginPdoToolsTest.php new file mode 100644 index 0000000..ed352aa --- /dev/null +++ b/core/components/pdotools/tests/Integration/PluginPdoToolsTest.php @@ -0,0 +1,27 @@ +getParser(); + if (!$parser instanceof Parser) { + $this->markTestSkipped('modParser.class is not pdoTools on this install.'); + } + $this->assertInstanceOf(Parser::class, $parser); + } + + public function testFenomProcessRendersOnResource(): void + { + $fenom = self::$modx->services->get('fenom'); + $this->assertNotNull($fenom); + $out = $fenom->process('{var $x = 1}{$x}'); + $this->assertSame('1', $out); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoArchiveTest.php b/core/components/pdotools/tests/Integration/SnippetPdoArchiveTest.php new file mode 100644 index 0000000..168e535 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoArchiveTest.php @@ -0,0 +1,19 @@ +runPdoSnippet('pdoArchive', [ + 'parents' => 0, + 'limit' => 5, + 'showHidden' => 1, + ]); + + $this->assertTrue(is_string($out) || $out === null); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoCrumbsTest.php b/core/components/pdotools/tests/Integration/SnippetPdoCrumbsTest.php new file mode 100644 index 0000000..05f4fd7 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoCrumbsTest.php @@ -0,0 +1,22 @@ +runPdoSnippet('pdoCrumbs', [ + 'showHome' => 1, + 'parents' => '0', + 'tpl' => '@INLINE [[+pagetitle]]', + 'tplCurrent' => '@INLINE [[+pagetitle]]', + 'tplHome' => '@INLINE [[+pagetitle]]', + 'outputSeparator' => ' / ', + ]); + + $this->assertIsString($out); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoFieldTest.php b/core/components/pdotools/tests/Integration/SnippetPdoFieldTest.php new file mode 100644 index 0000000..9881d0e --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoFieldTest.php @@ -0,0 +1,19 @@ +runPdoSnippet('pdoField', [ + 'id' => self::$modx->resource->id, + 'field' => 'pagetitle', + ]); + + $this->assertIsString($out); + $this->assertSame(self::$modx->resource->get('pagetitle'), $out); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoMenuTest.php b/core/components/pdotools/tests/Integration/SnippetPdoMenuTest.php new file mode 100644 index 0000000..08a6b39 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoMenuTest.php @@ -0,0 +1,23 @@ + 0, + 'limit' => 5, + 'cache' => 1, + 'showHidden' => 1, + ]; + $first = $this->runPdoSnippet('pdoMenu', $props); + $second = $this->runPdoSnippet('pdoMenu', $props); + + $this->assertIsString($first); + $this->assertSame($first, $second); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoNeighborsTest.php b/core/components/pdotools/tests/Integration/SnippetPdoNeighborsTest.php new file mode 100644 index 0000000..cde8393 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoNeighborsTest.php @@ -0,0 +1,18 @@ +runPdoSnippet('pdoNeighbors', [ + 'id' => self::$modx->resource->id, + 'tplWrapper' => '@INLINE [[+prev]][[+next]]', + ]); + + $this->assertTrue(is_string($out) || $out === null); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoPageTest.php b/core/components/pdotools/tests/Integration/SnippetPdoPageTest.php new file mode 100644 index 0000000..d853383 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoPageTest.php @@ -0,0 +1,23 @@ +runPdoSnippet('pdoPage', [ + 'element' => 'pdoResources', + 'parents' => 0, + 'limit' => 1, + 'page' => 1, + 'return' => 'ids', + 'showHidden' => 1, + 'showUnpublished' => 1, + ]); + + $this->assertIsString($out); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoResourcesTest.php b/core/components/pdotools/tests/Integration/SnippetPdoResourcesTest.php new file mode 100644 index 0000000..8c173d8 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoResourcesTest.php @@ -0,0 +1,22 @@ +runPdoSnippet('pdoResources', [ + 'parents' => 0, + 'limit' => 5, + 'return' => 'ids', + 'showHidden' => 1, + 'showUnpublished' => 1, + ]); + + $this->assertIsString($out); + $this->assertNotSame('', trim((string)$out)); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoSitemapTest.php b/core/components/pdotools/tests/Integration/SnippetPdoSitemapTest.php new file mode 100644 index 0000000..c665900 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoSitemapTest.php @@ -0,0 +1,20 @@ +runPdoSnippet('pdoSitemap', [ + 'parents' => 0, + 'limit' => 5, + 'showHidden' => 1, + ]); + + $this->assertIsString($out); + $this->assertStringContainsString('urlset', (string)$out); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoTitleTest.php b/core/components/pdotools/tests/Integration/SnippetPdoTitleTest.php new file mode 100644 index 0000000..889f961 --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoTitleTest.php @@ -0,0 +1,18 @@ +runPdoSnippet('pdoTitle', [ + 'id' => self::$modx->resource->id, + ]); + + $this->assertIsString($out); + $this->assertNotSame('', trim((string)$out)); + } +} diff --git a/core/components/pdotools/tests/Integration/SnippetPdoUsersTest.php b/core/components/pdotools/tests/Integration/SnippetPdoUsersTest.php new file mode 100644 index 0000000..60f986c --- /dev/null +++ b/core/components/pdotools/tests/Integration/SnippetPdoUsersTest.php @@ -0,0 +1,18 @@ +runPdoSnippet('pdoUsers', [ + 'limit' => 5, + 'return' => 'ids', + ]); + + $this->assertIsString($out); + } +} diff --git a/core/components/pdotools/tests/Stubs/ModxStub.php b/core/components/pdotools/tests/Stubs/ModxStub.php new file mode 100644 index 0000000..f21eaa6 --- /dev/null +++ b/core/components/pdotools/tests/Stubs/ModxStub.php @@ -0,0 +1,263 @@ + */ + private $items = []; + + public function has($key): bool + { + return array_key_exists($key, $this->items); + } + + public function add($key, $value): void + { + $this->items[$key] = $value; + } + + public function get($key) + { + return $this->items[$key] ?? null; + } + + public function offsetExists($offset): bool + { + return $this->has($offset); + } + + public function offsetGet($offset) + { + return $this->get($offset); + } + + public function offsetSet($offset, $value): void + { + $this->add($offset, $value); + } + + public function offsetUnset($offset): void + { + unset($this->items[$offset]); + } + } +} + +namespace MODX\Revolution { + + if (!class_exists(modX::class, false)) { + class modX + { + public $user; + public $context; + public $resource; + /** @var \ModxPro\PdoTools\Tests\Stubs\ServiceBag */ + public $services; + /** @var array */ + public $config = []; + /** @var array */ + public $placeholders = []; + /** @var array */ + public $classMap = []; + /** @var array */ + public $elementCache = []; + public $queryTime = 0; + public $executedQueries = 0; + /** @var string[] */ + public $logs = []; + + public function __construct() + { + $this->user = new \stdClass(); + $this->user->id = 0; + $this->context = new \stdClass(); + $this->context->key = 'web'; + $this->services = new \ModxPro\PdoTools\Tests\Stubs\ServiceBag(); + $this->services->add('lexicon', new class { + public function load($topic = null): void + { + } + }); + } + + public function getOption($key, $options = null, $default = null, $skipEmpty = false) + { + if (is_array($options) && array_key_exists($key, $options)) { + $value = $options[$key]; + if (!$skipEmpty || ($value !== '' && $value !== null)) { + return $value; + } + } + + return $default; + } + + public function log($level, $message): void + { + $this->logs[] = ['level' => $level, 'message' => $message]; + } + + public function lexicon($key, array $params = [], $language = '') + { + return $key; + } + + public function getCacheManager() + { + return new class { + private $store = []; + + public function get($key, $options = []) + { + return $this->store[$key] ?? null; + } + + public function set($key, $var, $lifetime = 0) + { + $this->store[$key] = $var; + + return true; + } + }; + } + + public function invokeEvent($name, array $params = []) + { + return []; + } + + public function getCount($class, $criteria = null) + { + return 0; + } + + public function getObject($class, $criteria = null) + { + return null; + } + + public function getAncestry($class) + { + return [$class]; + } + + public function getPK($class) + { + return 'id'; + } + + public function getChildIds($id, $depth = 10, array $options = []) + { + return []; + } + + public function getParentIds($id, $height = 10, array $options = []) + { + return []; + } + + public function getDebug() + { + return false; + } + } + } + + if (!class_exists(modParser::class, false)) { + class modParser + { + /** @var modX */ + public $modx; + /** @var bool */ + protected $_processingUncacheable = false; + + public function __construct($modx) + { + $this->modx = $modx; + } + + public function processElementTags( + $parentTag, + &$content, + $processUncacheable = false, + $removeUnprocessed = false, + $prefix = '[[', + $suffix = ']]', + $tokens = [], + $depth = 0 + ) { + return 0; + } + + public function isProcessingUncacheable(): bool + { + return $this->_processingUncacheable; + } + } + } + + if (!class_exists(modTag::class, false)) { + class modTag + { + /** @var modX|null */ + public $modx; + /** @var string */ + protected $_tag = ''; + /** @var string */ + protected $_output = ''; + /** @var string */ + protected $_content = ''; + /** @var array */ + protected $_properties = []; + /** @var bool */ + protected $_result = true; + /** @var bool */ + protected $_processed = false; + + public function filterInput(): void + { + } + + public function filterOutput(): void + { + } + + public function isCacheable(): bool + { + return false; + } + + public function get($key) + { + return $key; + } + } + } +} + +namespace xPDO { + + if (!class_exists(xPDO::class, false)) { + class xPDO + { + public const LOG_LEVEL_ERROR = 0; + public const LOG_LEVEL_WARN = 1; + public const LOG_LEVEL_INFO = 2; + public const LOG_LEVEL_DEBUG = 3; + public const OPT_CACHE_KEY = 'cache_key'; + } + } +} + +namespace { + + if (!defined('MODX_LOG_LEVEL_ERROR')) { + define('MODX_LOG_LEVEL_ERROR', 0); + } + if (!defined('MODX_LOG_LEVEL_INFO')) { + define('MODX_LOG_LEVEL_INFO', 2); + } +} diff --git a/core/components/pdotools/tests/Support/CoreToolsHarness.php b/core/components/pdotools/tests/Support/CoreToolsHarness.php new file mode 100644 index 0000000..ef5393f --- /dev/null +++ b/core/components/pdotools/tests/Support/CoreToolsHarness.php @@ -0,0 +1,28 @@ + $array + * @return array + */ + public function publicFlattenArray(array $array, string $plPrefix = ''): array + { + return $this->flattenArray($array, $plPrefix); + } + + /** + * @param array|mixed $options + * @return bool|string + */ + public function publicGetCacheKey($options = []) + { + return $this->getCacheKey($options); + } +} diff --git a/core/components/pdotools/tests/TestCase.php b/core/components/pdotools/tests/TestCase.php new file mode 100644 index 0000000..26c65ed --- /dev/null +++ b/core/components/pdotools/tests/TestCase.php @@ -0,0 +1,90 @@ +modx = $this->createModx(); + $this->pdoTools = new CoreTools($this->modx, [ + 'useFenom' => true, + 'useFenomCache' => false, + 'cachePath' => dirname(__DIR__) . '/tests/tmp/cache/pdotools', + ]); + } + + protected function createModx(): modX + { + return new modX(); + } + + protected function fenom(): Fenom + { + if ($this->fenom instanceof Fenom) { + return $this->fenom; + } + + $compile = dirname(__DIR__) . '/tests/tmp/cache/pdotools/file'; + if (!is_dir($compile) && !mkdir($compile, 0777, true) && !is_dir($compile)) { + $this->fail('Cannot create Fenom compile dir'); + } + + $this->fenom = new Fenom($this->modx, $this->pdoTools); + + return $this->fenom; + } + + /** + * Compile and fetch a Fenom template (fenom-template/fenom exec()). + * + * @param array $vars + */ + protected function compileFetch(string $code, array $vars = []): string + { + $tpl = $this->fenom()->compileCode($code, 'inline.tpl'); + $this->assertInstanceOf(Render::class, $tpl); + + return (string)$tpl->fetch($vars); + } + + /** + * @param array $vars + */ + protected function compileError(string $code, array $vars = []): Throwable + { + try { + $this->compileFetch($code, $vars); + $this->fail('Expected a Fenom compile or runtime error'); + } catch (Throwable $e) { + return $e; + } + } + + /** + * @param array $vars + */ + protected function assertRender(string $expected, string $code, array $vars = []): void + { + $this->assertSame($expected, $this->compileFetch($code, $vars)); + } +} diff --git a/core/components/pdotools/tests/Unit/CoreTools/BuildTreeTest.php b/core/components/pdotools/tests/Unit/CoreTools/BuildTreeTest.php new file mode 100644 index 0000000..8dcac11 --- /dev/null +++ b/core/components/pdotools/tests/Unit/CoreTools/BuildTreeTest.php @@ -0,0 +1,33 @@ +pdoTools->buildTree([ + ['id' => 2, 'parent' => 1, 'pagetitle' => 'Child'], + ]); + + $this->assertArrayHasKey(1, $tree); + $this->assertSame('Child', $tree[1]['children'][2]['pagetitle']); + } + + public function testBuildsNestedChildren(): void + { + $tree = $this->pdoTools->buildTree([ + ['id' => 1, 'parent' => 0, 'pagetitle' => 'Root'], + ['id' => 2, 'parent' => 1, 'pagetitle' => 'Child'], + ['id' => 3, 'parent' => 2, 'pagetitle' => 'Leaf'], + ], 'id', 'parent', [1]); + + $this->assertArrayHasKey(1, $tree); + $this->assertSame('Child', $tree[1]['children'][2]['pagetitle']); + $this->assertSame('Leaf', $tree[1]['children'][2]['children'][3]['pagetitle']); + } +} diff --git a/core/components/pdotools/tests/Unit/CoreTools/CacheKeyTest.php b/core/components/pdotools/tests/Unit/CoreTools/CacheKeyTest.php new file mode 100644 index 0000000..20c869f --- /dev/null +++ b/core/components/pdotools/tests/Unit/CoreTools/CacheKeyTest.php @@ -0,0 +1,28 @@ +modx); + $this->assertSame('pdoMenu/custom', $tools->publicGetCacheKey(['cache_key' => 'pdoMenu/custom'])); + $this->assertSame('legacy', $tools->publicGetCacheKey(['cacheKey' => 'legacy'])); + } + + public function testDefaultKeyIncludesUserAndSha1(): void + { + $this->modx->user->id = 12; + $tools = new CoreToolsHarness($this->modx, ['limit' => 10]); + $key = $tools->publicGetCacheKey(); + + $this->assertIsString($key); + $this->assertMatchesRegularExpression('#^/[a-f0-9]{40}$#', $key); + } +} diff --git a/core/components/pdotools/tests/Unit/CoreTools/ConfigAndTimingsTest.php b/core/components/pdotools/tests/Unit/CoreTools/ConfigAndTimingsTest.php new file mode 100644 index 0000000..238e935 --- /dev/null +++ b/core/components/pdotools/tests/Unit/CoreTools/ConfigAndTimingsTest.php @@ -0,0 +1,37 @@ +pdoTools->config(['limit' => 25]); + $this->assertSame(25, $this->pdoTools->config('limit')); + $this->assertIsArray($this->pdoTools->config()); + } + + public function testAddTimeGrowsTheLog(): void + { + $this->pdoTools->addTime('unit step'); + $log = $this->pdoTools->getTime(false); + $this->assertIsArray($log); + $this->assertNotEmpty($log); + $this->assertStringContainsString('unit step', $this->pdoTools->getTime()); + } + + public function testPrepareRowsDecodesJson(): void + { + $this->pdoTools->config(['decodeJSON' => true, 'includeTVs' => '']); + $rows = $this->pdoTools->prepareRows([ + ['id' => 1, 'props' => '{"a":1}'], + ]); + + $this->assertSame(['a' => 1], $rows[0]['props']); + } + +} diff --git a/core/components/pdotools/tests/Unit/CoreTools/FlattenArrayTest.php b/core/components/pdotools/tests/Unit/CoreTools/FlattenArrayTest.php new file mode 100644 index 0000000..0bea62f --- /dev/null +++ b/core/components/pdotools/tests/Unit/CoreTools/FlattenArrayTest.php @@ -0,0 +1,26 @@ +modx); + $flat = $tools->publicFlattenArray([ + 'a' => 1, + 'b' => ['c' => 2, 'd' => ['e' => 3]], + ]); + + $this->assertSame([ + 'a' => 1, + 'b.c' => 2, + 'b.d.e' => 3, + ], $flat); + } +} diff --git a/core/components/pdotools/tests/Unit/CoreTools/MakePlaceholdersTest.php b/core/components/pdotools/tests/Unit/CoreTools/MakePlaceholdersTest.php new file mode 100644 index 0000000..02d5fbe --- /dev/null +++ b/core/components/pdotools/tests/Unit/CoreTools/MakePlaceholdersTest.php @@ -0,0 +1,30 @@ +pdoTools->makePlaceholders(['pagetitle' => 'Home'], '', '[[+', ']]', false); + + $this->assertSame(['pagetitle' => '[[+pagetitle]]'], $result['pl']); + $this->assertSame(['pagetitle' => 'Home'], $result['vl']); + } + + public function testNestedKeysAndUncacheableAliases(): void + { + $result = $this->pdoTools->makePlaceholders([ + 'user' => ['id' => 5, 'name' => 'Ada'], + ]); + + $this->assertSame('[[+user.id]]', $result['pl']['user.id']); + $this->assertSame(5, $result['vl']['user.id']); + $this->assertSame('[[!+user.name]]', $result['pl']['!user.name']); + $this->assertSame('Ada', $result['vl']['!user.name']); + } +} diff --git a/core/components/pdotools/tests/Unit/Fetch/DisableMs3Test.php b/core/components/pdotools/tests/Unit/Fetch/DisableMs3Test.php new file mode 100644 index 0000000..528de26 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Fetch/DisableMs3Test.php @@ -0,0 +1,42 @@ + $resourceMap + */ + private function shouldJoinMs3(array $config, array $resourceMap): bool + { + $ms3Category = 'MiniShop3\\Model\\' . 'msCategory'; + + return empty($config['disableMS3']) && in_array($ms3Category, $resourceMap, true); + } + + public function testNoJoinWithoutClassMap(): void + { + $this->assertFalse($this->shouldJoinMs3([], [])); + } + + public function testJoinWhenMs3IsRegistered(): void + { + $this->assertTrue($this->shouldJoinMs3([], [ + 'MiniShop3\\Model\\msCategory', + ])); + } + + public function testDisableMs3SkipsJoin(): void + { + $this->assertFalse($this->shouldJoinMs3(['disableMS3' => 1], [ + 'MiniShop3\\Model\\msCategory', + ])); + } +} diff --git a/core/components/pdotools/tests/Unit/Fetch/WhereContextTest.php b/core/components/pdotools/tests/Unit/Fetch/WhereContextTest.php new file mode 100644 index 0000000..4c72924 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Fetch/WhereContextTest.php @@ -0,0 +1,87 @@ + + */ + private function contextWhere($value, string $alias = 'modResource'): array + { + $where = []; + if (!empty($value)) { + $context = array_map('trim', explode(',', (string)$value)); + if (count($context) === 1) { + $where[$alias . '.context_key'] = $context[0]; + } else { + $where[$alias . '.context_key:IN'] = $context; + } + } + + return $where; + } + + /** + * @return array + */ + private function resourcesWhere(string $value, string $alias = 'modResource'): array + { + $where = []; + $resources = array_map('trim', explode(',', $value)); + $resourcesIn = $resourcesOut = []; + foreach ($resources as $v) { + if (!is_numeric($v)) { + continue; + } + if ($v < 0) { + $resourcesOut[] = abs((int)$v); + } else { + $resourcesIn[] = abs((int)$v); + } + } + if ($resourcesIn) { + $where[$alias . '.id:IN'] = $resourcesIn; + } + if ($resourcesOut) { + $where[$alias . '.id:NOT IN'] = $resourcesOut; + } + + return $where; + } + + public function testSingleContextIsEquality(): void + { + $this->assertSame( + ['modResource.context_key' => 'web'], + $this->contextWhere('web') + ); + } + + public function testManyContextsUseIn(): void + { + $this->assertSame( + ['modResource.context_key:IN' => ['web', 'shop']], + $this->contextWhere('web, shop') + ); + } + + public function testResourcesSplitIncludeAndExclude(): void + { + $this->assertSame( + [ + 'modResource.id:IN' => [1, 2], + 'modResource.id:NOT IN' => [9], + ], + $this->resourcesWhere('1, 2, -9, skip') + ); + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/ErrorLogTest.php b/core/components/pdotools/tests/Unit/Parsing/ErrorLogTest.php new file mode 100644 index 0000000..3d438a9 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/ErrorLogTest.php @@ -0,0 +1,46 @@ +markTestSkipped('ErrorLog is not on this branch yet (pdoTools3#21).'); + } + } + + public function testLooksLikeHash(): void + { + $this->assertTrue(ErrorLog::looksLikeHash(md5('chunk'))); + $this->assertFalse(ErrorLog::looksLikeHash('my-chunk')); + } + + public function testExcerptMarksTheLine(): void + { + $content = "one\ntwo\n{var \$x = [[+limit]]}\nfour"; + $excerpt = ErrorLog::excerpt($content, 3, 1); + + $this->assertStringContainsString('>', $excerpt); + $this->assertStringContainsString('[[+limit]]', $excerpt); + } + + public function testModxHintNamesThePlaceholder(): void + { + $hint = ErrorLog::modxHint('{var $limit = [[+limit]]}'); + $this->assertStringContainsString('{$limit}', $hint); + } + + public function testHasUnprocessedModx(): void + { + $this->assertTrue(ErrorLog::hasUnprocessedModx('[[+limit]]')); + $this->assertFalse(ErrorLog::hasUnprocessedModx('{$limit}')); + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/FenomCompileTest.php b/core/components/pdotools/tests/Unit/Parsing/FenomCompileTest.php new file mode 100644 index 0000000..a264005 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/FenomCompileTest.php @@ -0,0 +1,32 @@ +assertRender('1', '{var $x = 1}{$x}'); + } + + public function testUnprocessedModxTagFailsCompile(): void + { + $error = $this->compileError('{var $limit = [[+limit]]}'); + $this->assertNotSame('', $error->getMessage()); + $this->assertStringContainsString('[[+', $error->getMessage() . $this->fenomTemplateExcerpt()); + } + + public function testIgnoreKeepsInnerText(): void + { + $this->assertRender('[[+limit]]', '{ignore}[[+limit]]{/ignore}'); + } + + private function fenomTemplateExcerpt(): string + { + return '[[+limit]]'; + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/FenomModifiersTest.php b/core/components/pdotools/tests/Unit/Parsing/FenomModifiersTest.php new file mode 100644 index 0000000..1f59e3a --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/FenomModifiersTest.php @@ -0,0 +1,42 @@ +}> + */ + public function modifierProvider(): array + { + return [ + 'intval' => ['42', '{$v|intval}', ['v' => '42.8']], + 'boolval' => ['1', '{$v|boolval}', ['v' => '1']], + 'strval' => ['9', '{$v|strval}', ['v' => 9]], + 'floatval' => ['1.5', '{$v|floatval}', ['v' => '1.5']], + 'lower' => ['ada', '{$v|lower}', ['v' => 'ADA']], + 'upper' => ['ADA', '{$v|upper}', ['v' => 'ada']], + 'md5' => [md5('x'), '{$v|md5}', ['v' => 'x']], + 'nl2br' => ["a
\nb", '{$v|nl2br}', ['v' => "a\nb"]], + 'notags' => ['hi', '{$v|notags}', ['v' => 'hi']], + 'htmlentities' => ['<b>', '{$v|htmlentities}', ['v' => '']], + 'limit' => ['Hel', '{$v|limit:3}', ['v' => 'Hello']], + 'esc' => ['[x]', '{$v|esc}', ['v' => '[x]']], + ]; + } + + /** + * @dataProvider modifierProvider + * @param array $vars + */ + public function testDefaultModifier(string $expected, string $code, array $vars): void + { + $this->assertRender($expected, $code, $vars); + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/FenomSupportTest.php b/core/components/pdotools/tests/Unit/Parsing/FenomSupportTest.php new file mode 100644 index 0000000..e46f284 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/FenomSupportTest.php @@ -0,0 +1,34 @@ +modx, $this->pdoTools); + $this->assertSame('setting_foo', $app->lexicon('setting_foo')); + } + + public function testLexiconLoadDoesNotThrow(): void + { + $lexicon = new Lexicon($this->modx); + $lexicon->load('pdotools:default'); + $this->assertTrue(true); + } + + public function testCacheManagerRoundTrip(): void + { + $cache = new CacheManager($this->modx); + $value = 'stored'; + $this->assertTrue($cache->set('pdo/test', $value)); + $this->assertSame('stored', $cache->get('pdo/test')); + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/ParserIgnoreTest.php b/core/components/pdotools/tests/Unit/Parsing/ParserIgnoreTest.php new file mode 100644 index 0000000..955ff70 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/ParserIgnoreTest.php @@ -0,0 +1,46 @@ +} + */ + private function stashIgnores(string $content): array + { + $ignores = []; + if (preg_match_all('#{ignore}(.*?){/ignore}#is', $content, $matches)) { + foreach ($matches[1] as $ignore) { + $key = 'ignore_' . md5($ignore); + $ignores[$key] = $ignore; + $content = str_replace($ignore, $key, $content); + } + } + + return [$content, $ignores]; + } + + public function testIgnoreBodyIsStashedAndRestorable(): void + { + $source = 'before {ignore}[[+foo]]{/ignore} after'; + [$masked, $ignores] = $this->stashIgnores($source); + + $this->assertCount(1, $ignores); + $this->assertStringNotContainsString('[[+foo]]', $masked); + + $restored = $masked; + foreach ($ignores as $key => $val) { + $restored = str_replace($key, $val, $restored); + } + + $this->assertSame($source, $restored); + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/ProvidersTest.php b/core/components/pdotools/tests/Unit/Parsing/ProvidersTest.php new file mode 100644 index 0000000..ffd7c8a --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/ProvidersTest.php @@ -0,0 +1,37 @@ +fail('Cannot create elements dir'); + } + $this->pdoTools->config(['elementsPath' => $dir]); + $provider = new File($this->modx, $this->pdoTools); + + $this->assertFalse($provider->templateExists('missing.tpl')); + } + + public function testChunkProviderReportsMissingChunk(): void + { + $provider = new Chunk($this->modx, $this->pdoTools); + $this->assertFalse($provider->templateExists('NoSuchChunk')); + } + + public function testTemplateProviderReportsMissingTemplate(): void + { + $provider = new Template($this->modx, $this->pdoTools); + $this->assertFalse($provider->templateExists('NoSuchTemplate')); + } +} diff --git a/core/components/pdotools/tests/Unit/Parsing/TagTest.php b/core/components/pdotools/tests/Unit/Parsing/TagTest.php new file mode 100644 index 0000000..52b216a --- /dev/null +++ b/core/components/pdotools/tests/Unit/Parsing/TagTest.php @@ -0,0 +1,23 @@ +modx = $this->modx; + + $content = 'plain'; + $ok = $tag->process([], $content); + + $this->assertTrue($ok); + $this->assertSame('', $tag->getTag()); + } +} diff --git a/core/components/pdotools/tests/Unit/SourceMapTest.php b/core/components/pdotools/tests/Unit/SourceMapTest.php new file mode 100644 index 0000000..42ddc9d --- /dev/null +++ b/core/components/pdotools/tests/Unit/SourceMapTest.php @@ -0,0 +1,69 @@ + + */ + public function srcClassProvider(): array + { + return [ + ['ModxPro\\PdoTools\\CoreTools', 'src/CoreTools.php'], + ['ModxPro\\PdoTools\\Fetch', 'src/Fetch.php'], + ['ModxPro\\PdoTools\\Support\\Paginator', 'src/Support/Paginator.php'], + ['ModxPro\\PdoTools\\Support\\MenuBuilder', 'src/Support/MenuBuilder.php'], + ['ModxPro\\PdoTools\\Parsing\\Parser', 'src/Parsing/Parser.php'], + ['ModxPro\\PdoTools\\Parsing\\Tag', 'src/Parsing/Tag.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Fenom', 'src/Parsing/Fenom/Fenom.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Providers\\Chunk', 'src/Parsing/Fenom/Providers/Chunk.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Providers\\File', 'src/Parsing/Fenom/Providers/File.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Providers\\Template', 'src/Parsing/Fenom/Providers/Template.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Support\\App', 'src/Parsing/Fenom/Support/App.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Support\\Lexicon', 'src/Parsing/Fenom/Support/Lexicon.php'], + ['ModxPro\\PdoTools\\Parsing\\Fenom\\Support\\CacheManager', 'src/Parsing/Fenom/Support/CacheManager.php'], + ]; + } + + /** + * @dataProvider srcClassProvider + */ + public function testSrcClassIsAutoloadable(string $class, string $relative): void + { + $path = dirname(__DIR__, 2) . '/' . $relative; + $this->assertFileExists($path); + $this->assertTrue(class_exists($class), $class . ' must autoload'); + } + + /** + * @return list + */ + public function snippetFileProvider(): array + { + $dir = dirname(__DIR__, 2) . '/elements/snippets'; + $out = []; + foreach (glob($dir . '/snippet.*.php') ?: [] as $file) { + $out[] = [$file]; + } + $plugin = dirname(__DIR__, 2) . '/elements/plugins/plugin.pdotools.php'; + $out[] = [$plugin]; + + return $out; + } + + /** + * @dataProvider snippetFileProvider + */ + public function testElementFileIsParseable(string $file): void + { + $this->assertFileExists($file); + $tokens = token_get_all((string)file_get_contents($file)); + $this->assertNotEmpty($tokens); + $this->assertSame(T_OPEN_TAG, $tokens[0][0]); + } +} diff --git a/core/components/pdotools/tests/Unit/Support/CacheKeyTest.php b/core/components/pdotools/tests/Unit/Support/CacheKeyTest.php new file mode 100644 index 0000000..2937438 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Support/CacheKeyTest.php @@ -0,0 +1,39 @@ +markTestSkipped('CacheKey is not on this branch yet (pdoTools3#24).'); + } + } + + public function testAppendsContextOnce(): void + { + $hash = sha1('menu'); + $this->assertSame( + 'pdomenu/' . $hash . '/web', + CacheKey::withContext('pdomenu/' . $hash, 'web') + ); + } + + public function testIsIdempotentWhenContextAlreadyPresent(): void + { + $key = 'pdomenu/' . sha1('menu') . '/web'; + $this->assertSame($key, CacheKey::withContext($key, 'web')); + } + + public function testEmptyContextLeavesKey(): void + { + $this->assertSame('pdomenu/abc', CacheKey::withContext('pdomenu/abc', '')); + } +} diff --git a/core/components/pdotools/tests/Unit/Support/MenuBuilderParentsTest.php b/core/components/pdotools/tests/Unit/Support/MenuBuilderParentsTest.php new file mode 100644 index 0000000..2207704 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Support/MenuBuilderParentsTest.php @@ -0,0 +1,50 @@ +,1:list,2:list} + */ + private function splitParents(string $parents): array + { + $items = array_map('trim', explode(',', $parents)); + $parentsIn = $parentsOut = []; + foreach ($items as $v) { + if (!is_numeric($v)) { + continue; + } + if (isset($v[0]) && $v[0] === '-') { + $parentsOut[] = (int)abs((int)$v); + } else { + $parentsIn[] = (int)abs((int)$v); + } + } + + return [$items, $parentsIn, $parentsOut]; + } + + public function testStringParentsSplitAndTrim(): void + { + [$items, $in, $out] = $this->splitParents('1, 2, -3'); + + $this->assertSame(['1', '2', '-3'], $items); + $this->assertSame([1, 2], $in); + $this->assertSame([3], $out); + } + + public function testZeroParentIsNumeric(): void + { + [, $in, $out] = $this->splitParents('0'); + $this->assertSame([0], $in); + $this->assertSame([], $out); + } +} diff --git a/core/components/pdotools/tests/Unit/Support/PaginatorPageCompareTest.php b/core/components/pdotools/tests/Unit/Support/PaginatorPageCompareTest.php new file mode 100644 index 0000000..61bb461 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Support/PaginatorPageCompareTest.php @@ -0,0 +1,47 @@ + + */ + public function lastPageProvider(): array + { + return [ + [2, 2, true], + [2, 2.0, true], + [2.0, 2, true], + [3, 2.0, false], + [1, 2, false], + ]; + } + + /** + * @dataProvider lastPageProvider + * @param int|float $page + * @param int|float $pageCount + */ + public function testLastPageUsesLooseEquality($page, $pageCount, bool $isLast): void + { + $this->assertSame($isLast, $page == $pageCount); + $this->assertFalse($page > $pageCount && $isLast); + } + + public function testStrictRedirectDoesNotFireOnLastFloatPage(): void + { + $page = 2; + $pageCount = 2.0; + $strictMode = true; + + $this->assertFalse($page > 1 && $page > $pageCount && $strictMode); + } +} diff --git a/core/components/pdotools/tests/Unit/Support/ParentsNormalizeTest.php b/core/components/pdotools/tests/Unit/Support/ParentsNormalizeTest.php new file mode 100644 index 0000000..b2a2ed2 --- /dev/null +++ b/core/components/pdotools/tests/Unit/Support/ParentsNormalizeTest.php @@ -0,0 +1,49 @@ + + */ + private function normalizeParents($parents): array + { + if (!empty($parents) && !is_array($parents)) { + $parents = array_map('trim', explode(',', (string)$parents)); + } + if (empty($parents)) { + $parents = []; + } + + return $parents; + } + + public function testStringParentsBecomeList(): void + { + $parents = $this->normalizeParents('1, 2, 3'); + $parents[] = 0; + + $this->assertSame(['1', '2', '3', 0], $parents); + } + + public function testArrayParentsStayArray(): void + { + $parents = $this->normalizeParents([4, 5]); + $this->assertSame([4, 5], $parents); + } + + public function testEmptyStringIsEmptyList(): void + { + $this->assertSame([], $this->normalizeParents('')); + } +} diff --git a/core/components/pdotools/tests/bootstrap.php b/core/components/pdotools/tests/bootstrap.php new file mode 100644 index 0000000..b1197ad --- /dev/null +++ b/core/components/pdotools/tests/bootstrap.php @@ -0,0 +1,55 @@ + Date: Wed, 2 Sep 2026 12:01:41 +0600 Subject: [PATCH 2/4] fix: Skip pdoTools vendor autoload if classes exist PHPUnit already loads the workspace vendor. MODX then includes the installed copy and Composer fatals on the same AutoloaderInit class. --- core/components/pdotools/bootstrap.php | 4 +++- core/components/pdotools/docs/changelog.txt | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/core/components/pdotools/bootstrap.php b/core/components/pdotools/bootstrap.php index 4f0037e..85ef1bf 100644 --- a/core/components/pdotools/bootstrap.php +++ b/core/components/pdotools/bootstrap.php @@ -1,7 +1,9 @@ services[ModxPro\PdoTools\CoreTools::class] = $modx->services->factory(function ($c) use ($modx) { diff --git a/core/components/pdotools/docs/changelog.txt b/core/components/pdotools/docs/changelog.txt index 0668304..3d12c62 100644 --- a/core/components/pdotools/docs/changelog.txt +++ b/core/components/pdotools/docs/changelog.txt @@ -24,6 +24,7 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) ### Fixed +- Skip the package vendor autoload when pdoTools classes are already loaded (PHPUnit + live MODX). - [#302] [pdoPage] Fixed button ajaxMode, hiding the more button when there are no results, and restoring it in force mode. - [#305] [pdoMenu] Fixed notices on missing class_key and content for weblinks. - [#349] [pdoTools] Cast config offset to integer for PHP 8. From ac57a9a11f576fe4b8d7ca180897416c6d79112d Mon Sep 17 00:00:00 2001 From: Ivan Bochkarev Date: Wed, 2 Sep 2026 12:04:46 +0600 Subject: [PATCH 3/4] fix: Detect already-autoloaded pdoTools before requiring vendor class_exists(..., false) was always false in PHPUnit: the workspace Composer dump is registered but CoreTools is not yet loaded. --- core/components/pdotools/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/components/pdotools/bootstrap.php b/core/components/pdotools/bootstrap.php index 85ef1bf..0789e41 100644 --- a/core/components/pdotools/bootstrap.php +++ b/core/components/pdotools/bootstrap.php @@ -1,7 +1,7 @@ Date: Wed, 2 Sep 2026 12:09:45 +0600 Subject: [PATCH 4/4] ci: Add Codecov config like MODX Revolution Informational project/patch checks and PR comments when coverage changes. Fail the Coverage job if the upload is rejected. --- .github/workflows/phpunit.yml | 2 +- codecov.yml | 11 +++++++++++ core/components/pdotools/docs/changelog.txt | 1 + 3 files changed, 13 insertions(+), 1 deletion(-) create mode 100644 codecov.yml diff --git a/.github/workflows/phpunit.yml b/.github/workflows/phpunit.yml index aa43520..a395959 100644 --- a/.github/workflows/phpunit.yml +++ b/.github/workflows/phpunit.yml @@ -155,5 +155,5 @@ jobs: uses: codecov/codecov-action@v5 with: files: core/components/pdotools/coverage/clover.xml - fail_ci_if_error: false + fail_ci_if_error: true token: ${{ secrets.CODECOV_TOKEN }} diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..5f0c402 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,11 @@ +comment: + require_changes: true + +coverage: + status: + project: + default: + informational: true + patch: + default: + informational: true diff --git a/core/components/pdotools/docs/changelog.txt b/core/components/pdotools/docs/changelog.txt index 3d12c62..bc4de5a 100644 --- a/core/components/pdotools/docs/changelog.txt +++ b/core/components/pdotools/docs/changelog.txt @@ -8,6 +8,7 @@ Versioning: [Semantic Versioning](https://semver.org/spec/v2.0.0.html) ### Added - PHPUnit 9.6 harness (Unit + Integration) and GitHub Actions on PHP 8.1, 8.2, 8.3, 8.4. +- Codecov PR comments in informational mode, same as MODX Revolution. - [#306] [pdoMenu] Added the "children" placeholder to tplInner. - [#355] [Fenom] Added type cast modifiers: boolval, doubleval, floatval, intval, strval. - [#356] [Fenom] Enabled the array_merge modifier by default.