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",