diff --git a/.gitignore b/.gitignore index b396e534b34..c1723b0345e 100644 --- a/.gitignore +++ b/.gitignore @@ -59,7 +59,8 @@ tests/cli/vendor # Composer /vendor/ -/bin/composer/**/vendor +/bin/composer/**/vendor/ +/lib/vendor/ contributors.md contributors.html diff --git a/bin/build-lib.sh b/bin/build-lib.sh new file mode 100755 index 00000000000..d4e73015af2 --- /dev/null +++ b/bin/build-lib.sh @@ -0,0 +1,34 @@ +#!/bin/sh + +# Output colorized strings +# +# Color codes: +# 0 - black +# 1 - red +# 2 - green +# 3 - yellow +# 4 - blue +# 5 - magenta +# 6 - cian +# 7 - white +output() { + echo "$(tput setaf "$1")$2$(tput sgr0)" +} + +if [ -z "$(php -r "echo version_compare(PHP_VERSION,'7.2','>=');")" ]; then + output 1 "PHP 7.2 or newer is required to run Mozart, the current PHP version is $(php -r 'echo PHP_VERSION;')" + exit 1 +fi + +output 6 "Building lib package" + +# Clean the output directories to remove any files not present anymore +rm -rf lib/packages lib/classes +mkdir lib/packages lib/classes + +# Running update on the lib package will automatically run Mozart +composer update -d ./lib + +output 6 "Updating autoload files" + +composer dump-autoload diff --git a/bin/composer/mozart/composer.json b/bin/composer/mozart/composer.json new file mode 100644 index 00000000000..bc84e4ad217 --- /dev/null +++ b/bin/composer/mozart/composer.json @@ -0,0 +1,10 @@ +{ + "require-dev": { + "coenjacobs/mozart": "dev-master" + }, + "config": { + "platform": { + "php": "7.2" + } + } +} diff --git a/bin/composer/mozart/composer.lock b/bin/composer/mozart/composer.lock new file mode 100644 index 00000000000..beb86eb0013 --- /dev/null +++ b/bin/composer/mozart/composer.lock @@ -0,0 +1,699 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "cbcce1648bdb890ae805e1afb7396e3c", + "packages": [], + "packages-dev": [ + { + "name": "coenjacobs/mozart", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/coenjacobs/mozart.git", + "reference": "b063c0b3c9923fc763e89376e3d671ce450a839a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/coenjacobs/mozart/zipball/b063c0b3c9923fc763e89376e3d671ce450a839a", + "reference": "b063c0b3c9923fc763e89376e3d671ce450a839a", + "shasum": "" + }, + "require": { + "league/flysystem": "^1.0", + "php": "^7.2", + "symfony/console": "^4|^5", + "symfony/finder": "^4|^5" + }, + "require-dev": { + "mheap/phpunit-github-actions-printer": "^1.4", + "phpunit/phpunit": "^8.5", + "squizlabs/php_codesniffer": "^3.5" + }, + "bin": [ + "bin/mozart" + ], + "type": "library", + "autoload": { + "psr-4": { + "CoenJacobs\\Mozart\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Coen Jacobs", + "email": "coenjacobs@gmail.com" + } + ], + "description": "Composes all dependencies as a package inside a WordPress plugin", + "support": { + "issues": "https://github.com/coenjacobs/mozart/issues", + "source": "https://github.com/coenjacobs/mozart/tree/master" + }, + "funding": [ + { + "url": "https://github.com/coenjacobs", + "type": "github" + } + ], + "time": "2020-11-16T21:14:14+00:00" + }, + { + "name": "league/flysystem", + "version": "1.0.70", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/flysystem.git", + "reference": "585824702f534f8d3cf7fab7225e8466cc4b7493" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/585824702f534f8d3cf7fab7225e8466cc4b7493", + "reference": "585824702f534f8d3cf7fab7225e8466cc4b7493", + "shasum": "" + }, + "require": { + "ext-fileinfo": "*", + "php": ">=5.5.9" + }, + "conflict": { + "league/flysystem-sftp": "<1.0.6" + }, + "require-dev": { + "phpspec/phpspec": "^3.4 || ^4.0 || ^5.0 || ^6.0", + "phpunit/phpunit": "^5.7.26" + }, + "suggest": { + "ext-fileinfo": "Required for MimeType", + "ext-ftp": "Allows you to use FTP server storage", + "ext-openssl": "Allows you to use FTPS server storage", + "league/flysystem-aws-s3-v2": "Allows you to use S3 storage with AWS SDK v2", + "league/flysystem-aws-s3-v3": "Allows you to use S3 storage with AWS SDK v3", + "league/flysystem-azure": "Allows you to use Windows Azure Blob storage", + "league/flysystem-cached-adapter": "Flysystem adapter decorator for metadata caching", + "league/flysystem-eventable-filesystem": "Allows you to use EventableFilesystem", + "league/flysystem-rackspace": "Allows you to use Rackspace Cloud Files", + "league/flysystem-sftp": "Allows you to use SFTP server storage via phpseclib", + "league/flysystem-webdav": "Allows you to use WebDAV storage", + "league/flysystem-ziparchive": "Allows you to use ZipArchive adapter", + "spatie/flysystem-dropbox": "Allows you to use Dropbox storage", + "srmklive/flysystem-dropbox-v2": "Allows you to use Dropbox storage for PHP 5 applications" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Flysystem\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Frank de Jonge", + "email": "info@frenky.net" + } + ], + "description": "Filesystem abstraction: Many filesystems, one API.", + "keywords": [ + "Cloud Files", + "WebDAV", + "abstraction", + "aws", + "cloud", + "copy.com", + "dropbox", + "file systems", + "files", + "filesystem", + "filesystems", + "ftp", + "rackspace", + "remote", + "s3", + "sftp", + "storage" + ], + "support": { + "issues": "https://github.com/thephpleague/flysystem/issues", + "source": "https://github.com/thephpleague/flysystem/tree/1.0.70" + }, + "funding": [ + { + "url": "https://offset.earth/frankdejonge", + "type": "other" + } + ], + "time": "2020-07-26T07:20:36+00:00" + }, + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://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/master" + }, + "time": "2017-02-14T16:28:37+00:00" + }, + { + "name": "symfony/console", + "version": "v4.4.16", + "source": { + "type": "git", + "url": "https://github.com/symfony/console.git", + "reference": "20f73dd143a5815d475e0838ff867bce1eebd9d5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/console/zipball/20f73dd143a5815d475e0838ff867bce1eebd9d5", + "reference": "20f73dd143a5815d475e0838ff867bce1eebd9d5", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "symfony/polyfill-mbstring": "~1.0", + "symfony/polyfill-php73": "^1.8", + "symfony/polyfill-php80": "^1.15", + "symfony/service-contracts": "^1.1|^2" + }, + "conflict": { + "symfony/dependency-injection": "<3.4", + "symfony/event-dispatcher": "<4.3|>=5", + "symfony/lock": "<4.4", + "symfony/process": "<3.3" + }, + "provide": { + "psr/log-implementation": "1.0" + }, + "require-dev": { + "psr/log": "~1.0", + "symfony/config": "^3.4|^4.0|^5.0", + "symfony/dependency-injection": "^3.4|^4.0|^5.0", + "symfony/event-dispatcher": "^4.3", + "symfony/lock": "^4.4|^5.0", + "symfony/process": "^3.4|^4.0|^5.0", + "symfony/var-dumper": "^4.3|^5.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": "Symfony Console Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/console/tree/v4.4.16" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T11:50:19+00:00" + }, + { + "name": "symfony/finder", + "version": "v4.4.16", + "source": { + "type": "git", + "url": "https://github.com/symfony/finder.git", + "reference": "26f63b8d4e92f2eecd90f6791a563ebb001abe31" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/finder/zipball/26f63b8d4e92f2eecd90f6791a563ebb001abe31", + "reference": "26f63b8d4e92f2eecd90f6791a563ebb001abe31", + "shasum": "" + }, + "require": { + "php": ">=7.1.3" + }, + "type": "library", + "autoload": { + "psr-4": { + "Symfony\\Component\\Finder\\": "" + }, + "exclude-from-classmap": [ + "/Tests/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Fabien Potencier", + "email": "fabien@symfony.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony Finder Component", + "homepage": "https://symfony.com", + "support": { + "source": "https://github.com/symfony/finder/tree/v4.4.16" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-24T11:50:19+00:00" + }, + { + "name": "symfony/polyfill-mbstring", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-mbstring.git", + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/39d483bdf39be819deabf04ec872eb0b2410b531", + "reference": "39d483bdf39be819deabf04ec872eb0b2410b531", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "suggest": { + "ext-mbstring": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Mbstring\\": "" + }, + "files": [ + "bootstrap.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": "Symfony polyfill for the Mbstring extension", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "mbstring", + "polyfill", + "portable", + "shim" + ], + "support": { + "source": "https://github.com/symfony/polyfill-mbstring/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-php73", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php73.git", + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php73/zipball/8ff431c517be11c78c48a39a66d37431e26a6bed", + "reference": "8ff431c517be11c78c48a39a66d37431e26a6bed", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php73\\": "" + }, + "files": [ + "bootstrap.php" + ], + "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 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/polyfill-php73/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/polyfill-php80", + "version": "v1.20.0", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-php80.git", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-php80/zipball/e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "reference": "e70aa8b064c5b72d3df2abd5ab1e90464ad009de", + "shasum": "" + }, + "require": { + "php": ">=7.1" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.20-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Php80\\": "" + }, + "files": [ + "bootstrap.php" + ], + "classmap": [ + "Resources/stubs" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ion Bazan", + "email": "ion.bazan@gmail.com" + }, + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "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/polyfill-php80/tree/v1.20.0" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-10-23T14:02:19+00:00" + }, + { + "name": "symfony/service-contracts", + "version": "v1.1.9", + "source": { + "type": "git", + "url": "https://github.com/symfony/service-contracts.git", + "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/service-contracts/zipball/b776d18b303a39f56c63747bcb977ad4b27aca26", + "reference": "b776d18b303a39f56c63747bcb977ad4b27aca26", + "shasum": "" + }, + "require": { + "php": ">=7.1.3", + "psr/container": "^1.0" + }, + "suggest": { + "symfony/service-implementation": "" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + }, + "thanks": { + "name": "symfony/contracts", + "url": "https://github.com/symfony/contracts" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Contracts\\Service\\": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Nicolas Grekas", + "email": "p@tchwork.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Generic abstractions related to writing services", + "homepage": "https://symfony.com", + "keywords": [ + "abstractions", + "contracts", + "decoupling", + "interfaces", + "interoperability", + "standards" + ], + "support": { + "source": "https://github.com/symfony/service-contracts/tree/v1.1.9" + }, + "funding": [ + { + "url": "https://symfony.com/sponsor", + "type": "custom" + }, + { + "url": "https://github.com/fabpot", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/symfony/symfony", + "type": "tidelift" + } + ], + "time": "2020-07-06T13:19:58+00:00" + } + ], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": { + "coenjacobs/mozart": 20 + }, + "prefer-stable": false, + "prefer-lowest": false, + "platform": [], + "platform-dev": [], + "platform-overrides": { + "php": "7.2" + }, + "plugin-api-version": "1.1.0" +} diff --git a/bin/composer/phpcs/composer.lock b/bin/composer/phpcs/composer.lock index 363928fcb9a..9eee228d3be 100644 --- a/bin/composer/phpcs/composer.lock +++ b/bin/composer/phpcs/composer.lock @@ -71,10 +71,6 @@ "stylecheck", "tests" ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, "time": "2020-06-25T14:57:39+00:00" }, { @@ -133,10 +129,6 @@ "phpcs", "standards" ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibility" - }, "time": "2019-12-27T09:44:58+00:00" }, { @@ -189,10 +181,6 @@ "polyfill", "standards" ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" - }, "time": "2019-11-04T15:17:54+00:00" }, { @@ -243,10 +231,6 @@ "standards", "wordpress" ], - "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" - }, "time": "2019-08-28T14:22:28+00:00" }, { @@ -298,11 +282,6 @@ "phpcs", "standards" ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, "time": "2020-10-23T02:01:07+00:00" }, { @@ -343,10 +322,6 @@ "woocommerce", "wordpress" ], - "support": { - "issues": "https://github.com/woocommerce/woocommerce-sniffs/issues", - "source": "https://github.com/woocommerce/woocommerce-sniffs/tree/master" - }, "time": "2020-08-06T18:23:45+00:00" }, { @@ -393,11 +368,6 @@ "standards", "wordpress" ], - "support": { - "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", - "source": "https://github.com/WordPress/WordPress-Coding-Standards", - "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" - }, "time": "2020-05-13T23:57:56+00:00" } ], @@ -411,5 +381,5 @@ "platform-overrides": { "php": "7.0" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "1.1.0" } diff --git a/bin/composer/phpunit/composer.lock b/bin/composer/phpunit/composer.lock index 3d4ddb93b9f..c39e74f0ed9 100644 --- a/bin/composer/phpunit/composer.lock +++ b/bin/composer/phpunit/composer.lock @@ -332,10 +332,6 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/release/4.x" - }, "time": "2019-12-28T18:55:12+00:00" }, { @@ -448,10 +444,6 @@ "spy", "stub" ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.10.3" - }, "time": "2020-03-05T15:02:03+00:00" }, { @@ -612,10 +604,6 @@ "keywords": [ "template" ], - "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" - }, "time": "2015-06-21T13:50:34+00:00" }, { @@ -920,10 +908,6 @@ ], "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/master" - }, "time": "2017-03-04T06:30:41+00:00" }, { @@ -1169,10 +1153,6 @@ "export", "exporter" ], - "support": { - "issues": "https://github.com/sebastianbergmann/exporter/issues", - "source": "https://github.com/sebastianbergmann/exporter/tree/master" - }, "time": "2019-09-14T09:02:43+00:00" }, { @@ -1224,10 +1204,6 @@ "keywords": [ "global state" ], - "support": { - "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/2.0.0" - }, "time": "2017-04-27T15:39:26+00:00" }, { @@ -1275,10 +1251,6 @@ ], "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/master" - }, "time": "2017-08-03T12:35:26+00:00" }, { @@ -1324,10 +1296,6 @@ ], "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/master" - }, "time": "2017-03-29T09:07:27+00:00" }, { @@ -1381,10 +1349,6 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/master" - }, "time": "2017-03-03T06:23:57+00:00" }, { @@ -1474,10 +1438,6 @@ ], "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/master" - }, "time": "2016-10-03T07:35:21+00:00" }, { @@ -1597,10 +1557,6 @@ } ], "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/master" - }, "time": "2019-06-13T22:48:21+00:00" }, { @@ -1650,10 +1606,6 @@ "check", "validate" ], - "support": { - "issues": "https://github.com/webmozart/assert/issues", - "source": "https://github.com/webmozart/assert/tree/master" - }, "time": "2020-07-08T17:02:28+00:00" } ], @@ -1667,5 +1619,5 @@ "platform-overrides": { "php": "7.0" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "1.1.0" } diff --git a/bin/composer/wp/composer.lock b/bin/composer/wp/composer.lock index 9d610856bc0..e081be14315 100644 --- a/bin/composer/wp/composer.lock +++ b/bin/composer/wp/composer.lock @@ -9,16 +9,16 @@ "packages-dev": [ { "name": "gettext/gettext", - "version": "v4.8.2", + "version": "v4.8.3", "source": { "type": "git", "url": "https://github.com/php-gettext/Gettext.git", - "reference": "e474f872f2c8636cf53fd283ec4ce1218f3d236a" + "reference": "57ff4fb16647e78e80a5909fe3c190f1c3110321" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/e474f872f2c8636cf53fd283ec4ce1218f3d236a", - "reference": "e474f872f2c8636cf53fd283ec4ce1218f3d236a", + "url": "https://api.github.com/repos/php-gettext/Gettext/zipball/57ff4fb16647e78e80a5909fe3c190f1c3110321", + "reference": "57ff4fb16647e78e80a5909fe3c190f1c3110321", "shasum": "" }, "require": { @@ -70,9 +70,9 @@ "support": { "email": "oom@oscarotero.com", "issues": "https://github.com/oscarotero/Gettext/issues", - "source": "https://github.com/php-gettext/Gettext/tree/v4.8.2" + "source": "https://github.com/php-gettext/Gettext/tree/v4.8.3" }, - "time": "2019-12-02T10:21:14+00:00" + "time": "2020-11-18T22:35:49+00:00" }, { "name": "gettext/languages", @@ -133,10 +133,6 @@ "translations", "unicode" ], - "support": { - "issues": "https://github.com/php-gettext/Languages/issues", - "source": "https://github.com/php-gettext/Languages/tree/2.6.0" - }, "time": "2019-11-13T10:30:21+00:00" }, { @@ -182,10 +178,6 @@ } ], "description": "Peast is PHP library that generates AST for JavaScript code", - "support": { - "issues": "https://github.com/mck89/peast/issues", - "source": "https://github.com/mck89/peast/tree/v1.11.0" - }, "time": "2020-10-09T15:12:13+00:00" }, { @@ -232,10 +224,6 @@ "mustache", "templating" ], - "support": { - "issues": "https://github.com/bobthecow/mustache.php/issues", - "source": "https://github.com/bobthecow/mustache.php/tree/master" - }, "time": "2019-11-23T21:40:31+00:00" }, { @@ -285,10 +273,6 @@ "iri", "sockets" ], - "support": { - "issues": "https://github.com/rmccue/Requests/issues", - "source": "https://github.com/rmccue/Requests/tree/master" - }, "time": "2016-10-13T00:11:37+00:00" }, { @@ -398,10 +382,6 @@ ], "description": "Provides internationalization tools for WordPress projects.", "homepage": "https://github.com/wp-cli/i18n-command", - "support": { - "issues": "https://github.com/wp-cli/i18n-command/issues", - "source": "https://github.com/wp-cli/i18n-command/tree/master" - }, "time": "2020-07-08T15:20:38+00:00" }, { @@ -450,9 +430,6 @@ ], "description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)", "homepage": "https://github.com/mustangostang/spyc/", - "support": { - "source": "https://github.com/wp-cli/spyc/tree/autoload" - }, "time": "2017-04-25T11:26:20+00:00" }, { @@ -503,10 +480,6 @@ "cli", "console" ], - "support": { - "issues": "https://github.com/wp-cli/php-cli-tools/issues", - "source": "https://github.com/wp-cli/php-cli-tools/tree/master" - }, "time": "2018-09-04T13:28:00+00:00" }, { @@ -569,11 +542,6 @@ "cli", "wordpress" ], - "support": { - "docs": "https://make.wordpress.org/cli/handbook/", - "issues": "https://github.com/wp-cli/wp-cli/issues", - "source": "https://github.com/wp-cli/wp-cli" - }, "time": "2020-02-18T08:15:37+00:00" } ], @@ -587,5 +555,5 @@ "platform-overrides": { "php": "7.0" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "1.1.0" } diff --git a/bin/prefix-vendor-namespaces.sh b/bin/prefix-vendor-namespaces.sh deleted file mode 100755 index 393b6974c8d..00000000000 --- a/bin/prefix-vendor-namespaces.sh +++ /dev/null @@ -1,29 +0,0 @@ -#!/bin/sh - -# Output colorized strings -# -# Color codes: -# 0 - black -# 1 - red -# 2 - green -# 3 - yellow -# 4 - blue -# 5 - magenta -# 6 - cian -# 7 - white -output() { - echo "$(tput setaf "$1")$2$(tput sgr0)" -} - -output 6 "Prefixing the appropriate vendor namespaces with Automattic\WooCommerce\Vendor" - -# Replace "League\Container" in "use" and "namespace" with "Automattic\WooCommerce\Vendor\League\Container". -REGEX='s/^[[:space:]]*(use|namespace)[[:space:]]*(League\\Container)/\1 Automattic\\WooCommerce\\Vendor\\\2/g' - -find ./vendor/league/container -iname '*.php' -exec sed -i'.bak' -E -e "$REGEX" {} \; -find ./vendor/league/container -name "*.php.bak" -type f -delete - -# Replace too in the composer.json file for the package. -sed -i'.bak' -E -e "s/\"(League\\\\\\\Container)/\"Automattic\\\\\\\WooCommerce\\\\\\\Vendor\\\\\\\\\1/g" vendor/league/container/composer.json -rm -f vendor/league/container/composer.json.bak - diff --git a/composer.json b/composer.json index dab242a8822..d2375ddd79f 100644 --- a/composer.json +++ b/composer.json @@ -6,6 +6,12 @@ "license": "GPL-3.0-or-later", "prefer-stable": true, "minimum-stability": "dev", + "repositories": [ + { + "type": "path", + "url": "lib" + } + ], "require": { "php": ">=7.0", "automattic/jetpack-autoloader": "2.2.0", @@ -16,8 +22,7 @@ "psr/container": "1.0.0", "woocommerce/action-scheduler": "3.1.6", "woocommerce/woocommerce-admin": "1.7.0", - "woocommerce/woocommerce-blocks": "3.8.0", - "league/container": "3.3.3" + "woocommerce/woocommerce-blocks": "3.8.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.4" @@ -43,7 +48,10 @@ ], "psr-4": { "Automattic\\WooCommerce\\": "src/", - "Automattic\\WooCommerce\\Vendor\\League\\Container\\": "vendor/league/container/" + "Automattic\\WooCommerce\\Vendor\\": "lib/packages/" + }, + "psr-0": { + "Automattic\\WooCommerce\\Vendor\\": "lib/packages/" } }, "autoload-dev": { @@ -58,12 +66,10 @@ "scripts": { "post-install-cmd": [ "@composer bin all install --ansi", - "sh ./bin/prefix-vendor-namespaces.sh", "sh ./bin/package-update.sh" ], "post-update-cmd": [ "@composer bin all update --ansi", - "sh ./bin/prefix-vendor-namespaces.sh", "sh ./bin/package-update.sh" ], "test": [ @@ -86,6 +92,9 @@ ], "bin": [ "echo 'bin not installed'" + ], + "build-lib": [ + "sh ./bin/build-lib.sh" ] }, "extra": { diff --git a/composer.lock b/composer.lock index b78f6116b82..2440ade2902 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6494b4d4b956386e32381541ebd79839", + "content-hash": "ddeda3843bbb8fd35abf1cea951c47df", "packages": [ { "name": "automattic/jetpack-autoloader", @@ -220,82 +220,6 @@ ], "time": "2020-04-07T06:57:05+00:00" }, - { - "name": "league/container", - "version": "3.3.3", - "source": { - "type": "git", - "url": "https://github.com/thephpleague/container.git", - "reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/thephpleague/container/zipball/7dc67bdf89efc338e674863c0ea70a63efe4de05", - "reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05", - "shasum": "" - }, - "require": { - "php": "^7.0 || ^8.0", - "psr/container": "^1.0" - }, - "provide": { - "psr/container-implementation": "^1.0" - }, - "replace": { - "orno/di": "~2.0" - }, - "require-dev": { - "phpunit/phpunit": "^6.0", - "squizlabs/php_codesniffer": "^3.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-3.x": "3.x-dev", - "dev-2.x": "2.x-dev", - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "League\\Container\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Phil Bennett", - "email": "philipobenito@gmail.com", - "homepage": "http://www.philipobenito.com", - "role": "Developer" - } - ], - "description": "A fast and intuitive dependency injection container.", - "homepage": "https://github.com/thephpleague/container", - "keywords": [ - "container", - "dependency", - "di", - "injection", - "league", - "provider", - "service" - ], - "support": { - "issues": "https://github.com/thephpleague/container/issues", - "source": "https://github.com/thephpleague/container/tree/3.3.3" - }, - "funding": [ - { - "url": "https://github.com/philipobenito", - "type": "github" - } - ], - "time": "2020-09-28T13:38:44+00:00" - }, { "name": "maxmind-db/reader", "version": "v1.6.0", @@ -751,5 +675,5 @@ "platform-overrides": { "php": "7.0" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "1.1.0" } diff --git a/lib/README.md b/lib/README.md new file mode 100644 index 00000000000..7119d5574bd --- /dev/null +++ b/lib/README.md @@ -0,0 +1,31 @@ +## WooCommerce Lib Directory + +This directory contains a dummy package responsible for managing WooCommerce dependencies that require conflict avoidance. +The contents of the `packages` and `classes` directories get automatically generated by `composer install` and `composer update`. + +This allows us to prefix namespaces and classmap classes to avoid conflicts with plugins that include the same package. +All namespaces are prefixed with `Automattic\WooCommerce\Vendor` and classmap classes prefixed with `WC_Vendor_`. + +**_Do not_ make direct changes in the files contained in `packages` or `classes`! Any changes will be lost!** + +### Adding Packages + +In order to avoid including the original dependencies in the root autoloader we must utilize `require-dev` for them. +Composer treats `require` dependencies as transitive while `require-dev` dependencies get ignored by consumers. + +1. Add package to `require-dev` section of `composer.json` +2. Add package slug to `extra/mozart/packages` section of `composer.json` +3. Run `composer run-script build-lib` from the root directory (You should now see the package in `packages/VendorName/PackageName` or `classes`) + +### Updating Packages + +Updating a package is as easy as changing the version in `composer.json` and then running `composer run-script build-lib` from the root directory. + +### Ignoring Packages + +If you would like to add a package which does not undergo conflict avoidance you must take steps to ensure it appears in +the root autoloader. + +1. Add package to the `require` section of both the `lib/composer.json` and root `composer.json` file instead of `require-dev` +2. Add package slug to `extra/mozart/excluded-packages` section of `composer.json` +3. Run `composer run-script build-lib` from the root directory (You **should not** see the package in `packages/VendorName/PackageName` or `classes`) diff --git a/lib/composer.json b/lib/composer.json new file mode 100644 index 00000000000..7e9e4481f95 --- /dev/null +++ b/lib/composer.json @@ -0,0 +1,41 @@ +{ + "name": "woocommerce/woocommerce-lib", + "description": "A package for hiding re-namespaced dependencies and executing them", + "prefer-stable": true, + "minimum-stability": "dev", + "require": { + "php": ">=7.0", + "psr/container": "^1.0" + }, + "require-dev": { + "league/container": "3.3.3" + }, + "config": { + "platform": { + "php": "7.0" + } + }, + "scripts": { + "post-install-cmd": [ + "\"../vendor/bin/mozart\" compose" + ], + "post-update-cmd": [ + "\"../vendor/bin/mozart\" compose" + ] + }, + "extra": { + "mozart": { + "dep_namespace": "Automattic\\WooCommerce\\Vendor\\", + "dep_directory": "/packages/", + "packages": [ + "league/container" + ], + "excluded_packages": [ + "psr/container" + ], + "classmap_directory": "/classes/", + "classmap_prefix": "WC_Vendor_", + "delete_vendor_directories": true + } + } +} diff --git a/lib/composer.lock b/lib/composer.lock new file mode 100644 index 00000000000..ac31c819004 --- /dev/null +++ b/lib/composer.lock @@ -0,0 +1,146 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", + "This file is @generated automatically" + ], + "content-hash": "df548645b5c00d585705cd10c6ffd3f7", + "packages": [ + { + "name": "psr/container", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/php-fig/container.git", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Psr\\Container\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "PHP-FIG", + "homepage": "http://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" + ], + "time": "2017-02-14T16:28:37+00:00" + } + ], + "packages-dev": [ + { + "name": "league/container", + "version": "3.3.3", + "source": { + "type": "git", + "url": "https://github.com/thephpleague/container.git", + "reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/thephpleague/container/zipball/7dc67bdf89efc338e674863c0ea70a63efe4de05", + "reference": "7dc67bdf89efc338e674863c0ea70a63efe4de05", + "shasum": "" + }, + "require": { + "php": "^7.0 || ^8.0", + "psr/container": "^1.0" + }, + "provide": { + "psr/container-implementation": "^1.0" + }, + "replace": { + "orno/di": "~2.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0", + "squizlabs/php_codesniffer": "^3.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-3.x": "3.x-dev", + "dev-2.x": "2.x-dev", + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "League\\Container\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Phil Bennett", + "email": "philipobenito@gmail.com", + "homepage": "http://www.philipobenito.com", + "role": "Developer" + } + ], + "description": "A fast and intuitive dependency injection container.", + "homepage": "https://github.com/thephpleague/container", + "keywords": [ + "container", + "dependency", + "di", + "injection", + "league", + "provider", + "service" + ], + "funding": [ + { + "url": "https://github.com/philipobenito", + "type": "github" + } + ], + "time": "2020-09-28T13:38:44+00:00" + } + ], + "aliases": [], + "minimum-stability": "dev", + "stability-flags": [], + "prefer-stable": true, + "prefer-lowest": false, + "platform": { + "php": ">=7.0" + }, + "platform-dev": [], + "platform-overrides": { + "php": "7.0" + }, + "plugin-api-version": "1.1.0" +} diff --git a/lib/packages/League/Container/Argument/ArgumentResolverInterface.php b/lib/packages/League/Container/Argument/ArgumentResolverInterface.php new file mode 100644 index 00000000000..9c7393f6578 --- /dev/null +++ b/lib/packages/League/Container/Argument/ArgumentResolverInterface.php @@ -0,0 +1,28 @@ +getValue(); + } elseif ($argument instanceof ClassNameInterface) { + $id = $argument->getClassName(); + } elseif (!is_string($argument)) { + return $argument; + } else { + $justStringValue = true; + $id = $argument; + } + + $container = null; + + try { + $container = $this->getLeagueContainer(); + } catch (ContainerException $e) { + if ($this instanceof ReflectionContainer) { + $container = $this; + } + } + + if ($container !== null) { + try { + return $container->get($id); + } catch (NotFoundException $exception) { + if ($argument instanceof ClassNameWithOptionalValue) { + return $argument->getOptionalValue(); + } + + if ($justStringValue) { + return $id; + } + + throw $exception; + } + } + + if ($argument instanceof ClassNameWithOptionalValue) { + return $argument->getOptionalValue(); + } + + // Just a string value. + return $id; + }, $arguments); + } + + /** + * {@inheritdoc} + */ + public function reflectArguments(ReflectionFunctionAbstract $method, array $args = []) : array + { + $arguments = array_map(function (ReflectionParameter $param) use ($method, $args) { + $name = $param->getName(); + $type = $param->getType(); + + if (array_key_exists($name, $args)) { + return new RawArgument($args[$name]); + } + + if ($type) { + if (PHP_VERSION_ID >= 70200) { + $typeName = $type->getName(); + } else { + $typeName = (string) $type; + } + + $typeName = ltrim($typeName, '?'); + + if ($param->isDefaultValueAvailable()) { + return new ClassNameWithOptionalValue($typeName, $param->getDefaultValue()); + } + + return new ClassName($typeName); + } + + if ($param->isDefaultValueAvailable()) { + return new RawArgument($param->getDefaultValue()); + } + + throw new NotFoundException(sprintf( + 'Unable to resolve a value for parameter (%s) in the function/method (%s)', + $name, + $method->getName() + )); + }, $method->getParameters()); + + return $this->resolveArguments($arguments); + } + + /** + * @return ContainerInterface + */ + abstract public function getContainer() : ContainerInterface; + + /** + * @return Container + */ + abstract public function getLeagueContainer() : Container; +} diff --git a/lib/packages/League/Container/Argument/ClassName.php b/lib/packages/League/Container/Argument/ClassName.php new file mode 100644 index 00000000000..bab358fce36 --- /dev/null +++ b/lib/packages/League/Container/Argument/ClassName.php @@ -0,0 +1,29 @@ +value = $value; + } + + /** + * {@inheritdoc} + */ + public function getClassName() : string + { + return $this->value; + } +} diff --git a/lib/packages/League/Container/Argument/ClassNameInterface.php b/lib/packages/League/Container/Argument/ClassNameInterface.php new file mode 100644 index 00000000000..ab2708eaeee --- /dev/null +++ b/lib/packages/League/Container/Argument/ClassNameInterface.php @@ -0,0 +1,13 @@ +className = $className; + $this->optionalValue = $optionalValue; + } + + /** + * @inheritDoc + */ + public function getClassName(): string + { + return $this->className; + } + + public function getOptionalValue() + { + return $this->optionalValue; + } +} diff --git a/lib/packages/League/Container/Argument/RawArgument.php b/lib/packages/League/Container/Argument/RawArgument.php new file mode 100644 index 00000000000..fe0ddd06d18 --- /dev/null +++ b/lib/packages/League/Container/Argument/RawArgument.php @@ -0,0 +1,29 @@ +value = $value; + } + + /** + * {@inheritdoc} + */ + public function getValue() + { + return $this->value; + } +} diff --git a/lib/packages/League/Container/Argument/RawArgumentInterface.php b/lib/packages/League/Container/Argument/RawArgumentInterface.php new file mode 100644 index 00000000000..8730cac8590 --- /dev/null +++ b/lib/packages/League/Container/Argument/RawArgumentInterface.php @@ -0,0 +1,13 @@ +definitions = $definitions ?? new DefinitionAggregate; + $this->providers = $providers ?? new ServiceProviderAggregate; + $this->inflectors = $inflectors ?? new InflectorAggregate; + + if ($this->definitions instanceof ContainerAwareInterface) { + $this->definitions->setLeagueContainer($this); + } + + if ($this->providers instanceof ContainerAwareInterface) { + $this->providers->setLeagueContainer($this); + } + + if ($this->inflectors instanceof ContainerAwareInterface) { + $this->inflectors->setLeagueContainer($this); + } + } + + /** + * Add an item to the container. + * + * @param string $id + * @param mixed $concrete + * @param boolean $shared + * + * @return DefinitionInterface + */ + public function add(string $id, $concrete = null, bool $shared = null) : DefinitionInterface + { + $concrete = $concrete ?? $id; + $shared = $shared ?? $this->defaultToShared; + + return $this->definitions->add($id, $concrete, $shared); + } + + /** + * Proxy to add with shared as true. + * + * @param string $id + * @param mixed $concrete + * + * @return DefinitionInterface + */ + public function share(string $id, $concrete = null) : DefinitionInterface + { + return $this->add($id, $concrete, true); + } + + /** + * Whether the container should default to defining shared definitions. + * + * @param boolean $shared + * + * @return self + */ + public function defaultToShared(bool $shared = true) : ContainerInterface + { + $this->defaultToShared = $shared; + + return $this; + } + + /** + * Get a definition to extend. + * + * @param string $id [description] + * + * @return DefinitionInterface + */ + public function extend(string $id) : DefinitionInterface + { + if ($this->providers->provides($id)) { + $this->providers->register($id); + } + + if ($this->definitions->has($id)) { + return $this->definitions->getDefinition($id); + } + + throw new NotFoundException( + sprintf('Unable to extend alias (%s) as it is not being managed as a definition', $id) + ); + } + + /** + * Add a service provider. + * + * @param ServiceProviderInterface|string $provider + * + * @return self + */ + public function addServiceProvider($provider) : self + { + $this->providers->add($provider); + + return $this; + } + + /** + * {@inheritdoc} + */ + public function get($id, bool $new = false) + { + if ($this->definitions->has($id)) { + $resolved = $this->definitions->resolve($id, $new); + return $this->inflectors->inflect($resolved); + } + + if ($this->definitions->hasTag($id)) { + $arrayOf = $this->definitions->resolveTagged($id, $new); + + array_walk($arrayOf, function (&$resolved) { + $resolved = $this->inflectors->inflect($resolved); + }); + + return $arrayOf; + } + + if ($this->providers->provides($id)) { + $this->providers->register($id); + + if (!$this->definitions->has($id) && !$this->definitions->hasTag($id)) { + throw new ContainerException(sprintf('Service provider lied about providing (%s) service', $id)); + } + + return $this->get($id, $new); + } + + foreach ($this->delegates as $delegate) { + if ($delegate->has($id)) { + $resolved = $delegate->get($id); + return $this->inflectors->inflect($resolved); + } + } + + throw new NotFoundException(sprintf('Alias (%s) is not being managed by the container or delegates', $id)); + } + + /** + * {@inheritdoc} + */ + public function has($id) : bool + { + if ($this->definitions->has($id)) { + return true; + } + + if ($this->definitions->hasTag($id)) { + return true; + } + + if ($this->providers->provides($id)) { + return true; + } + + foreach ($this->delegates as $delegate) { + if ($delegate->has($id)) { + return true; + } + } + + return false; + } + + /** + * Allows for manipulation of specific types on resolution. + * + * @param string $type + * @param callable|null $callback + * + * @return InflectorInterface + */ + public function inflector(string $type, callable $callback = null) : InflectorInterface + { + return $this->inflectors->add($type, $callback); + } + + /** + * Delegate a backup container to be checked for services if it + * cannot be resolved via this container. + * + * @param ContainerInterface $container + * + * @return self + */ + public function delegate(ContainerInterface $container) : self + { + $this->delegates[] = $container; + + if ($container instanceof ContainerAwareInterface) { + $container->setLeagueContainer($this); + } + + return $this; + } +} diff --git a/lib/packages/League/Container/ContainerAwareInterface.php b/lib/packages/League/Container/ContainerAwareInterface.php new file mode 100644 index 00000000000..b0a4f91d335 --- /dev/null +++ b/lib/packages/League/Container/ContainerAwareInterface.php @@ -0,0 +1,40 @@ +container = $container; + + return $this; + } + + /** + * Get the container. + * + * @return ContainerInterface + */ + public function getContainer() : ContainerInterface + { + if ($this->container instanceof ContainerInterface) { + return $this->container; + } + + throw new ContainerException('No container implementation has been set.'); + } + + /** + * Set a container. + * + * @param Container $container + * + * @return self + */ + public function setLeagueContainer(Container $container) : ContainerAwareInterface + { + $this->container = $container; + $this->leagueContainer = $container; + + return $this; + } + + /** + * Get the container. + * + * @return Container + */ + public function getLeagueContainer() : Container + { + if ($this->leagueContainer instanceof Container) { + return $this->leagueContainer; + } + + throw new ContainerException('No container implementation has been set.'); + } +} diff --git a/lib/packages/League/Container/Definition/Definition.php b/lib/packages/League/Container/Definition/Definition.php new file mode 100644 index 00000000000..c35708016c1 --- /dev/null +++ b/lib/packages/League/Container/Definition/Definition.php @@ -0,0 +1,274 @@ +alias = $id; + $this->concrete = $concrete; + } + + /** + * {@inheritdoc} + */ + public function addTag(string $tag) : DefinitionInterface + { + $this->tags[$tag] = true; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function hasTag(string $tag) : bool + { + return isset($this->tags[$tag]); + } + + /** + * {@inheritdoc} + */ + public function setAlias(string $id) : DefinitionInterface + { + $this->alias = $id; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getAlias() : string + { + return $this->alias; + } + + /** + * {@inheritdoc} + */ + public function setShared(bool $shared = true) : DefinitionInterface + { + $this->shared = $shared; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function isShared() : bool + { + return $this->shared; + } + + /** + * {@inheritdoc} + */ + public function getConcrete() + { + return $this->concrete; + } + + /** + * {@inheritdoc} + */ + public function setConcrete($concrete) : DefinitionInterface + { + $this->concrete = $concrete; + $this->resolved = null; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addArgument($arg) : DefinitionInterface + { + $this->arguments[] = $arg; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addArguments(array $args) : DefinitionInterface + { + foreach ($args as $arg) { + $this->addArgument($arg); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addMethodCall(string $method, array $args = []) : DefinitionInterface + { + $this->methods[] = [ + 'method' => $method, + 'arguments' => $args + ]; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function addMethodCalls(array $methods = []) : DefinitionInterface + { + foreach ($methods as $method => $args) { + $this->addMethodCall($method, $args); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function resolve(bool $new = false) + { + $concrete = $this->concrete; + + if ($this->isShared() && $this->resolved !== null && $new === false) { + return $this->resolved; + } + + if (is_callable($concrete)) { + $concrete = $this->resolveCallable($concrete); + } + + if ($concrete instanceof RawArgumentInterface) { + $this->resolved = $concrete->getValue(); + + return $concrete->getValue(); + } + + if ($concrete instanceof ClassNameInterface) { + $concrete = $concrete->getClassName(); + } + + if (is_string($concrete) && class_exists($concrete)) { + $concrete = $this->resolveClass($concrete); + } + + if (is_object($concrete)) { + $concrete = $this->invokeMethods($concrete); + } + + $this->resolved = $concrete; + + return $concrete; + } + + /** + * Resolve a callable. + * + * @param callable $concrete + * + * @return mixed + */ + protected function resolveCallable(callable $concrete) + { + $resolved = $this->resolveArguments($this->arguments); + + return call_user_func_array($concrete, $resolved); + } + + /** + * Resolve a class. + * + * @param string $concrete + * + * @return object + * + * @throws ReflectionException + */ + protected function resolveClass(string $concrete) + { + $resolved = $this->resolveArguments($this->arguments); + $reflection = new ReflectionClass($concrete); + + return $reflection->newInstanceArgs($resolved); + } + + /** + * Invoke methods on resolved instance. + * + * @param object $instance + * + * @return object + */ + protected function invokeMethods($instance) + { + foreach ($this->methods as $method) { + $args = $this->resolveArguments($method['arguments']); + + /** @var callable $callable */ + $callable = [$instance, $method['method']]; + call_user_func_array($callable, $args); + } + + return $instance; + } +} diff --git a/lib/packages/League/Container/Definition/DefinitionAggregate.php b/lib/packages/League/Container/Definition/DefinitionAggregate.php new file mode 100644 index 00000000000..3e39b2fc207 --- /dev/null +++ b/lib/packages/League/Container/Definition/DefinitionAggregate.php @@ -0,0 +1,124 @@ +definitions = array_filter($definitions, function ($definition) { + return ($definition instanceof DefinitionInterface); + }); + } + + /** + * {@inheritdoc} + */ + public function add(string $id, $definition, bool $shared = false) : DefinitionInterface + { + if (!$definition instanceof DefinitionInterface) { + $definition = new Definition($id, $definition); + } + + $this->definitions[] = $definition + ->setAlias($id) + ->setShared($shared) + ; + + return $definition; + } + + /** + * {@inheritdoc} + */ + public function has(string $id) : bool + { + foreach ($this->getIterator() as $definition) { + if ($id === $definition->getAlias()) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function hasTag(string $tag) : bool + { + foreach ($this->getIterator() as $definition) { + if ($definition->hasTag($tag)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getDefinition(string $id) : DefinitionInterface + { + foreach ($this->getIterator() as $definition) { + if ($id === $definition->getAlias()) { + return $definition->setLeagueContainer($this->getLeagueContainer()); + } + } + + throw new NotFoundException(sprintf('Alias (%s) is not being handled as a definition.', $id)); + } + + /** + * {@inheritdoc} + */ + public function resolve(string $id, bool $new = false) + { + return $this->getDefinition($id)->resolve($new); + } + + /** + * {@inheritdoc} + */ + public function resolveTagged(string $tag, bool $new = false) : array + { + $arrayOf = []; + + foreach ($this->getIterator() as $definition) { + if ($definition->hasTag($tag)) { + $arrayOf[] = $definition->setLeagueContainer($this->getLeagueContainer())->resolve($new); + } + } + + return $arrayOf; + } + + /** + * {@inheritdoc} + */ + public function getIterator() : Generator + { + $count = count($this->definitions); + + for ($i = 0; $i < $count; $i++) { + yield $this->definitions[$i]; + } + } +} diff --git a/lib/packages/League/Container/Definition/DefinitionAggregateInterface.php b/lib/packages/League/Container/Definition/DefinitionAggregateInterface.php new file mode 100644 index 00000000000..2d5842fe6b3 --- /dev/null +++ b/lib/packages/League/Container/Definition/DefinitionAggregateInterface.php @@ -0,0 +1,67 @@ +type = $type; + $this->callback = $callback; + } + + /** + * {@inheritdoc} + */ + public function getType() : string + { + return $this->type; + } + + /** + * {@inheritdoc} + */ + public function invokeMethod(string $name, array $args) : InflectorInterface + { + $this->methods[$name] = $args; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function invokeMethods(array $methods) : InflectorInterface + { + foreach ($methods as $name => $args) { + $this->invokeMethod($name, $args); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setProperty(string $property, $value) : InflectorInterface + { + $this->properties[$property] = $this->resolveArguments([$value])[0]; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function setProperties(array $properties) : InflectorInterface + { + foreach ($properties as $property => $value) { + $this->setProperty($property, $value); + } + + return $this; + } + + /** + * {@inheritdoc} + */ + public function inflect($object) + { + $properties = $this->resolveArguments(array_values($this->properties)); + $properties = array_combine(array_keys($this->properties), $properties); + + // array_combine() can technically return false + foreach ($properties ?: [] as $property => $value) { + $object->{$property} = $value; + } + + foreach ($this->methods as $method => $args) { + $args = $this->resolveArguments($args); + + /** @var callable $callable */ + $callable = [$object, $method]; + call_user_func_array($callable, $args); + } + + if ($this->callback !== null) { + call_user_func($this->callback, $object); + } + } +} diff --git a/lib/packages/League/Container/Inflector/InflectorAggregate.php b/lib/packages/League/Container/Inflector/InflectorAggregate.php new file mode 100644 index 00000000000..4db8471c97d --- /dev/null +++ b/lib/packages/League/Container/Inflector/InflectorAggregate.php @@ -0,0 +1,58 @@ +inflectors[] = $inflector; + + return $inflector; + } + + /** + * {@inheritdoc} + */ + public function getIterator() : Generator + { + $count = count($this->inflectors); + + for ($i = 0; $i < $count; $i++) { + yield $this->inflectors[$i]; + } + } + + /** + * {@inheritdoc} + */ + public function inflect($object) + { + foreach ($this->getIterator() as $inflector) { + $type = $inflector->getType(); + + if (! $object instanceof $type) { + continue; + } + + $inflector->setLeagueContainer($this->getLeagueContainer()); + $inflector->inflect($object); + } + + return $object; + } +} diff --git a/lib/packages/League/Container/Inflector/InflectorAggregateInterface.php b/lib/packages/League/Container/Inflector/InflectorAggregateInterface.php new file mode 100644 index 00000000000..aac6455a96d --- /dev/null +++ b/lib/packages/League/Container/Inflector/InflectorAggregateInterface.php @@ -0,0 +1,27 @@ +cacheResolutions === true && array_key_exists($id, $this->cache)) { + return $this->cache[$id]; + } + + if (! $this->has($id)) { + throw new NotFoundException( + sprintf('Alias (%s) is not an existing class and therefore cannot be resolved', $id) + ); + } + + $reflector = new ReflectionClass($id); + $construct = $reflector->getConstructor(); + + $resolution = $construct === null + ? new $id + : $resolution = $reflector->newInstanceArgs($this->reflectArguments($construct, $args)) + ; + + if ($this->cacheResolutions === true) { + $this->cache[$id] = $resolution; + } + + return $resolution; + } + + /** + * {@inheritdoc} + */ + public function has($id) : bool + { + return class_exists($id); + } + + /** + * Invoke a callable via the container. + * + * @param callable $callable + * @param array $args + * + * @return mixed + * + * @throws ReflectionException + */ + public function call(callable $callable, array $args = []) + { + if (is_string($callable) && strpos($callable, '::') !== false) { + $callable = explode('::', $callable); + } + + if (is_array($callable)) { + if (is_string($callable[0])) { + $callable[0] = $this->getContainer()->get($callable[0]); + } + + $reflection = new ReflectionMethod($callable[0], $callable[1]); + + if ($reflection->isStatic()) { + $callable[0] = null; + } + + return $reflection->invokeArgs($callable[0], $this->reflectArguments($reflection, $args)); + } + + if (is_object($callable)) { + $reflection = new ReflectionMethod($callable, '__invoke'); + + return $reflection->invokeArgs($callable, $this->reflectArguments($reflection, $args)); + } + + $reflection = new ReflectionFunction(\Closure::fromCallable($callable)); + + return $reflection->invokeArgs($this->reflectArguments($reflection, $args)); + } + + /** + * Whether the container should default to caching resolutions and returning + * the cache on following calls. + * + * @param boolean $option + * + * @return self + */ + public function cacheResolutions(bool $option = true) : ContainerInterface + { + $this->cacheResolutions = $option; + + return $this; + } +} diff --git a/lib/packages/League/Container/ServiceProvider/AbstractServiceProvider.php b/lib/packages/League/Container/ServiceProvider/AbstractServiceProvider.php new file mode 100644 index 00000000000..ed6af441f80 --- /dev/null +++ b/lib/packages/League/Container/ServiceProvider/AbstractServiceProvider.php @@ -0,0 +1,46 @@ +provides, true); + } + + /** + * {@inheritdoc} + */ + public function setIdentifier(string $id) : ServiceProviderInterface + { + $this->identifier = $id; + + return $this; + } + + /** + * {@inheritdoc} + */ + public function getIdentifier() : string + { + return $this->identifier ?? get_class($this); + } +} diff --git a/lib/packages/League/Container/ServiceProvider/BootableServiceProviderInterface.php b/lib/packages/League/Container/ServiceProvider/BootableServiceProviderInterface.php new file mode 100644 index 00000000000..195b48a14a6 --- /dev/null +++ b/lib/packages/League/Container/ServiceProvider/BootableServiceProviderInterface.php @@ -0,0 +1,14 @@ +getContainer()->has($provider)) { + $provider = $this->getContainer()->get($provider); + } elseif (is_string($provider) && class_exists($provider)) { + $provider = new $provider; + } + + if (in_array($provider, $this->providers, true)) { + return $this; + } + + if ($provider instanceof ContainerAwareInterface) { + $provider->setLeagueContainer($this->getLeagueContainer()); + } + + if ($provider instanceof BootableServiceProviderInterface) { + $provider->boot(); + } + + if ($provider instanceof ServiceProviderInterface) { + $this->providers[] = $provider; + + return $this; + } + + throw new ContainerException( + 'A service provider must be a fully qualified class name or instance ' . + 'of (\Automattic\WooCommerce\Vendor\League\Container\ServiceProvider\ServiceProviderInterface)' + ); + } + + /** + * {@inheritdoc} + */ + public function provides(string $service) : bool + { + foreach ($this->getIterator() as $provider) { + if ($provider->provides($service)) { + return true; + } + } + + return false; + } + + /** + * {@inheritdoc} + */ + public function getIterator() : Generator + { + $count = count($this->providers); + + for ($i = 0; $i < $count; $i++) { + yield $this->providers[$i]; + } + } + + /** + * {@inheritdoc} + */ + public function register(string $service) + { + if (false === $this->provides($service)) { + throw new ContainerException( + sprintf('(%s) is not provided by a service provider', $service) + ); + } + + foreach ($this->getIterator() as $provider) { + if (in_array($provider->getIdentifier(), $this->registered, true)) { + continue; + } + + if ($provider->provides($service)) { + $provider->register(); + $this->registered[] = $provider->getIdentifier(); + } + } + } +} diff --git a/lib/packages/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php b/lib/packages/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php new file mode 100644 index 00000000000..c2f61d6d877 --- /dev/null +++ b/lib/packages/League/Container/ServiceProvider/ServiceProviderAggregateInterface.php @@ -0,0 +1,36 @@ +leagueContainer property or the `getLeagueContainer` method + * from the ContainerAwareTrait. + * + * @return void + */ + public function register(); + + /** + * Set a custom id for the service provider. This enables + * registering the same service provider multiple times. + * + * @param string $id + * + * @return self + */ + public function setIdentifier(string $id) : ServiceProviderInterface; + + /** + * The id of the service provider uniquely identifies it, so + * that we can quickly determine if it has already been registered. + * Defaults to get_class($provider). + * + * @return string + */ + public function getIdentifier() : string; +} diff --git a/phpcs.xml b/phpcs.xml index a4b5131f5c9..bfd630f6681 100644 --- a/phpcs.xml +++ b/phpcs.xml @@ -14,6 +14,7 @@ includes/wc-deprecated-functions.php */node_modules/* */vendor/* + lib/ diff --git a/src/Internal/DependencyManagement/AbstractServiceProvider.php b/src/Internal/DependencyManagement/AbstractServiceProvider.php index bd1409ebda3..bc35e90b37c 100644 --- a/src/Internal/DependencyManagement/AbstractServiceProvider.php +++ b/src/Internal/DependencyManagement/AbstractServiceProvider.php @@ -7,6 +7,7 @@ namespace Automattic\WooCommerce\Internal\DependencyManagement; use Automattic\WooCommerce\Vendor\League\Container\Argument\RawArgument; use Automattic\WooCommerce\Vendor\League\Container\Definition\DefinitionInterface; +use Automattic\WooCommerce\Vendor\League\Container\ServiceProvider\AbstractServiceProvider as BaseServiceProvider; /** * Base class for the service providers used to register classes in the container. @@ -18,7 +19,7 @@ use Automattic\WooCommerce\Vendor\League\Container\Definition\DefinitionInterfac * - The `share_with_auto_arguments` method, sibling of the above. * - Convenience `add` and `share` methods that are just proxies for the same methods in `$this->getContainer()`. */ -abstract class AbstractServiceProvider extends \Automattic\WooCommerce\Vendor\League\Container\ServiceProvider\AbstractServiceProvider { +abstract class AbstractServiceProvider extends BaseServiceProvider { /** * Register a class in the container and use reflection to guess the injection method arguments. diff --git a/src/Vendor/.gitignore b/src/Vendor/.gitignore new file mode 100644 index 00000000000..ef7b2901fa6 --- /dev/null +++ b/src/Vendor/.gitignore @@ -0,0 +1,5 @@ +# Prevent anyone from accidentally adding code to these directories. +# This will break any PRs that do, revealing ths mistake they made. +README.md +!.gitignore +!README.md diff --git a/src/Vendor/README.md b/src/Vendor/README.md new file mode 100644 index 00000000000..ae39d3e4e8b --- /dev/null +++ b/src/Vendor/README.md @@ -0,0 +1,7 @@ +# WARNING + +The namespace of this folder belongs to our dummy [lib package](./../lib/README.md) to manage conflict avoidance. +No files should be added here! + +These are **internal** dependencies and **should not** be considered backwards compatible! Developers should not +use these files outside of WooCommerce Core as they are subject to change. diff --git a/tests/e2e/env/package-lock.json b/tests/e2e/env/package-lock.json index 3f9544f0350..7def3f56cb9 100644 --- a/tests/e2e/env/package-lock.json +++ b/tests/e2e/env/package-lock.json @@ -5,7 +5,7 @@ "requires": true, "dependencies": { "@automattic/puppeteer-utils": { - "version": "github:Automattic/puppeteer-utils#0f3ec50fc22d7bd2a4bd69fc172e8a66d958ef2d", + "version": "github:Automattic/puppeteer-utils#0f3ec50", "from": "github:Automattic/puppeteer-utils#0f3ec50", "requires": { "@babel/cli": "^7.8.3",