From c798a19ff9c05076990dc466018be12fb8d49b3f Mon Sep 17 00:00:00 2001 From: QWp6t Date: Thu, 20 Aug 2020 09:05:39 -0700 Subject: [PATCH 01/22] refactor: Update entire code base BREAKING CHANGE: Several APIs have changed. --- .editorconfig | 5 +- .travis.yml | 10 +- README.md | 42 +- composer.json | 32 +- composer.lock | 2241 ++++++++++++++++- lib/utils.php | 68 - modules/clean-up.php | 157 -- modules/disable-asset-versioning.php | 15 - modules/disable-rest-api.php | 17 - modules/disable-trackbacks.php | 64 - modules/google-analytics.php | 63 - modules/js-to-footer.php | 16 - modules/nav-walker.php | 130 - modules/nice-search.php | 30 - modules/relative-urls.php | 58 - phpcs.xml | 30 - phpunit.xml.dist | 34 + resources/views/google-analytics.php | 21 + soil.php | 82 +- src/DOM.php | 82 + src/Exceptions/LifecycleException.php | 10 + src/Modules/AbstractModule.php | 176 ++ src/Modules/CleanUpModule.php | 261 ++ src/Modules/DisableAssetVersioningModule.php | 42 + src/Modules/DisableRestApiModule.php | 52 + src/Modules/DisableTrackbacksModule.php | 107 + src/Modules/GoogleAnalyticsModule.php | 38 + src/Modules/JsToFooterModule.php | 35 + src/Modules/NavWalkerModule.php | 50 + src/Modules/NiceSearchModule.php | 94 + src/Modules/RelativeUrlsModule.php | 146 ++ src/NavWalker.php | 141 ++ src/Soil.php | 106 + src/helpers.php | 53 + tests/TestCase.php | 35 + tests/Unit/DomTest.php | 68 + tests/Unit/EntrypointTest.php | 22 + tests/Unit/Helpers/UrlCompareTest.php | 53 + tests/Unit/ModuleTest.php | 106 + tests/Unit/Modules/CleanUpModuleTest.php | 155 ++ tests/Unit/Modules/RelativeUrlsModuleTest.php | 62 + tests/Unit/SoilTest.php | 53 + .../__fixtures__/modules/CustomHookModule.php | 8 + .../__fixtures__/modules/CustomNameModule.php | 8 + tests/__fixtures__/modules/StubModule.php | 13 + tests/api.php | 36 + tests/bootstrap.php | 21 + 47 files changed, 4285 insertions(+), 863 deletions(-) delete mode 100644 lib/utils.php delete mode 100644 modules/clean-up.php delete mode 100644 modules/disable-asset-versioning.php delete mode 100644 modules/disable-rest-api.php delete mode 100644 modules/disable-trackbacks.php delete mode 100644 modules/google-analytics.php delete mode 100644 modules/js-to-footer.php delete mode 100644 modules/nav-walker.php delete mode 100644 modules/nice-search.php delete mode 100644 modules/relative-urls.php delete mode 100644 phpcs.xml create mode 100644 phpunit.xml.dist create mode 100644 resources/views/google-analytics.php create mode 100644 src/DOM.php create mode 100644 src/Exceptions/LifecycleException.php create mode 100644 src/Modules/AbstractModule.php create mode 100644 src/Modules/CleanUpModule.php create mode 100644 src/Modules/DisableAssetVersioningModule.php create mode 100644 src/Modules/DisableRestApiModule.php create mode 100644 src/Modules/DisableTrackbacksModule.php create mode 100644 src/Modules/GoogleAnalyticsModule.php create mode 100644 src/Modules/JsToFooterModule.php create mode 100644 src/Modules/NavWalkerModule.php create mode 100644 src/Modules/NiceSearchModule.php create mode 100644 src/Modules/RelativeUrlsModule.php create mode 100644 src/NavWalker.php create mode 100644 src/Soil.php create mode 100644 src/helpers.php create mode 100644 tests/TestCase.php create mode 100644 tests/Unit/DomTest.php create mode 100644 tests/Unit/EntrypointTest.php create mode 100644 tests/Unit/Helpers/UrlCompareTest.php create mode 100644 tests/Unit/ModuleTest.php create mode 100644 tests/Unit/Modules/CleanUpModuleTest.php create mode 100644 tests/Unit/Modules/RelativeUrlsModuleTest.php create mode 100644 tests/Unit/SoilTest.php create mode 100644 tests/__fixtures__/modules/CustomHookModule.php create mode 100644 tests/__fixtures__/modules/CustomNameModule.php create mode 100644 tests/__fixtures__/modules/StubModule.php create mode 100644 tests/api.php create mode 100644 tests/bootstrap.php diff --git a/.editorconfig b/.editorconfig index cf8d7fa6..0e417842 100644 --- a/.editorconfig +++ b/.editorconfig @@ -4,8 +4,11 @@ root = true [*] indent_style = space -indent_size = 2 +indent_size = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true + +[resources/**] +indent_size = 2 diff --git a/.travis.yml b/.travis.yml index 2480bd99..0cf61f50 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,14 +1,15 @@ sudo: false language: php php: - - nightly - - 7.0 - 5.6 + - 7.0 + - 7.1 + - 7.2 + - 7.3 + - 7.4 matrix: fast_finish: true - allow_failures: - - php: nightly cache: directories: @@ -23,4 +24,5 @@ install: - composer install -o --prefer-dist --no-interaction script: + - composer lint - composer test diff --git a/README.md b/README.md index 332a29b0..9f8d7d56 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Soil is a commercial plugin available from [https://roots.io/plugins/soil/](http - PHP >= 5.4.x + PHP >= 5.6.x php -v php.net @@ -56,31 +56,31 @@ wp plugin activate soil ## Modules * **Cleaner WordPress markup**
- `add_theme_support('soil-clean-up');` + `add_theme_support('soil', 'clean-up');` * **Disable REST API**
- `add_theme_support('soil-disable-rest-api');` + `add_theme_support('soil', 'disable-rest-api');` * **Disable asset versioning**
- `add_theme_support('soil-disable-asset-versioning');` + `add_theme_support('soil', 'disable-asset-versioning');` * **Disable trackbacks**
- `add_theme_support('soil-disable-trackbacks');` + `add_theme_support('soil', 'disable-trackbacks');` -* **Google Analytics** ([more info](https://github.com/roots/soil/wiki/Google-Analytics))
- `add_theme_support('soil-google-analytics', 'UA-XXXXX-Y');` +* **Google Analytics**
+ `add_theme_support('soil', 'google-analytics');` * **Move all JS to the footer**
- `add_theme_support('soil-js-to-footer');` + `add_theme_support('soil, 'js-to-footer');` * **Cleaner walker for navigation menus**
- `add_theme_support('soil-nav-walker');` + `add_theme_support('soil', 'nav-walker');` * **Convert search results from `/?s=query` to `/search/query/`**
- `add_theme_support('soil-nice-search');` + `add_theme_support('soil', 'nice-search');` * **Root relative URLs**
- `add_theme_support('soil-relative-urls');` + `add_theme_support('soil', 'relative-urls');` And in a format you can copy & paste into your theme: ```php @@ -88,15 +88,17 @@ And in a format you can copy & paste into your theme: * Enable features from Soil when plugin is activated * @link https://roots.io/plugins/soil/ */ -add_theme_support('soil-clean-up'); -add_theme_support('soil-disable-rest-api'); -add_theme_support('soil-disable-asset-versioning'); -add_theme_support('soil-disable-trackbacks'); -add_theme_support('soil-google-analytics', 'UA-XXXXX-Y'); -add_theme_support('soil-js-to-footer'); -add_theme_support('soil-nav-walker'); -add_theme_support('soil-nice-search'); -add_theme_support('soil-relative-urls'); +add_theme_support('soil', [ + 'clean-up', + 'disable-rest-api', + 'disable-asset-versioning', + 'disable-trackbacks', + 'google-analytics', + 'js-to-footer', + 'nav-walker', + 'nice-search', + 'relative-urls' +]); ``` ## Support diff --git a/composer.json b/composer.json index dc4dd6da..a01b51fd 100644 --- a/composer.json +++ b/composer.json @@ -14,6 +14,11 @@ "name": "Scott Walkinshaw", "email": "scott.walkinshaw@gmail.com", "homepage": "https://github.com/swalkinshaw" + }, + { + "name": "QWp6t", + "email": "craig@roots.io", + "homepage": "https://github.com/qwp6t" } ], "keywords": [ @@ -23,16 +28,31 @@ "issues": "https://github.com/roots/soil/issues", "forum": "https://discourse.roots.io/" }, + "autoload": { + "psr-4": { + "Roots\\Soil\\": "src/" + }, + "files": [ + "src/helpers.php" + ] + }, + "autoload-dev": { + "psr-4": { + "Roots\\Soil\\Tests\\": "tests/", + "Roots\\Soil\\Tests\\Fixtures\\Modules\\": "tests/__fixtures__/modules/" + } + }, "require": { - "php": ">=5.4.0", - "composer/installers": "~1.0" + "php": ">=5.6.0" }, "require-dev": { - "squizlabs/php_codesniffer": "^2.5.1" + "squizlabs/php_codesniffer": "^3.5", + "brain/monkey": "^2.4", + "phpunit/phpunit": "^9.3", + "mockery/mockery": "^1.4" }, "scripts": { - "test": [ - "vendor/bin/phpcs --extensions=php --ignore=vendor/ -n -s ." - ] + "test": "vendor/bin/phpunit", + "lint": "vendor/bin/phpcs --standard=PSR12 --extensions=php --ignore=vendor/ -n -s src" } } diff --git a/composer.lock b/composer.lock index 94e27cc5..55e5d968 100644 --- a/composer.lock +++ b/composer.lock @@ -1,171 +1,2002 @@ { "_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#composer-lock-the-lock-file", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "hash": "2748ed88c284a2bc4572965d1088dbbf", - "content-hash": "b09ac7826fe615e8d29ed9324392fb7f", - "packages": [ + "content-hash": "e6d5094ef874ad50174bbb09c6e5e1a2", + "packages": [], + "packages-dev": [ + { + "name": "antecedent/patchwork", + "version": "2.1.12", + "source": { + "type": "git", + "url": "https://github.com/antecedent/patchwork.git", + "reference": "b98e046dd4c0acc34a0846604f06f6111654d9ea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/b98e046dd4c0acc34a0846604f06f6111654d9ea", + "reference": "b98e046dd4c0acc34a0846604f06f6111654d9ea", + "shasum": "" + }, + "require": { + "php": ">=5.4.0" + }, + "require-dev": { + "phpunit/phpunit": ">=4" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Ignas Rudaitis", + "email": "ignas.rudaitis@gmail.com" + } + ], + "description": "Method redefinition (monkey-patching) functionality for PHP.", + "homepage": "http://patchwork2.org/", + "keywords": [ + "aop", + "aspect", + "interception", + "monkeypatching", + "redefinition", + "runkit", + "testing" + ], + "time": "2019-12-22T17:52:09+00:00" + }, + { + "name": "brain/monkey", + "version": "2.4.0", + "source": { + "type": "git", + "url": "https://github.com/Brain-WP/BrainMonkey.git", + "reference": "b3ce8b619c26db6abd01b9dcfd6a2c0254060956" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/b3ce8b619c26db6abd01b9dcfd6a2c0254060956", + "reference": "b3ce8b619c26db6abd01b9dcfd6a2c0254060956", + "shasum": "" + }, + "require": { + "antecedent/patchwork": "^2.0", + "mockery/mockery": ">=0.9 <2", + "php": ">=5.6.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4", + "phpcompatibility/php-compatibility": "^9.3.0", + "phpunit/phpunit": "^5.7.9 || ^6.0 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-version/1": "1.x-dev", + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "psr-4": { + "Brain\\Monkey\\": "src/" + }, + "files": [ + "inc/api.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Giuseppe Mazzapica", + "email": "giuseppe.mazzapica@gmail.com", + "homepage": "https://gmazzap.me", + "role": "Developer" + } + ], + "description": "Mocking utility for PHP functions and WordPress plugin API", + "keywords": [ + "Monkey Patching", + "interception", + "mock", + "mock functions", + "mockery", + "patchwork", + "redefinition", + "runkit", + "test", + "testing" + ], + "time": "2019-11-24T16:03:21+00:00" + }, + { + "name": "doctrine/instantiator", + "version": "1.3.1", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", + "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^6.0", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.13", + "phpstan/phpstan-phpunit": "^0.11", + "phpstan/phpstan-shim": "^0.11", + "phpunit/phpunit": "^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "http://ocramius.github.com/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2020-05-29T17:27:14+00:00" + }, + { + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", + "source": { + "type": "git", + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "shasum": "" + }, + "require": { + "php": "^5.3|^7.0|^8.0" + }, + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" + }, + "require-dev": { + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "description": "This is the PHP port of Hamcrest Matchers", + "keywords": [ + "test" + ], + "time": "2020-07-09T08:09:16+00:00" + }, + { + "name": "mockery/mockery", + "version": "1.4.2", + "source": { + "type": "git", + "url": "https://github.com/mockery/mockery.git", + "reference": "20cab678faed06fac225193be281ea0fddb43b93" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/mockery/mockery/zipball/20cab678faed06fac225193be281ea0fddb43b93", + "reference": "20cab678faed06fac225193be281ea0fddb43b93", + "shasum": "" + }, + "require": { + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": "^7.3 || ^8.0" + }, + "conflict": { + "phpunit/phpunit": "<8.0" + }, + "require-dev": { + "phpunit/phpunit": "^8.5 || ^9.3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.4.x-dev" + } + }, + "autoload": { + "psr-0": { + "Mockery": "library/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "http://blog.astrumfutura.com" + }, + { + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "http://davedevelopment.co.uk" + } + ], + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", + "keywords": [ + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" + ], + "time": "2020-08-11T18:10:13+00:00" + }, + { + "name": "myclabs/deep-copy", + "version": "1.10.1", + "source": { + "type": "git", + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "replace": { + "myclabs/deep-copy": "self.version" + }, + "require-dev": { + "doctrine/collections": "^1.0", + "doctrine/common": "^2.6", + "phpunit/phpunit": "^7.1" + }, + "type": "library", + "autoload": { + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + }, + "files": [ + "src/DeepCopy/deep_copy.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "description": "Create deep copies (clones) of your objects", + "keywords": [ + "clone", + "copy", + "duplicate", + "object", + "object graph" + ], + "funding": [ + { + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" + } + ], + "time": "2020-06-29T13:22:24+00:00" + }, + { + "name": "nikic/php-parser", + "version": "v4.8.0", + "source": { + "type": "git", + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8c58eb4cd4f3883f82611abeac2efbc3dbed787e", + "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e", + "shasum": "" + }, + "require": { + "ext-tokenizer": "*", + "php": ">=7.0" + }, + "require-dev": { + "ircmaxell/php-yacc": "^0.0.6", + "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" + }, + "bin": [ + "bin/php-parse" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.8-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Nikita Popov" + } + ], + "description": "A PHP parser written in PHP", + "keywords": [ + "parser", + "php" + ], + "time": "2020-08-09T10:23:20+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "ext-xmlwriter": "*", + "phar-io/version": "^3.0.1", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2020-06-27T14:33:11+00:00" + }, + { + "name": "phar-io/version", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", + "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2020-06-27T14:39:04+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "2.2.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionCommon.git", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-2.x": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jaap van Otterdijk", + "email": "opensource@ijaap.nl" + } + ], + "description": "Common reflection classes used by phpdocumentor to reflect the code structure", + "homepage": "http://www.phpdoc.org", + "keywords": [ + "FQSEN", + "phpDocumentor", + "phpdoc", + "reflection", + "static analysis" + ], + "time": "2020-06-27T09:03:43+00:00" + }, + { + "name": "phpdocumentor/reflection-docblock", + "version": "5.2.1", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", + "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", + "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", + "shasum": "" + }, + "require": { + "ext-filter": "*", + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.2", + "phpdocumentor/type-resolver": "^1.3", + "webmozart/assert": "^1.9.1" + }, + "require-dev": { + "mockery/mockery": "~1.3.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + }, + { + "name": "Jaap van Otterdijk", + "email": "account@ijaap.nl" + } + ], + "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", + "time": "2020-08-15T11:14:08+00:00" + }, + { + "name": "phpdocumentor/type-resolver", + "version": "1.3.0", + "source": { + "type": "git", + "url": "https://github.com/phpDocumentor/TypeResolver.git", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", + "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", + "shasum": "" + }, + "require": { + "php": "^7.2 || ^8.0", + "phpdocumentor/reflection-common": "^2.0" + }, + "require-dev": { + "ext-tokenizer": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "phpDocumentor\\Reflection\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Mike van Riel", + "email": "me@mikevanriel.com" + } + ], + "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", + "time": "2020-06-27T10:12:23+00:00" + }, + { + "name": "phpspec/prophecy", + "version": "1.11.1", + "source": { + "type": "git", + "url": "https://github.com/phpspec/prophecy.git", + "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", + "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.2", + "php": "^7.2", + "phpdocumentor/reflection-docblock": "^5.0", + "sebastian/comparator": "^3.0 || ^4.0", + "sebastian/recursion-context": "^3.0 || ^4.0" + }, + "require-dev": { + "phpspec/phpspec": "^6.0", + "phpunit/phpunit": "^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.11.x-dev" + } + }, + "autoload": { + "psr-4": { + "Prophecy\\": "src/Prophecy" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Konstantin Kudryashov", + "email": "ever.zet@gmail.com", + "homepage": "http://everzet.com" + }, + { + "name": "Marcello Duarte", + "email": "marcello.duarte@gmail.com" + } + ], + "description": "Highly opinionated mocking framework for PHP 5.3+", + "homepage": "https://github.com/phpspec/prophecy", + "keywords": [ + "Double", + "Dummy", + "fake", + "mock", + "spy", + "stub" + ], + "time": "2020-07-08T12:44:21+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "9.1.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4422fca28c3634e2de8c7c373af97a104dd1a45f", + "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^4.8", + "php": "^7.3 || ^8.0", + "phpunit/php-file-iterator": "^3.0.3", + "phpunit/php-text-template": "^2.0.2", + "sebastian/code-unit-reverse-lookup": "^2.0.2", + "sebastian/complexity": "^2.0", + "sebastian/environment": "^5.1.2", + "sebastian/lines-of-code": "^1.0", + "sebastian/version": "^3.0.1", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-pcov": "*", + "ext-xdebug": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-08-13T15:04:53+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "3.0.4", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/25fefc5b19835ca653877fe081644a3f8c1d915e", + "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-07-11T05:18:21+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "3.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "7a85b66acc48cacffdf87dadd3694e7123674298" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7a85b66acc48cacffdf87dadd3694e7123674298", + "reference": "7a85b66acc48cacffdf87dadd3694e7123674298", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-08-06T07:04:15+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", + "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "keywords": [ + "template" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T11:55:37+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "5.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/cc49734779cbb302bf51a44297dab8c4bbf941e7", + "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", + "keywords": [ + "timer" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T11:58:13+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "9.3.7", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "c638a0cac77347980352485912de48c99b42ad00" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c638a0cac77347980352485912de48c99b42ad00", + "reference": "c638a0cac77347980352485912de48c99b42ad00", + "shasum": "" + }, + "require": { + "doctrine/instantiator": "^1.3.1", + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.1", + "phar-io/version": "^3.0.2", + "php": "^7.3 || ^8.0", + "phpspec/prophecy": "^1.11.1", + "phpunit/php-code-coverage": "^9.1.1", + "phpunit/php-file-iterator": "^3.0.4", + "phpunit/php-invoker": "^3.1", + "phpunit/php-text-template": "^2.0.2", + "phpunit/php-timer": "^5.0.1", + "sebastian/code-unit": "^1.0.5", + "sebastian/comparator": "^4.0.3", + "sebastian/diff": "^4.0.2", + "sebastian/environment": "^5.1.2", + "sebastian/exporter": "^4.0.2", + "sebastian/global-state": "^5.0", + "sebastian/object-enumerator": "^4.0.2", + "sebastian/resource-operations": "^3.0.2", + "sebastian/type": "^2.2.1", + "sebastian/version": "^3.0.1" + }, + "require-dev": { + "ext-pdo": "*", + "phpspec/prophecy-phpunit": "^2.0.1" + }, + "suggest": { + "ext-soap": "*", + "ext-xdebug": "*" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "9.3-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ], + "files": [ + "src/Framework/Assert/Functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "funding": [ + { + "url": "https://phpunit.de/donate.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-08-11T15:36:12+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "1.0.5", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "c1e2df332c905079980b119c4db103117e5e5c90" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/c1e2df332c905079980b119c4db103117e5e5c90", + "reference": "c1e2df332c905079980b119c4db103117e5e5c90", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:50:45+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "2.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ee51f9bb0c6d8a43337055db3120829fa14da819", + "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:04:00+00:00" + }, + { + "name": "sebastian/comparator", + "version": "4.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "sebastian/diff": "^4.0", + "sebastian/exporter": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:05:46+00:00" + }, + { + "name": "sebastian/complexity", + "version": "2.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "33fcd6a26656c6546f70871244ecba4b4dced097" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/33fcd6a26656c6546f70871244ecba4b4dced097", + "reference": "33fcd6a26656c6546f70871244ecba4b4dced097", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.7", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-07-25T14:01:34+00:00" + }, + { + "name": "sebastian/diff", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-30T04:46:02+00:00" + }, + { + "name": "sebastian/environment", + "version": "5.1.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", + "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "http://www.github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:07:24+00:00" + }, + { + "name": "sebastian/exporter", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "571d721db4aec847a0e59690b954af33ebf9f023" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", + "reference": "571d721db4aec847a0e59690b954af33ebf9f023", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-mbstring": "*", + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "http://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:08:55+00:00" + }, + { + "name": "sebastian/global-state", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "22ae663c951bdc39da96603edc3239ed3a299097" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/22ae663c951bdc39da96603edc3239ed3a299097", + "reference": "22ae663c951bdc39da96603edc3239ed3a299097", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^9.3" + }, + "suggest": { + "ext-uopz": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "5.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Snapshotting of global state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-08-07T04:09:03+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "1.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e02bf626f404b5daec382a7b8a6a4456e49017e5", + "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^4.6", + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-07-22T18:33:42+00:00" + }, + { + "name": "sebastian/object-enumerator", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/074fed2d0a6d08e1677dd8ce9d32aecb384917b8", + "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0", + "sebastian/object-reflector": "^2.0", + "sebastian/recursion-context": "^4.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:11:32+00:00" + }, { - "name": "composer/installers", - "version": "v1.0.23", + "name": "sebastian/object-reflector", + "version": "2.0.2", "source": { "type": "git", - "url": "https://github.com/composer/installers.git", - "reference": "6213d900e92647831f7a406d5c530ea1f3d4360e" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "127a46f6b057441b201253526f81d5406d6c7840" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/6213d900e92647831f7a406d5c530ea1f3d4360e", - "reference": "6213d900e92647831f7a406d5c530ea1f3d4360e", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/127a46f6b057441b201253526f81d5406d6c7840", + "reference": "127a46f6b057441b201253526f81d5406d6c7840", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0" + "php": "^7.3 || ^8.0" }, - "replace": { - "roundcube/plugin-installer": "*", - "shama/baton": "*" + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:12:55+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "4.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" }, "require-dev": { - "composer/composer": "1.0.*@dev", - "phpunit/phpunit": "4.1.*" + "phpunit/phpunit": "^9.0" }, - "type": "composer-plugin", + "type": "library", "extra": { - "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { - "psr-0": { - "Composer\\Installers\\": "src/" + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } + ], + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:14:17+00:00" + }, + { + "name": "sebastian/resource-operations", + "version": "3.0.2", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "0653718a5a629b065e91f774595267f8dc32e213" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0653718a5a629b065e91f774595267f8dc32e213", + "reference": "0653718a5a629b065e91f774595267f8dc32e213", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "MIT" + "BSD-3-Clause" ], "authors": [ { - "name": "Kyle Robinson Young", - "email": "kyle@dontkry.com", - "homepage": "https://github.com/shama" - } - ], - "description": "A multi-framework Composer library installer", - "homepage": "http://composer.github.com/installers/", - "keywords": [ - "Craft", - "Dolibarr", - "Hurad", - "MODX Evo", - "OXID", - "SMF", - "Thelia", - "WolfCMS", - "agl", - "aimeos", - "annotatecms", - "bitrix", - "cakephp", - "chef", - "codeigniter", - "concrete5", - "croogo", - "dokuwiki", - "drupal", - "elgg", - "fuelphp", - "grav", - "installer", - "joomla", - "kohana", - "laravel", - "lithium", - "magento", - "mako", - "mediawiki", - "modulework", - "moodle", - "phpbb", - "piwik", - "ppi", - "puppet", - "roundcube", - "shopware", - "silverstripe", - "symfony", - "typo3", - "wordpress", - "zend", - "zikula" - ], - "time": "2016-01-27 12:54:22" - } - ], - "packages-dev": [ + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:16:22+00:00" + }, + { + "name": "sebastian/type", + "version": "2.2.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/86991e2b33446cd96e648c18bcdb1e95afb2c05a", + "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "require-dev": { + "phpunit/phpunit": "^9.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.2-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-07-05T08:31:53+00:00" + }, + { + "name": "sebastian/version", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "626586115d0ed31cb71483be55beb759b5af5a3c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/626586115d0ed31cb71483be55beb759b5af5a3c", + "reference": "626586115d0ed31cb71483be55beb759b5af5a3c", + "shasum": "" + }, + "require": { + "php": "^7.3 || ^8.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2020-06-26T12:18:43+00:00" + }, { "name": "squizlabs/php_codesniffer", - "version": "2.5.1", + "version": "3.5.6", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "6731851d6aaf1d0d6c58feff1065227b7fda3ba8" + "reference": "e97627871a7eab2f70e59166072a6b767d5834e0" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6731851d6aaf1d0d6c58feff1065227b7fda3ba8", - "reference": "6731851d6aaf1d0d6c58feff1065227b7fda3ba8", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/e97627871a7eab2f70e59166072a6b767d5834e0", + "reference": "e97627871a7eab2f70e59166072a6b767d5834e0", "shasum": "" }, "require": { + "ext-simplexml": "*", "ext-tokenizer": "*", "ext-xmlwriter": "*", - "php": ">=5.1.2" + "php": ">=5.4.0" }, "require-dev": { - "phpunit/phpunit": "~4.0" + "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" }, "bin": [ - "scripts/phpcs", - "scripts/phpcbf" + "bin/phpcs", + "bin/phpcbf" ], "type": "library", "extra": { "branch-alias": { - "dev-master": "2.x-dev" + "dev-master": "3.x-dev" } }, - "autoload": { - "classmap": [ - "CodeSniffer.php", - "CodeSniffer/CLI.php", - "CodeSniffer/Exception.php", - "CodeSniffer/File.php", - "CodeSniffer/Fixer.php", - "CodeSniffer/Report.php", - "CodeSniffer/Reporting.php", - "CodeSniffer/Sniff.php", - "CodeSniffer/Tokens.php", - "CodeSniffer/Reports/", - "CodeSniffer/Tokenizers/", - "CodeSniffer/DocGenerators/", - "CodeSniffer/Standards/AbstractPatternSniff.php", - "CodeSniffer/Standards/AbstractScopeSniff.php", - "CodeSniffer/Standards/AbstractVariableSniff.php", - "CodeSniffer/Standards/IncorrectPatternException.php", - "CodeSniffer/Standards/Generic/Sniffs/", - "CodeSniffer/Standards/MySource/Sniffs/", - "CodeSniffer/Standards/PEAR/Sniffs/", - "CodeSniffer/Standards/PSR1/Sniffs/", - "CodeSniffer/Standards/PSR2/Sniffs/", - "CodeSniffer/Standards/Squiz/Sniffs/", - "CodeSniffer/Standards/Zend/Sniffs/" - ] - }, "notification-url": "https://packagist.org/downloads/", "license": [ "BSD-3-Clause" @@ -177,12 +2008,183 @@ } ], "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "http://www.squizlabs.com/php-codesniffer", + "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", "keywords": [ "phpcs", "standards" ], - "time": "2016-01-19 23:39:10" + "time": "2020-08-10T04:50:15+00:00" + }, + { + "name": "symfony/polyfill-ctype", + "version": "v1.18.1", + "source": { + "type": "git", + "url": "https://github.com/symfony/polyfill-ctype.git", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", + "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", + "shasum": "" + }, + "require": { + "php": ">=5.3.3" + }, + "suggest": { + "ext-ctype": "For best performance" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.18-dev" + }, + "thanks": { + "name": "symfony/polyfill", + "url": "https://github.com/symfony/polyfill" + } + }, + "autoload": { + "psr-4": { + "Symfony\\Polyfill\\Ctype\\": "" + }, + "files": [ + "bootstrap.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Gert de Pagter", + "email": "BackEndTea@gmail.com" + }, + { + "name": "Symfony Community", + "homepage": "https://symfony.com/contributors" + } + ], + "description": "Symfony polyfill for ctype functions", + "homepage": "https://symfony.com", + "keywords": [ + "compatibility", + "ctype", + "polyfill", + "portable" + ], + "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-14T12:35:20+00:00" + }, + { + "name": "theseer/tokenizer", + "version": "1.2.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "75a63c33a8577608444246075ea0af0d052e452a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", + "reference": "75a63c33a8577608444246075ea0af0d052e452a", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2020-07-12T23:59:07+00:00" + }, + { + "name": "webmozart/assert", + "version": "1.9.1", + "source": { + "type": "git", + "url": "https://github.com/webmozart/assert.git", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", + "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", + "shasum": "" + }, + "require": { + "php": "^5.3.3 || ^7.0 || ^8.0", + "symfony/polyfill-ctype": "^1.8" + }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<3.9.1" + }, + "require-dev": { + "phpunit/phpunit": "^4.8.36 || ^7.5.13" + }, + "type": "library", + "autoload": { + "psr-4": { + "Webmozart\\Assert\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Assertions to validate method input/output with nice error messages.", + "keywords": [ + "assert", + "check", + "validate" + ], + "time": "2020-07-08T17:02:28+00:00" } ], "aliases": [], @@ -191,7 +2193,8 @@ "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.4.0" + "php": ">=5.6.0" }, - "platform-dev": [] + "platform-dev": [], + "plugin-api-version": "1.1.0" } diff --git a/lib/utils.php b/lib/utils.php deleted file mode 100644 index 4b1eb30a..00000000 --- a/lib/utils.php +++ /dev/null @@ -1,68 +0,0 @@ -

' . $message . '

'; - }; - if (call_user_func_array('current_user_can', (array) $capability)) { - add_action('admin_notices', function () use ($alert, $errors) { - array_map($alert, (array) $errors); - }); - } -} diff --git a/modules/clean-up.php b/modules/clean-up.php deleted file mode 100644 index 53d49260..00000000 --- a/modules/clean-up.php +++ /dev/null @@ -1,157 +0,0 @@ -'s - * Remove inline CSS and JS from WP emoji support - * Remove inline CSS used by Recent Comments widget - * Remove inline CSS used by posts with galleries - * Remove self-closing tag - * - * You can enable/disable this feature in functions.php (or app/setup.php if you're using Sage): - * add_theme_support('soil-clean-up'); - */ -function head_cleanup() { - // Originally from https://wpengineer.com/1438/wordpress-header/ - remove_action('wp_head', 'feed_links_extra', 3); - add_action('wp_head', 'ob_start', 1, 0); - add_action('wp_head', function () { - $pattern = '/.*' . preg_quote(esc_url(get_feed_link('comments_' . get_default_feed())), '/') . '.*[\r\n]+/'; - echo preg_replace($pattern, '', ob_get_clean()); - }, 3, 0); - remove_action('wp_head', 'rsd_link'); - remove_action('wp_head', 'wlwmanifest_link'); - remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10); - remove_action('wp_head', 'wp_generator'); - remove_action('wp_head', 'wp_shortlink_wp_head', 10); - remove_action('wp_head', 'print_emoji_detection_script', 7); - remove_action('admin_print_scripts', 'print_emoji_detection_script'); - remove_action('wp_print_styles', 'print_emoji_styles'); - remove_action('admin_print_styles', 'print_emoji_styles'); - remove_action('wp_head', 'wp_oembed_add_discovery_links'); - remove_action('wp_head', 'wp_oembed_add_host_js'); - remove_action('wp_head', 'rest_output_link_wp_head', 10); - remove_filter('the_content_feed', 'wp_staticize_emoji'); - remove_filter('comment_text_rss', 'wp_staticize_emoji'); - remove_filter('wp_mail', 'wp_staticize_emoji_for_email'); - add_filter('use_default_gallery_style', '__return_false'); - add_filter('emoji_svg_url', '__return_false'); - add_filter('show_recent_comments_widget_style', '__return_false'); -} -add_action('init', __NAMESPACE__ . '\\head_cleanup'); - -/** - * Remove the WordPress version from RSS feeds - */ -add_filter('the_generator', '__return_false'); - -/** - * Clean up language_attributes() used in tag - * - * Remove dir="ltr" - */ -function language_attributes() { - $attributes = []; - - if (is_rtl()) { - $attributes[] = 'dir="rtl"'; - } - - $lang = get_bloginfo('language'); - - if ($lang) { - $attributes[] = "lang=\"$lang\""; - } - - $output = implode(' ', $attributes); - $output = apply_filters('soil/language_attributes', $output); - - return $output; -} -add_filter('language_attributes', __NAMESPACE__ . '\\language_attributes'); - -/** - * Clean up output of stylesheet tags - */ -function clean_style_tag($input) { - preg_match_all("!!", $input, $matches); - if (empty($matches[2])) { - return $input; - } - // Only display media if it is meaningful - $media = $matches[3][0] !== '' && $matches[3][0] !== 'all' ? ' media="' . $matches[3][0] . '"' : ''; - return '' . "\n"; -} -add_filter('style_loader_tag', __NAMESPACE__ . '\\clean_style_tag'); - -/** - * Clean up output of - - - -Home - *
  • Sample PageHome
  • - * - * - * You can enable/disable this feature in functions.php (or app/setup.php if you're using Sage): - * add_theme_support('soil-nav-walker'); - */ -class NavWalker extends \Walker_Nav_Menu { - private $cpt; // Boolean, is current post a custom post type - private $archive; // Stores the archive page for current URL - - public function __construct() { - $cpt = get_post_type(); - $this->cpt = in_array($cpt, get_post_types(array('_builtin' => false))); - $this->archive = get_post_type_archive_link($cpt); - $this->is_search = is_search(); - } - - public function checkCurrent($classes) { - return preg_match('/(current[-_])|active/', $classes); - } - - // @codingStandardsIgnoreStart - public function display_element($element, &$children_elements, $max_depth, $depth = 0, $args, &$output) { - $element->is_subitem = ((!empty($children_elements[$element->ID]) && (($depth + 1) < $max_depth || ($max_depth === 0)))); - - if ($element->is_subitem) { - foreach ($children_elements[$element->ID] as $child) { - if ($child->current_item_parent || Utils\url_compare($this->archive, $child->url)) { - $element->classes[] = 'active'; - } - } - } - - $element->is_active = (!empty($element->url) && strpos($this->archive, $element->url)); - - if ($element->is_active && !$this->is_search) { - $element->classes[] = 'active'; - } - - parent::display_element($element, $children_elements, $max_depth, $depth, $args, $output); - } - // @codingStandardsIgnoreEnd - - public function cssClasses($classes, $item) { - $slug = sanitize_title($item->title); - - // Fix core `active` behavior for custom post types - if ($this->cpt) { - $classes = str_replace('current_page_parent', '', $classes); - - if ($this->archive && !$this->is_search) { - if (Utils\url_compare($this->archive, $item->url)) { - $classes[] = 'active'; - } - } - } - - // Remove most core classes - $classes = preg_replace('/(current(-menu-|[-_]page[-_])(item|parent|ancestor))/', 'active', $classes); - $classes = preg_replace('/^((menu|page)[-_\w+]+)+/', '', $classes); - - // Re-add core `menu-item` class - $classes[] = 'menu-item'; - - // Re-add core `menu-item-has-children` class on parent elements - if ($item->is_subitem) { - $classes[] = 'menu-item-has-children'; - } - - // Add `menu-` class - $classes[] = 'menu-' . $slug; - - $classes = array_unique($classes); - $classes = array_map('trim', $classes); - - return array_filter($classes); - } - - public function walk($elements, $max_depth, ...$args) { - // Add filters - add_filter('nav_menu_css_class', array($this, 'cssClasses'), 10, 2); - add_filter('nav_menu_item_id', '__return_null'); - - // Perform usual walk - $output = call_user_func_array(['parent', 'walk'], func_get_args()); - - // Unregister filters - remove_filter('nav_menu_css_class', [$this, 'cssClasses']); - remove_filter('nav_menu_item_id', '__return_null'); - - // Return result - return $output; - } -} - -/** - * Clean up wp_nav_menu_args - * - * Remove the container - * Remove the id="" on nav menu items - */ -function nav_menu_args($args = '') { - $nav_menu_args = []; - $nav_menu_args['container'] = false; - - if (!$args['items_wrap']) { - $nav_menu_args['items_wrap'] = ''; - } - - if (!$args['walker']) { - $nav_menu_args['walker'] = new NavWalker(); - } - - return array_merge($args, $nav_menu_args); -} -add_filter('wp_nav_menu_args', __NAMESPACE__ . '\\nav_menu_args'); diff --git a/modules/nice-search.php b/modules/nice-search.php deleted file mode 100644 index c5ac4aaa..00000000 --- a/modules/nice-search.php +++ /dev/null @@ -1,30 +0,0 @@ -get_search_permastruct()) { - return; - } - - $search_base = $wp_rewrite->search_base; - if (is_search() && !is_admin() && strpos($_SERVER['REQUEST_URI'], "/{$search_base}/") === false && strpos($_SERVER['REQUEST_URI'], '&') === false) { - wp_redirect(get_search_link()); - exit(); - } -} -add_action('template_redirect', __NAMESPACE__ . '\\redirect'); - -function rewrite($url) { - return str_replace('/?s=', '/search/', $url); -} -add_filter('wpseo_json_ld_search_url', __NAMESPACE__ . '\\rewrite'); diff --git a/modules/relative-urls.php b/modules/relative-urls.php deleted file mode 100644 index bfaf15bf..00000000 --- a/modules/relative-urls.php +++ /dev/null @@ -1,58 +0,0 @@ - $src) { - $sources[$source]['url'] = \Roots\Soil\Utils\root_relative_url($src['url']); - } - return $sources; -}); - -/** - * Compatibility with The SEO Framework - */ -add_action('the_seo_framework_do_before_output', function () { - remove_filter('wp_get_attachment_url', 'Roots\\Soil\\Utils\\root_relative_url'); -}); -add_action('the_seo_framework_do_after_output', function () { - add_filter('wp_get_attachment_url', 'Roots\\Soil\\Utils\\root_relative_url'); -}); diff --git a/phpcs.xml b/phpcs.xml deleted file mode 100644 index 84ab8d9b..00000000 --- a/phpcs.xml +++ /dev/null @@ -1,30 +0,0 @@ - - - Roots Coding Standards - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 00000000..b058c4c0 --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,34 @@ + + + + + ./ + + + ./resources + ./vendor + ./tests + + + + + + ./tests/Unit + + + ./tests/Feature + + + diff --git a/resources/views/google-analytics.php b/resources/views/google-analytics.php new file mode 100644 index 00000000..41129bf0 --- /dev/null +++ b/resources/views/google-analytics.php @@ -0,0 +1,21 @@ + + + + diff --git a/soil.php b/soil.php index 19e330d2..ea135064 100644 --- a/soil.php +++ b/soil.php @@ -1,72 +1,24 @@ options; - } - if (substr($module, 0, 5) !== 'soil-') { - return self::get('soil-' . $module); - } - return []; - } - - protected function __construct($options) { - $this->set($options); - } - - public function set($options) { - $this->options = $options; - } -} - -require_once __DIR__ . '/lib/utils.php'; - -function load_modules() { - global $_wp_theme_features; - - // Skip loading modules in the admin but allow in ajax actions. - if ((is_admin() && !wp_doing_ajax())) { - return; - } - - foreach (glob(__DIR__ . '/modules/*.php') as $file) { - $feature = 'soil-' . basename($file, '.php'); - if (isset($_wp_theme_features[$feature])) { - Options::init($feature, $_wp_theme_features[$feature]); - require_once $file; - } - } -} -add_action('after_setup_theme', __NAMESPACE__ . '\\load_modules', 100); + add_action('after_setup_theme', new Soil($modules), 100); +}); diff --git a/src/DOM.php b/src/DOM.php new file mode 100644 index 00000000..d2bb2f5b --- /dev/null +++ b/src/DOM.php @@ -0,0 +1,82 @@ +doc = new DOMDocument(); + + // use LibXML internal error handler to prevent errors from bubbling to PHP + libxml_use_internal_errors(true); + $this->doc->loadHTML('' . $html, \LIBXML_HTML_NOIMPLIED | \LIBXML_HTML_NODEFDTD); + libxml_clear_errors(); // clear all libxml errors + } + + /** + * Executes callback on each DOMElement. + * + * @param callable $callback + * @return DOM + */ + public function each($callback) + { + foreach ($this->xpath('//*') as $node) { + $callback($node); + } + + return $this; + } + + /** + * Evaluates the given XPath expression + * + * @param string $expression The XPath expression to execute. + * @return DOMNodeList + */ + public function xpath($expression) + { + return (new DOMXPath($this->doc))->query($expression); + } + + /** + * Save the document HTML. + * + * @return string + */ + public function html() + { + // Note: 23 = strlen('') + return trim(substr($this->doc->saveHTML(), 23)); + } + + /** {@inheritdoc} */ + public function __call($name, $arguments) + { + return $this->doc->{$name}(...$arguments); + } + + /** {@inheritdoc} */ + public function __get($name) + { + return $this->doc->{$name}; + } +} diff --git a/src/Exceptions/LifecycleException.php b/src/Exceptions/LifecycleException.php new file mode 100644 index 00000000..dd9005a1 --- /dev/null +++ b/src/Exceptions/LifecycleException.php @@ -0,0 +1,10 @@ +condition()) { + return; + } + + $this->handle(); + } + + /** + * Module handle. + * + * @return void + */ + abstract protected function handle(); + + /** + * Register the module. + * + * This attaches the module to its hook. + * + * @return string + * @throws LifecycleException + */ + public function register() + { + if ($this->loaded) { + throw new LifecycleException( + sprintf('Module %s has already loaded.', get_class($this)) + ); + } + + if (did_action($this->hook) || doing_action($this->hook)) { + throw new LifecycleException( + sprintf('Hook %s has already been fired.', $this->hook) + ); + } + + $this->loaded = add_action($this->hook, $this); + } + + /** + * Internal hook handler + * + * @param string $hook Name of the hook + * @param string $method Method of $this to be executed + * @param int $priority Hook priority + * @param int $numArgs Number of arguments supported by the $method + * @return void + */ + protected function filter($hook, $method, $priority = 10, $numArgs = 1) + { + add_filter($hook, [$this, $method], $priority, $numArgs); + } + + /** + * Internal hook handler + * + * @param string[] $hook Name of the hook + * @param string $method Method of $this to be executed + * @param int $priority Hook priority + * @param int $numArgs Number of arguments supported by the $method + * @return void + */ + protected function filters($hooks, $method, $priority = 10, $numArgs = 1) + { + $count = count($hooks); + array_map( + [$this, 'filter'], + (array) $hooks, + array_fill(0, $count, $method), + array_fill(0, $count, $priority), + array_fill(0, $count, $numArgs) + ); + } + + /** + * Condition under which the module is loaded. + * + * By default, modules are disabled in admin panel. + * + * @return bool + */ + protected function condition() + { + $features = (array) $GLOBALS['_wp_theme_features']['soil'][0] ?? []; + + return apply_filters( + 'soil/load-module/' . $this->provides(), + in_array($this->provides(), $features) && (!is_admin() || wp_doing_ajax()) + ); + } + + /** + * Name of feature provided by the module. + * + * @return string + */ + public function provides() + { + if (! $this->name) { + $this->name = strtolower(preg_replace( + ['/([a-z\d])([A-Z])/', '/([^-])([A-Z][a-z])/'], + '$1-$2', + basename(strtr(static::class, ['\\' => '/', 'Module' => ''])) + )); + } + + return $this->name; + } + + /** + * Render the specified view. + * + * @param string $view + * @param array $data + * @return string + */ + protected function render($view = null, $data = []) + { + if (is_array($view) && empty($data)) { + $data = $view; + $view = null; + } + + $view = $view ?? ($this->provides() . '.php'); + extract($data); + ob_start(); + include __DIR__ . "/../../resources/views/{$view}"; + return ob_get_clean(); + } +} diff --git a/src/Modules/CleanUpModule.php b/src/Modules/CleanUpModule.php new file mode 100644 index 00000000..65194dc8 --- /dev/null +++ b/src/Modules/CleanUpModule.php @@ -0,0 +1,261 @@ +'s + * Remove inline CSS and JS from WP emoji support + * Remove inline CSS used by Recent Comments widget + * Remove inline CSS used by posts with galleries + * Remove self-closing tag + */ +class CleanUpModule extends AbstractModule +{ + /** + * Name of the module. + * + * @var string + */ + protected $name = 'clean-up'; + + /** + * Module handle. + * + * @return void + */ + public function handle() + { + $this->filter('init', 'headCleanup'); + $this->filter('language_attributes', 'languageAttributes'); + $this->filter('body_class', 'bodyClass'); + $this->filter('embed_oembed_html', 'embedWrap'); + $this->filter('get_bloginfo_rss', 'removeDefaultSiteTagline'); + + $this->filters([ + 'get_avatar', // + 'comment_id_fields', // + 'post_thumbnail_html' // + ], 'removeSelfClosingTags'); + + if (class_exists(DOMDocument::class)) { + $this->filter('style_loader_tag', 'cleanStylesheetLinks'); + $this->filter('script_loader_tag', 'cleanScriptTags'); + } + + $this->removeCommentsFeed(); + $this->removeWordPressVersionFromRssFeeds(); + } + + /** + * Clean up output section. + * + * @internal Used by `init` + * + * @link https://wpengineer.com/1438/wordpress-header/ + * + * @return void + */ + public function headCleanup() + { + remove_action('wp_head', 'feed_links_extra', 3); + remove_action('wp_head', 'rsd_link'); + remove_action('wp_head', 'wlwmanifest_link'); + remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10); + remove_action('wp_head', 'wp_generator'); + remove_action('wp_head', 'wp_shortlink_wp_head', 10); + remove_action('wp_head', 'print_emoji_detection_script', 7); + remove_action('admin_print_scripts', 'print_emoji_detection_script'); + remove_action('wp_print_styles', 'print_emoji_styles'); + remove_action('admin_print_styles', 'print_emoji_styles'); + remove_action('wp_head', 'wp_oembed_add_discovery_links'); + remove_action('wp_head', 'wp_oembed_add_host_js'); + remove_action('wp_head', 'rest_output_link_wp_head', 10); + remove_filter('the_content_feed', 'wp_staticize_emoji'); + remove_filter('comment_text_rss', 'wp_staticize_emoji'); + remove_filter('wp_mail', 'wp_staticize_emoji_for_email'); + add_filter('use_default_gallery_style', '__return_false'); + add_filter('emoji_svg_url', '__return_false'); + add_filter('show_recent_comments_widget_style', '__return_false'); + } + + /** + * Remove comments feed from . + * + * @return void + */ + public function removeCommentsFeed() + { + add_action('wp_head', 'ob_start', 1, 0); + add_action('wp_head', function () { + $pattern = '/.*' . preg_quote(esc_url(get_feed_link('comments_' . get_default_feed())), '/') . '.*[\r\n]+/'; + echo preg_replace($pattern, '', ob_get_clean()); + }, 3, 0); + } + + /** + * Remove the WordPress version from RSS feeds. + * + * @return void + */ + public function removeWordPressVersionFromRssFeeds() + { + add_filter('the_generator', '__return_false'); + } + + /** + * Clean up language_attributes() used in tag + * + * Remove dir="ltr" + * + * @internal Used by `language_attributes` + * + * @return void + */ + public function languageAttributes() + { + $attributes = []; + + if (is_rtl()) { + $attributes[] = 'dir="rtl"'; + } + + $lang = get_bloginfo('language'); + + if ($lang) { + $attributes[] = "lang=\"{$lang}\""; + } + + return implode(' ', $attributes); + } + + /** + * Clean up output of stylesheet tags + * + * @internal Used by `style_loader_tag` + * + * @param string $html + * @return string + */ + public function cleanStylesheetLinks($html) + { + return (new DOM($html))->each(static function ($link) { + $link->removeAttribute('type'); + $link->removeAttribute('id'); + + if (($media = $link->getAttribute('media')) && $media !== 'all') { + return; + } + + $link->removeAttribute('media'); + })->html(); + } + + /** + * Clean up output of "; + + $this->assertEquals( + '', + $module->cleanScriptTags($script) + ); + } + + /** @test */ + public function it_should_clean_body_classes_for_front_page() + { + $module = new CleanUpModule(); + stubs([ + 'is_single' => false, + 'is_page' => true, + 'is_front_page' => true, + 'get_option' => '4', + 'get_permalink' => 'http://example.test/' + ]); + $classes = ['foobar', 'page-template-default', 'page-id-4']; + + $this->assertEquals(['foobar'], $module->bodyClass($classes)); + } + + /** @test */ + public function it_should_clean_body_classes_for_pages() + { + $module = new CleanUpModule(); + stubs([ + 'is_single' => false, + 'is_page' => true, + 'is_front_page' => false, + 'get_permalink' => 'http://example.test/about-us' + ]); + $classes = ['foobar', 'page-template-default']; + + $this->assertEquals(['foobar', 'about-us'], $module->bodyClass($classes)); + } + + /** @test */ + public function it_should_clean_body_classes_for_posts() + { + $module = new CleanUpModule(); + stubs([ + 'is_single' => true, + 'is_page' => false, + 'is_front_page' => false, + 'get_permalink' => 'http://example.test/my-first-blog-post' + ]); + $classes = ['foobar', 'page-template-default']; + + $this->assertEquals(['foobar', 'my-first-blog-post'], $module->bodyClass($classes)); + } + + /** @test */ + public function it_should_remove_default_site_tagline() + { + $module = new CleanUpModule(); + + $this->assertEquals('', $module->removeDefaultSiteTagline('Just another WordPress site')); + $this->assertEquals('foobar', $module->removeDefaultSiteTagline('foobar')); + } + + /** @test */ + public function it_should_remove_self_closing_tags() + { + $module = new CleanUpModule(); + + $this->assertEquals('', $module->removeSelfClosingTags('')); + } +} diff --git a/tests/Unit/Modules/RelativeUrlsModuleTest.php b/tests/Unit/Modules/RelativeUrlsModuleTest.php new file mode 100644 index 00000000..79c190d6 --- /dev/null +++ b/tests/Unit/Modules/RelativeUrlsModuleTest.php @@ -0,0 +1,62 @@ + false, + 'network_home_url' => 'https://example.test/' + ]); + + $this->assertEquals('/about-us', $module->relativeUrl('https://example.test/about-us')); + $this->assertEquals('https://google.com/about', $module->relativeUrl('https://google.com/about')); + + $this->assertEquals('/about-us', $module->relativeUrl('//example.test/about-us')); + $this->assertEquals('//google.com/about', $module->relativeUrl('//google.com/about')); + } + + /** @test */ + public function it_should_never_return_a_relative_url_for_rss_feed() + { + $module = new RelativeUrlsModule(); + stubs([ + 'is_feed' => true, + 'network_home_url' => 'https://example.test/' + ]); + + $this->assertEquals('https://example.test/about-us', $module->relativeUrl('https://example.test/about-us')); + $this->assertEquals('//example.test/about-us', $module->relativeUrl('//example.test/about-us')); + } + + /** @test */ + public function it_should_make_all_srcset_urls_relative() + { + $module = new RelativeUrlsModule(); + stubs([ + 'is_feed' => false, + 'network_home_url' => 'https://example.test/' + ]); + + $sources = [ + ['url' => 'https://example.test/app/uploads/example.jpg'], + ['url' => 'https://example.test/app/uploads/example-200x200.jpg'], + ['url' => 'https://example.test/app/uploads/example-600x600.jpg'], + ]; + + $this->assertEquals([ + ['url' => '/app/uploads/example.jpg'], + ['url' => '/app/uploads/example-200x200.jpg'], + ['url' => '/app/uploads/example-600x600.jpg'], + ], $module->imageSrcset($sources)); + } +} diff --git a/tests/Unit/SoilTest.php b/tests/Unit/SoilTest.php new file mode 100644 index 00000000..2bded6a5 --- /dev/null +++ b/tests/Unit/SoilTest.php @@ -0,0 +1,53 @@ +shouldReceive('register') + ->once() + ->withNoArgs(); + + $soil(); + } + + /** @test */ + public function it_should_fire_init_hook_when_invoked() + { + $module = StubModule::class; + $soil = new Soil([$module]); + + $soil(); + + $this->assertEquals(1, did_action('soil/init')); + } + + /** @test */ + public function it_should_discover_modules() + { + $modules = Soil::discoverModules(fixture('modules/*.php'), 'Roots\Soil\Tests\Fixtures\Modules'); + + $this->assertCount(3, $modules); + $this->assertSame([ + CustomHookModule::class, + CustomNameModule::class, + StubModule::class + ], $modules); + } +} diff --git a/tests/__fixtures__/modules/CustomHookModule.php b/tests/__fixtures__/modules/CustomHookModule.php new file mode 100644 index 00000000..bd9a6b54 --- /dev/null +++ b/tests/__fixtures__/modules/CustomHookModule.php @@ -0,0 +1,8 @@ + Date: Fri, 21 Aug 2020 07:48:40 -0700 Subject: [PATCH 02/22] dev(deps): remove composer.lock --- .gitignore | 1 + composer.lock | 2200 ------------------------------------------------- 2 files changed, 1 insertion(+), 2200 deletions(-) delete mode 100644 composer.lock diff --git a/.gitignore b/.gitignore index 22d0d82f..7579f743 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ vendor +composer.lock diff --git a/composer.lock b/composer.lock deleted file mode 100644 index 55e5d968..00000000 --- a/composer.lock +++ /dev/null @@ -1,2200 +0,0 @@ -{ - "_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": "e6d5094ef874ad50174bbb09c6e5e1a2", - "packages": [], - "packages-dev": [ - { - "name": "antecedent/patchwork", - "version": "2.1.12", - "source": { - "type": "git", - "url": "https://github.com/antecedent/patchwork.git", - "reference": "b98e046dd4c0acc34a0846604f06f6111654d9ea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/antecedent/patchwork/zipball/b98e046dd4c0acc34a0846604f06f6111654d9ea", - "reference": "b98e046dd4c0acc34a0846604f06f6111654d9ea", - "shasum": "" - }, - "require": { - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": ">=4" - }, - "type": "library", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Ignas Rudaitis", - "email": "ignas.rudaitis@gmail.com" - } - ], - "description": "Method redefinition (monkey-patching) functionality for PHP.", - "homepage": "http://patchwork2.org/", - "keywords": [ - "aop", - "aspect", - "interception", - "monkeypatching", - "redefinition", - "runkit", - "testing" - ], - "time": "2019-12-22T17:52:09+00:00" - }, - { - "name": "brain/monkey", - "version": "2.4.0", - "source": { - "type": "git", - "url": "https://github.com/Brain-WP/BrainMonkey.git", - "reference": "b3ce8b619c26db6abd01b9dcfd6a2c0254060956" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/b3ce8b619c26db6abd01b9dcfd6a2c0254060956", - "reference": "b3ce8b619c26db6abd01b9dcfd6a2c0254060956", - "shasum": "" - }, - "require": { - "antecedent/patchwork": "^2.0", - "mockery/mockery": ">=0.9 <2", - "php": ">=5.6.0" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4", - "phpcompatibility/php-compatibility": "^9.3.0", - "phpunit/phpunit": "^5.7.9 || ^6.0 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-version/1": "1.x-dev", - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "psr-4": { - "Brain\\Monkey\\": "src/" - }, - "files": [ - "inc/api.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Giuseppe Mazzapica", - "email": "giuseppe.mazzapica@gmail.com", - "homepage": "https://gmazzap.me", - "role": "Developer" - } - ], - "description": "Mocking utility for PHP functions and WordPress plugin API", - "keywords": [ - "Monkey Patching", - "interception", - "mock", - "mock functions", - "mockery", - "patchwork", - "redefinition", - "runkit", - "test", - "testing" - ], - "time": "2019-11-24T16:03:21+00:00" - }, - { - "name": "doctrine/instantiator", - "version": "1.3.1", - "source": { - "type": "git", - "url": "https://github.com/doctrine/instantiator.git", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/f350df0268e904597e3bd9c4685c53e0e333feea", - "reference": "f350df0268e904597e3bd9c4685c53e0e333feea", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "require-dev": { - "doctrine/coding-standard": "^6.0", - "ext-pdo": "*", - "ext-phar": "*", - "phpbench/phpbench": "^0.13", - "phpstan/phpstan-phpunit": "^0.11", - "phpstan/phpstan-shim": "^0.11", - "phpunit/phpunit": "^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.2.x-dev" - } - }, - "autoload": { - "psr-4": { - "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Marco Pivetta", - "email": "ocramius@gmail.com", - "homepage": "http://ocramius.github.com/" - } - ], - "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", - "homepage": "https://www.doctrine-project.org/projects/instantiator.html", - "keywords": [ - "constructor", - "instantiate" - ], - "funding": [ - { - "url": "https://www.doctrine-project.org/sponsorship.html", - "type": "custom" - }, - { - "url": "https://www.patreon.com/phpdoctrine", - "type": "patreon" - }, - { - "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", - "type": "tidelift" - } - ], - "time": "2020-05-29T17:27:14+00:00" - }, - { - "name": "hamcrest/hamcrest-php", - "version": "v2.0.1", - "source": { - "type": "git", - "url": "https://github.com/hamcrest/hamcrest-php.git", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", - "shasum": "" - }, - "require": { - "php": "^5.3|^7.0|^8.0" - }, - "replace": { - "cordoval/hamcrest-php": "*", - "davedevelopment/hamcrest-php": "*", - "kodova/hamcrest-php": "*" - }, - "require-dev": { - "phpunit/php-file-iterator": "^1.4 || ^2.0", - "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.1-dev" - } - }, - "autoload": { - "classmap": [ - "hamcrest" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "description": "This is the PHP port of Hamcrest Matchers", - "keywords": [ - "test" - ], - "time": "2020-07-09T08:09:16+00:00" - }, - { - "name": "mockery/mockery", - "version": "1.4.2", - "source": { - "type": "git", - "url": "https://github.com/mockery/mockery.git", - "reference": "20cab678faed06fac225193be281ea0fddb43b93" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mockery/mockery/zipball/20cab678faed06fac225193be281ea0fddb43b93", - "reference": "20cab678faed06fac225193be281ea0fddb43b93", - "shasum": "" - }, - "require": { - "hamcrest/hamcrest-php": "^2.0.1", - "lib-pcre": ">=7.0", - "php": "^7.3 || ^8.0" - }, - "conflict": { - "phpunit/phpunit": "<8.0" - }, - "require-dev": { - "phpunit/phpunit": "^8.5 || ^9.3" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.4.x-dev" - } - }, - "autoload": { - "psr-0": { - "Mockery": "library/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Pádraic Brady", - "email": "padraic.brady@gmail.com", - "homepage": "http://blog.astrumfutura.com" - }, - { - "name": "Dave Marshall", - "email": "dave.marshall@atstsolutions.co.uk", - "homepage": "http://davedevelopment.co.uk" - } - ], - "description": "Mockery is a simple yet flexible PHP mock object framework", - "homepage": "https://github.com/mockery/mockery", - "keywords": [ - "BDD", - "TDD", - "library", - "mock", - "mock objects", - "mockery", - "stub", - "test", - "test double", - "testing" - ], - "time": "2020-08-11T18:10:13+00:00" - }, - { - "name": "myclabs/deep-copy", - "version": "1.10.1", - "source": { - "type": "git", - "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "reference": "969b211f9a51aa1f6c01d1d2aef56d3bd91598e5", - "shasum": "" - }, - "require": { - "php": "^7.1 || ^8.0" - }, - "replace": { - "myclabs/deep-copy": "self.version" - }, - "require-dev": { - "doctrine/collections": "^1.0", - "doctrine/common": "^2.6", - "phpunit/phpunit": "^7.1" - }, - "type": "library", - "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, - "files": [ - "src/DeepCopy/deep_copy.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "description": "Create deep copies (clones) of your objects", - "keywords": [ - "clone", - "copy", - "duplicate", - "object", - "object graph" - ], - "funding": [ - { - "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", - "type": "tidelift" - } - ], - "time": "2020-06-29T13:22:24+00:00" - }, - { - "name": "nikic/php-parser", - "version": "v4.8.0", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/8c58eb4cd4f3883f82611abeac2efbc3dbed787e", - "reference": "8c58eb4cd4f3883f82611abeac2efbc3dbed787e", - "shasum": "" - }, - "require": { - "ext-tokenizer": "*", - "php": ">=7.0" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.6", - "phpunit/phpunit": "^6.5 || ^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.8-dev" - } - }, - "autoload": { - "psr-4": { - "PhpParser\\": "lib/PhpParser" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Nikita Popov" - } - ], - "description": "A PHP parser written in PHP", - "keywords": [ - "parser", - "php" - ], - "time": "2020-08-09T10:23:20+00:00" - }, - { - "name": "phar-io/manifest", - "version": "2.0.1", - "source": { - "type": "git", - "url": "https://github.com/phar-io/manifest.git", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/manifest/zipball/85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "reference": "85265efd3af7ba3ca4b2a2c34dbfc5788dd29133", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-phar": "*", - "ext-xmlwriter": "*", - "phar-io/version": "^3.0.1", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0.x-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", - "time": "2020-06-27T14:33:11+00:00" - }, - { - "name": "phar-io/version", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/phar-io/version.git", - "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/c6bb6825def89e0a32220f88337f8ceaf1975fa0", - "reference": "c6bb6825def89e0a32220f88337f8ceaf1975fa0", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - }, - { - "name": "Sebastian Heuer", - "email": "sebastian@phpeople.de", - "role": "Developer" - }, - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "Developer" - } - ], - "description": "Library for handling version information and constraints", - "time": "2020-06-27T14:39:04+00:00" - }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.2.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d870572532cd70bc3fab58f2e23ad423c8404c44", - "reference": "d870572532cd70bc3fab58f2e23ad423c8404c44", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2020-08-15T11:14:08+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e878a14a65245fbe78f8080eba03b47c3b705651", - "reference": "e878a14a65245fbe78f8080eba03b47c3b705651", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "time": "2020-06-27T10:12:23+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "1.11.1", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/b20034be5efcdab4fb60ca3a29cba2949aead160", - "reference": "b20034be5efcdab4fb60ca3a29cba2949aead160", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2", - "phpdocumentor/reflection-docblock": "^5.0", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0", - "phpunit/phpunit": "^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.11.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "time": "2020-07-08T12:44:21+00:00" - }, - { - "name": "phpunit/php-code-coverage", - "version": "9.1.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/4422fca28c3634e2de8c7c373af97a104dd1a45f", - "reference": "4422fca28c3634e2de8c7c373af97a104dd1a45f", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-libxml": "*", - "ext-xmlwriter": "*", - "nikic/php-parser": "^4.8", - "php": "^7.3 || ^8.0", - "phpunit/php-file-iterator": "^3.0.3", - "phpunit/php-text-template": "^2.0.2", - "sebastian/code-unit-reverse-lookup": "^2.0.2", - "sebastian/complexity": "^2.0", - "sebastian/environment": "^5.1.2", - "sebastian/lines-of-code": "^1.0", - "sebastian/version": "^3.0.1", - "theseer/tokenizer": "^1.2.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-pcov": "*", - "ext-xdebug": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.", - "homepage": "https://github.com/sebastianbergmann/php-code-coverage", - "keywords": [ - "coverage", - "testing", - "xunit" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-08-13T15:04:53+00:00" - }, - { - "name": "phpunit/php-file-iterator", - "version": "3.0.4", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/25fefc5b19835ca653877fe081644a3f8c1d915e", - "reference": "25fefc5b19835ca653877fe081644a3f8c1d915e", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "FilterIterator implementation that filters files based on a list of suffixes.", - "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", - "keywords": [ - "filesystem", - "iterator" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-07-11T05:18:21+00:00" - }, - { - "name": "phpunit/php-invoker", - "version": "3.1.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "7a85b66acc48cacffdf87dadd3694e7123674298" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/7a85b66acc48cacffdf87dadd3694e7123674298", - "reference": "7a85b66acc48cacffdf87dadd3694e7123674298", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^9.0" - }, - "suggest": { - "ext-pcntl": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.1-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", - "keywords": [ - "process" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-08-06T07:04:15+00:00" - }, - { - "name": "phpunit/php-text-template", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", - "reference": "6ff9c8ea4d3212b88fcf74e25e516e2c51c99324", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", - "keywords": [ - "template" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T11:55:37+00:00" - }, - { - "name": "phpunit/php-timer", - "version": "5.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/cc49734779cbb302bf51a44297dab8c4bbf941e7", - "reference": "cc49734779cbb302bf51a44297dab8c4bbf941e7", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", - "keywords": [ - "timer" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T11:58:13+00:00" - }, - { - "name": "phpunit/phpunit", - "version": "9.3.7", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c638a0cac77347980352485912de48c99b42ad00" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c638a0cac77347980352485912de48c99b42ad00", - "reference": "c638a0cac77347980352485912de48c99b42ad00", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.3.1", - "ext-dom": "*", - "ext-json": "*", - "ext-libxml": "*", - "ext-mbstring": "*", - "ext-xml": "*", - "ext-xmlwriter": "*", - "myclabs/deep-copy": "^1.10.1", - "phar-io/manifest": "^2.0.1", - "phar-io/version": "^3.0.2", - "php": "^7.3 || ^8.0", - "phpspec/prophecy": "^1.11.1", - "phpunit/php-code-coverage": "^9.1.1", - "phpunit/php-file-iterator": "^3.0.4", - "phpunit/php-invoker": "^3.1", - "phpunit/php-text-template": "^2.0.2", - "phpunit/php-timer": "^5.0.1", - "sebastian/code-unit": "^1.0.5", - "sebastian/comparator": "^4.0.3", - "sebastian/diff": "^4.0.2", - "sebastian/environment": "^5.1.2", - "sebastian/exporter": "^4.0.2", - "sebastian/global-state": "^5.0", - "sebastian/object-enumerator": "^4.0.2", - "sebastian/resource-operations": "^3.0.2", - "sebastian/type": "^2.2.1", - "sebastian/version": "^3.0.1" - }, - "require-dev": { - "ext-pdo": "*", - "phpspec/prophecy-phpunit": "^2.0.1" - }, - "suggest": { - "ext-soap": "*", - "ext-xdebug": "*" - }, - "bin": [ - "phpunit" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "9.3-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ], - "files": [ - "src/Framework/Assert/Functions.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "The PHP Unit Testing framework.", - "homepage": "https://phpunit.de/", - "keywords": [ - "phpunit", - "testing", - "xunit" - ], - "funding": [ - { - "url": "https://phpunit.de/donate.html", - "type": "custom" - }, - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-08-11T15:36:12+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "1.0.5", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "c1e2df332c905079980b119c4db103117e5e5c90" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/c1e2df332c905079980b119c4db103117e5e5c90", - "reference": "c1e2df332c905079980b119c4db103117e5e5c90", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:50:45+00:00" - }, - { - "name": "sebastian/code-unit-reverse-lookup", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/ee51f9bb0c6d8a43337055db3120829fa14da819", - "reference": "ee51f9bb0c6d8a43337055db3120829fa14da819", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Looks up which function or method a line of code belongs to", - "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:04:00+00:00" - }, - { - "name": "sebastian/comparator", - "version": "4.0.3", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", - "reference": "dcc580eadfaa4e7f9d2cf9ae1922134ea962e14f", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "sebastian/diff": "^4.0", - "sebastian/exporter": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@2bepublished.at" - } - ], - "description": "Provides the functionality to compare PHP values for equality", - "homepage": "https://github.com/sebastianbergmann/comparator", - "keywords": [ - "comparator", - "compare", - "equality" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:05:46+00:00" - }, - { - "name": "sebastian/complexity", - "version": "2.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "33fcd6a26656c6546f70871244ecba4b4dced097" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/33fcd6a26656c6546f70871244ecba4b4dced097", - "reference": "33fcd6a26656c6546f70871244ecba4b4dced097", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.7", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-07-25T14:01:34+00:00" - }, - { - "name": "sebastian/diff", - "version": "4.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", - "reference": "1e90b4cf905a7d06c420b1d2e9d11a4dc8a13113", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0", - "symfony/process": "^4.2 || ^5" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Kore Nordmann", - "email": "mail@kore-nordmann.de" - } - ], - "description": "Diff implementation", - "homepage": "https://github.com/sebastianbergmann/diff", - "keywords": [ - "diff", - "udiff", - "unidiff", - "unified diff" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-30T04:46:02+00:00" - }, - { - "name": "sebastian/environment", - "version": "5.1.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", - "reference": "0a757cab9d5b7ef49a619f1143e6c9c1bc0fe9d2", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "suggest": { - "ext-posix": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "http://www.github.com/sebastianbergmann/environment", - "keywords": [ - "Xdebug", - "environment", - "hhvm" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:07:24+00:00" - }, - { - "name": "sebastian/exporter", - "version": "4.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "571d721db4aec847a0e59690b954af33ebf9f023" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/571d721db4aec847a0e59690b954af33ebf9f023", - "reference": "571d721db4aec847a0e59690b954af33ebf9f023", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-mbstring": "*", - "phpunit/phpunit": "^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Volker Dusch", - "email": "github@wallbash.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - }, - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "http://www.github.com/sebastianbergmann/exporter", - "keywords": [ - "export", - "exporter" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:08:55+00:00" - }, - { - "name": "sebastian/global-state", - "version": "5.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "22ae663c951bdc39da96603edc3239ed3a299097" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/22ae663c951bdc39da96603edc3239ed3a299097", - "reference": "22ae663c951bdc39da96603edc3239ed3a299097", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "ext-dom": "*", - "phpunit/phpunit": "^9.3" - }, - "suggest": { - "ext-uopz": "*" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Snapshotting of global state", - "homepage": "http://www.github.com/sebastianbergmann/global-state", - "keywords": [ - "global state" - ], - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-08-07T04:09:03+00:00" - }, - { - "name": "sebastian/lines-of-code", - "version": "1.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/e02bf626f404b5daec382a7b8a6a4456e49017e5", - "reference": "e02bf626f404b5daec382a7b8a6a4456e49017e5", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^4.6", - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-07-22T18:33:42+00:00" - }, - { - "name": "sebastian/object-enumerator", - "version": "4.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/074fed2d0a6d08e1677dd8ce9d32aecb384917b8", - "reference": "074fed2d0a6d08e1677dd8ce9d32aecb384917b8", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0", - "sebastian/object-reflector": "^2.0", - "sebastian/recursion-context": "^4.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:11:32+00:00" - }, - { - "name": "sebastian/object-reflector", - "version": "2.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "127a46f6b057441b201253526f81d5406d6c7840" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/127a46f6b057441b201253526f81d5406d6c7840", - "reference": "127a46f6b057441b201253526f81d5406d6c7840", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:12:55+00:00" - }, - { - "name": "sebastian/recursion-context", - "version": "4.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/062231bf61d2b9448c4fa5a7643b5e1829c11d63", - "reference": "062231bf61d2b9448c4fa5a7643b5e1829c11d63", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" - } - ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:14:17+00:00" - }, - { - "name": "sebastian/resource-operations", - "version": "3.0.2", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "0653718a5a629b065e91f774595267f8dc32e213" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/0653718a5a629b065e91f774595267f8dc32e213", - "reference": "0653718a5a629b065e91f774595267f8dc32e213", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de" - } - ], - "description": "Provides a list of PHP built-in functions that operate on resources", - "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:16:22+00:00" - }, - { - "name": "sebastian/type", - "version": "2.2.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/type.git", - "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/86991e2b33446cd96e648c18bcdb1e95afb2c05a", - "reference": "86991e2b33446cd96e648c18bcdb1e95afb2c05a", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.2" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "2.2-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the types of the PHP type system", - "homepage": "https://github.com/sebastianbergmann/type", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-07-05T08:31:53+00:00" - }, - { - "name": "sebastian/version", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/version.git", - "reference": "626586115d0ed31cb71483be55beb759b5af5a3c" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/626586115d0ed31cb71483be55beb759b5af5a3c", - "reference": "626586115d0ed31cb71483be55beb759b5af5a3c", - "shasum": "" - }, - "require": { - "php": "^7.3 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library that helps with managing the version number of Git-hosted PHP projects", - "homepage": "https://github.com/sebastianbergmann/version", - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2020-06-26T12:18:43+00:00" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.5.6", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "e97627871a7eab2f70e59166072a6b767d5834e0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/e97627871a7eab2f70e59166072a6b767d5834e0", - "reference": "e97627871a7eab2f70e59166072a6b767d5834e0", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "time": "2020-08-10T04:50:15+00:00" - }, - { - "name": "symfony/polyfill-ctype", - "version": "v1.18.1", - "source": { - "type": "git", - "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/1c302646f6efc070cd46856e600e5e0684d6b454", - "reference": "1c302646f6efc070cd46856e600e5e0684d6b454", - "shasum": "" - }, - "require": { - "php": ">=5.3.3" - }, - "suggest": { - "ext-ctype": "For best performance" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.18-dev" - }, - "thanks": { - "name": "symfony/polyfill", - "url": "https://github.com/symfony/polyfill" - } - }, - "autoload": { - "psr-4": { - "Symfony\\Polyfill\\Ctype\\": "" - }, - "files": [ - "bootstrap.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Gert de Pagter", - "email": "BackEndTea@gmail.com" - }, - { - "name": "Symfony Community", - "homepage": "https://symfony.com/contributors" - } - ], - "description": "Symfony polyfill for ctype functions", - "homepage": "https://symfony.com", - "keywords": [ - "compatibility", - "ctype", - "polyfill", - "portable" - ], - "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-14T12:35:20+00:00" - }, - { - "name": "theseer/tokenizer", - "version": "1.2.0", - "source": { - "type": "git", - "url": "https://github.com/theseer/tokenizer.git", - "reference": "75a63c33a8577608444246075ea0af0d052e452a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/theseer/tokenizer/zipball/75a63c33a8577608444246075ea0af0d052e452a", - "reference": "75a63c33a8577608444246075ea0af0d052e452a", - "shasum": "" - }, - "require": { - "ext-dom": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": "^7.2 || ^8.0" - }, - "type": "library", - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Arne Blankerts", - "email": "arne@blankerts.de", - "role": "Developer" - } - ], - "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", - "funding": [ - { - "url": "https://github.com/theseer", - "type": "github" - } - ], - "time": "2020-07-12T23:59:07+00:00" - }, - { - "name": "webmozart/assert", - "version": "1.9.1", - "source": { - "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/bafc69caeb4d49c39fd0779086c03a3738cbb389", - "reference": "bafc69caeb4d49c39fd0779086c03a3738cbb389", - "shasum": "" - }, - "require": { - "php": "^5.3.3 || ^7.0 || ^8.0", - "symfony/polyfill-ctype": "^1.8" - }, - "conflict": { - "phpstan/phpstan": "<0.12.20", - "vimeo/psalm": "<3.9.1" - }, - "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" - }, - "type": "library", - "autoload": { - "psr-4": { - "Webmozart\\Assert\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Bernhard Schussek", - "email": "bschussek@gmail.com" - } - ], - "description": "Assertions to validate method input/output with nice error messages.", - "keywords": [ - "assert", - "check", - "validate" - ], - "time": "2020-07-08T17:02:28+00:00" - } - ], - "aliases": [], - "minimum-stability": "stable", - "stability-flags": [], - "prefer-stable": false, - "prefer-lowest": false, - "platform": { - "php": ">=5.6.0" - }, - "platform-dev": [], - "plugin-api-version": "1.1.0" -} From 1b2b7da37ce1910e065f9f4a21b7f50944fce994 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Fri, 21 Aug 2020 07:51:04 -0700 Subject: [PATCH 03/22] dev(deps): loosen version constraints for php 5.6 compat --- composer.json | 4 ++-- tests/TestCase56.php | 35 +++++++++++++++++++++++++++++++++++ tests/bootstrap.php | 4 ++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 tests/TestCase56.php diff --git a/composer.json b/composer.json index a01b51fd..a53f2f45 100644 --- a/composer.json +++ b/composer.json @@ -48,8 +48,8 @@ "require-dev": { "squizlabs/php_codesniffer": "^3.5", "brain/monkey": "^2.4", - "phpunit/phpunit": "^9.3", - "mockery/mockery": "^1.4" + "phpunit/phpunit": "<= 9.3", + "mockery/mockery": "^1.3 | ^1.4" }, "scripts": { "test": "vendor/bin/phpunit", diff --git a/tests/TestCase56.php b/tests/TestCase56.php new file mode 100644 index 00000000..797d8c29 --- /dev/null +++ b/tests/TestCase56.php @@ -0,0 +1,35 @@ + Date: Fri, 21 Aug 2020 07:57:05 -0700 Subject: [PATCH 04/22] test(compat-dom): use count() instead of DOMNodeList::count() --- tests/Unit/DomTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/DomTest.php b/tests/Unit/DomTest.php index 26fd6bc3..64cfb0ff 100644 --- a/tests/Unit/DomTest.php +++ b/tests/Unit/DomTest.php @@ -36,7 +36,7 @@ public function it_evaluate_xpath_expression() baz '); - $count = $doc->xpath('//span')->count(); + $count = count($doc->xpath('//span')); $this->assertEquals(4, $count); } From 3c455a16c8d449419274ff8e55c2434236081fa2 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Fri, 21 Aug 2020 08:02:05 -0700 Subject: [PATCH 05/22] fix(compat-module): Don't use ?? operator --- src/Modules/AbstractModule.php | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/Modules/AbstractModule.php b/src/Modules/AbstractModule.php index 21b30b7c..f38a6288 100644 --- a/src/Modules/AbstractModule.php +++ b/src/Modules/AbstractModule.php @@ -127,7 +127,11 @@ protected function filters($hooks, $method, $priority = 10, $numArgs = 1) */ protected function condition() { - $features = (array) $GLOBALS['_wp_theme_features']['soil'][0] ?? []; + $features = []; + + if (isset($GLOBALS['_wp_theme_features']['soil'][0])) { + $features = (array) $GLOBALS['_wp_theme_features']['soil'][0]; + } return apply_filters( 'soil/load-module/' . $this->provides(), @@ -167,7 +171,7 @@ protected function render($view = null, $data = []) $view = null; } - $view = $view ?? ($this->provides() . '.php'); + $view = $view ?: ($this->provides() . '.php'); extract($data); ob_start(); include __DIR__ . "/../../resources/views/{$view}"; From 4076f620c1ab4b87b056b1ddd25a23c3350900d7 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Fri, 21 Aug 2020 08:28:57 -0700 Subject: [PATCH 06/22] =?UTF-8?q?test(compat-dom):=20use=20DOMNodeList::?= =?UTF-8?q?=20instead=20of=20count()=20=F0=9F=98=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- tests/Unit/DomTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/DomTest.php b/tests/Unit/DomTest.php index 64cfb0ff..76756e93 100644 --- a/tests/Unit/DomTest.php +++ b/tests/Unit/DomTest.php @@ -36,7 +36,7 @@ public function it_evaluate_xpath_expression() baz '); - $count = count($doc->xpath('//span')); + $count = $doc->xpath('//span')->length; $this->assertEquals(4, $count); } From 5d0d9002e73c0e235ce6b877e5121d67f1fd056d Mon Sep 17 00:00:00 2001 From: QWp6t Date: Fri, 21 Aug 2020 08:30:24 -0700 Subject: [PATCH 07/22] dev(composer): fix module tests namespaces --- tests/Unit/Modules/CleanUpModuleTest.php | 2 +- tests/Unit/Modules/RelativeUrlsModuleTest.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/Unit/Modules/CleanUpModuleTest.php b/tests/Unit/Modules/CleanUpModuleTest.php index e091aa4c..a2841916 100644 --- a/tests/Unit/Modules/CleanUpModuleTest.php +++ b/tests/Unit/Modules/CleanUpModuleTest.php @@ -1,6 +1,6 @@ Date: Fri, 21 Aug 2020 08:39:25 -0700 Subject: [PATCH 08/22] test(compat): use compat TestCase for php 7.0 --- tests/bootstrap.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1b6daba5..afce6344 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -2,7 +2,7 @@ namespace Roots\Soil\Tests; -if (version_compare(phpversion(), '7.0', '<')) { +if (version_compare(phpversion(), '7.1', '<')) { require __DIR__ . '/TestCase56.php'; } From 9610966bf0173f28609df7f00b658944636c1fbb Mon Sep 17 00:00:00 2001 From: QWp6t Date: Fri, 21 Aug 2020 10:06:42 -0700 Subject: [PATCH 09/22] dev(phpcs): check for php 5.6+ compat --- .gitignore | 2 ++ composer.json | 6 ++++-- phpcs.xml.dist | 28 ++++++++++++++++++++++++++++ tests/TestCase.php | 2 ++ tests/bootstrap.php | 18 +----------------- tests/helpers.php | 18 ++++++++++++++++++ 6 files changed, 55 insertions(+), 19 deletions(-) create mode 100644 phpcs.xml.dist create mode 100644 tests/helpers.php diff --git a/.gitignore b/.gitignore index 7579f743..6792bab2 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,4 @@ vendor composer.lock +phpunit.xml +phpcs.xml diff --git a/composer.json b/composer.json index a53f2f45..4ed3e12b 100644 --- a/composer.json +++ b/composer.json @@ -49,10 +49,12 @@ "squizlabs/php_codesniffer": "^3.5", "brain/monkey": "^2.4", "phpunit/phpunit": "<= 9.3", - "mockery/mockery": "^1.3 | ^1.4" + "mockery/mockery": "^1.3 | ^1.4", + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", + "phpcompatibility/php-compatibility": "^9.3" }, "scripts": { "test": "vendor/bin/phpunit", - "lint": "vendor/bin/phpcs --standard=PSR12 --extensions=php --ignore=vendor/ -n -s src" + "lint": "vendor/bin/phpcs" } } diff --git a/phpcs.xml.dist b/phpcs.xml.dist new file mode 100644 index 00000000..d1a199af --- /dev/null +++ b/phpcs.xml.dist @@ -0,0 +1,28 @@ + + + PSR12 with PHP 5.6+ compatibility + + + + + + + + + + + + soil.php + src + tests + + + + 1 + + + + + tests/* + + diff --git a/tests/TestCase.php b/tests/TestCase.php index 41031f90..9e3dda46 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -8,6 +8,8 @@ use function Brain\Monkey\Functions\stubs; +// phpcs:disable PHPCompatibility.FunctionDeclarations.NewReturnTypeDeclarations.voidFound + class TestCase extends FrameworkTestCase { use MockeryPHPUnitIntegration; diff --git a/tests/bootstrap.php b/tests/bootstrap.php index afce6344..bd1da118 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -1,25 +1,9 @@ Date: Fri, 21 Aug 2020 10:10:11 -0700 Subject: [PATCH 10/22] dev(composer): fix helper tests namespaces --- tests/Unit/Helpers/UrlCompareTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Unit/Helpers/UrlCompareTest.php b/tests/Unit/Helpers/UrlCompareTest.php index acd2974e..7048ee45 100644 --- a/tests/Unit/Helpers/UrlCompareTest.php +++ b/tests/Unit/Helpers/UrlCompareTest.php @@ -1,6 +1,6 @@ Date: Sat, 22 Aug 2020 09:53:08 -0700 Subject: [PATCH 11/22] feat(options): add options support for modules --- resources/views/google-analytics.php | 13 +- src/Modules/AbstractModule.php | 58 ++++++- src/Modules/GoogleAnalyticsModule.php | 87 ++++++++++- src/Options.php | 213 ++++++++++++++++++++++++++ src/Soil.php | 56 ++++++- tests/Unit/OptionsTest.php | 159 +++++++++++++++++++ tests/Unit/SoilTest.php | 9 +- 7 files changed, 567 insertions(+), 28 deletions(-) create mode 100644 src/Options.php create mode 100644 tests/Unit/OptionsTest.php diff --git a/resources/views/google-analytics.php b/resources/views/google-analytics.php index 41129bf0..d6667820 100644 --- a/resources/views/google-analytics.php +++ b/resources/views/google-analytics.php @@ -1,3 +1,4 @@ + diff --git a/src/Modules/AbstractModule.php b/src/Modules/AbstractModule.php index f38a6288..f929ece5 100644 --- a/src/Modules/AbstractModule.php +++ b/src/Modules/AbstractModule.php @@ -3,6 +3,7 @@ namespace Roots\Soil\Modules; use Roots\Soil\Exceptions\LifecycleException; +use Roots\Soil\Options; use function add_action; use function add_filter; @@ -21,6 +22,20 @@ abstract class AbstractModule */ protected $name; + /** + * Module options. + * + * @var Options + */ + protected $options = false; + + /** + * Default options. + * + * @var array + */ + protected $defaults = ['enabled' => true]; + /** * Whether this module has already loaded. * @@ -63,10 +78,11 @@ abstract protected function handle(); * * This attaches the module to its hook. * + * @param array|Options $options * @return string * @throws LifecycleException */ - public function register() + public function register($options = null) { if ($this->loaded) { throw new LifecycleException( @@ -80,9 +96,37 @@ public function register() ); } + $this->options = $this->processOptions($options); $this->loaded = add_action($this->hook, $this); } + /** + * Generate Options object based on input options array. + * + * @param array|Options $options + * @return Options + */ + protected function processOptions($options) + { + if (! isset($options['enabled'])) { + $options = ['enabled' => true]; + } + + $options = $options instanceof Options ? $options : new Options($options); + + return $options->merge($this->defaults); + } + + /** + * Retrieve module options. + * + * @return Options + */ + public function getOptions() + { + return $this->options; + } + /** * Internal hook handler * @@ -127,15 +171,9 @@ protected function filters($hooks, $method, $priority = 10, $numArgs = 1) */ protected function condition() { - $features = []; - - if (isset($GLOBALS['_wp_theme_features']['soil'][0])) { - $features = (array) $GLOBALS['_wp_theme_features']['soil'][0]; - } - return apply_filters( 'soil/load-module/' . $this->provides(), - in_array($this->provides(), $features) && (!is_admin() || wp_doing_ajax()) + $this->options->enabled && (!is_admin() || wp_doing_ajax()) ); } @@ -171,6 +209,10 @@ protected function render($view = null, $data = []) $view = null; } + if (empty($data)) { + $data = $this->options->all(); + } + $view = $view ?: ($this->provides() . '.php'); extract($data); ob_start(); diff --git a/src/Modules/GoogleAnalyticsModule.php b/src/Modules/GoogleAnalyticsModule.php index 6c5c00e8..808c1ed7 100644 --- a/src/Modules/GoogleAnalyticsModule.php +++ b/src/Modules/GoogleAnalyticsModule.php @@ -14,6 +14,62 @@ class GoogleAnalyticsModule extends AbstractModule */ protected $name = 'google-analytics'; + /** + * Default options. + * + * @var array + */ + protected $defaults = [ + /** + * Enable this module. + * + * @var bool + */ + 'enabled' => true, + + /** + * This is to go live with GA. + * + * This should be false in non-production. + * + * @var bool + */ + 'should_load' => false, + + /** + * Google Analytics ID + * + * This is also known as your "property ID" or "measurement ID" + * + * Format: UA-XXXXX-Y + * + * @var string + */ + 'google_analytics_id' => null, + + /** + * Optimize container ID + * + * Format: OPT-A1B2CD (previously: GTM-A1B2CD) + * + * @link https://support.google.com/optimize/answer/6262084 + * + * @var string + */ + 'optimize_id' => null, + + /** + * Anonymize user IP addresses. + * + * This might be required depending on region. + * + * @link https://github.com/roots/soil/pull/206 + * + * @var bool + */ + 'anonymize_ip' => true, + ]; + /** * Name of the hook at which this module will run. * @@ -21,6 +77,30 @@ class GoogleAnalyticsModule extends AbstractModule */ protected $hook = 'wp_head'; + /** + * Generate Options object based on input options array. + * + * @param array|Options $options + * @return Options + */ + protected function processOptions($options) + { + $options = parent::processOptions($options); + + if (isset($options->options)) { + $options->google_analytics_id = $options->options; + unset($options->options); + } + + if (!$options->should_load) { + $options->should_load = !empty($options->google_analytics_id) + && (!defined('WP_ENV') || \WP_ENV === 'production') + && !current_user_can('manage_options'); + } + + return $options; + } + /** * Module handle. * @@ -28,11 +108,6 @@ class GoogleAnalyticsModule extends AbstractModule */ public function handle() { - echo $this->render([ - 'should_load' => null, - 'google_analytics_id' => null, - 'optimize_id' => null, - 'anonymize_ip' => null, - ]); + echo $this->render(); } } diff --git a/src/Options.php b/src/Options.php new file mode 100644 index 00000000..e1df4a02 --- /dev/null +++ b/src/Options.php @@ -0,0 +1,213 @@ +merge($options); + } + + /** + * Get option value. + * + * @param string $key + * @param mixed $default + * @return mixed + */ + public function get($key, $default = null) + { + if ($this->offsetExists($key)) { + return $this->options[$key]; + } + + return $default; + } + + /** + * Merge passed options. + * + * @param array|Options $options + * @return Options + */ + public function merge($options) + { + foreach ((array) $options as $option => $value) { + if (isset($this->options[$option])) { + continue; + } + + $this->offsetSet($option, $value); + } + + return $this; + } + + /** + * Forcefully merge passed options. + * + * This will overwrite options that already exist. + * + * @param array|Options $options + * @return Options + */ + public function forceMerge($options) + { + foreach ((array) $options as $option => $value) { + $this->offsetSet($option, $value); + } + + return $this; + } + + /** + * Get the internal array of options. + * + * @return array + */ + public function all() + { + return $this->options; + } + + /** + * Get all options. + * + * @return Traversable + */ + public function getIterator() + { + return $this->options; + } + + /** + * Get number of options. + * + * @return int + */ + public function count() + { + return count($this->options); + } + + /** + * Get option value. + * + * @param string $key + * @return mixed + */ + public function offsetGet($key) + { + return $this->get($key); + } + + /** + * Set option value. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function offsetSet($key, $value) + { + /** + * The following: + * $options[] = 'foobar' + * $options[1] = 'foobar' + * + * Will resolve as: + * $options['foobar'] = true + */ + if (!is_string($key)) { + $key = $value; + $value = true; + } + + $this->options[$key] = $value; + } + + /** + * Checks whether option exists. + * + * @param string $key + * @return bool + */ + public function offsetExists($key) + { + return array_key_exists($key, $this->options); + } + + /** + * Delete an option. + * + * @param string $key + * @return void + */ + public function offsetUnset($key) + { + unset($this->options[$key]); + } + + /** + * Get option value. + * + * @param string $key + * @return mixed + */ + public function __get($key) + { + return $this->get($key); + } + + /** + * Set option value. + * + * @param string $key + * @param mixed $value + * @return void + */ + public function __set($key, $value) + { + $this->offsetSet($key, $value); + } + + /** + * Checks whether option exists. + * + * @param string $key + * @return bool + */ + public function __isset($key) + { + return $this->offsetExists($key); + } + + /** + * Delete an option. + * + * @param string $key + * @return void + */ + public function __unset($key) + { + $this->offsetUnset($key); + } +} diff --git a/src/Soil.php b/src/Soil.php index f5aaef31..480abd91 100644 --- a/src/Soil.php +++ b/src/Soil.php @@ -17,15 +17,23 @@ class Soil */ protected $modules; + /** + * List of supported modules and options. + * + * @var array[] + */ + protected $features; + /** * Create an instance of Soil. * * @param string[]|object[] * @return void */ - public function __construct($modules = []) + public function __construct($modules = [], $features = []) { $this->modules = $modules; + $this->features = $this->features($features); } /** @@ -77,18 +85,62 @@ public function __invoke() apply_filters('soil/modules', (array) $this->modules) )); + if (! $this->features) { + $this->features = isset($GLOBALS['_wp_theme_features']['soil'][0]) + ? $this->features($GLOBALS['_wp_theme_features']['soil'][0]) + : []; + } + foreach ($modules as $module) { if (is_string($module)) { /** @var \Roots\Soil\Modules\AbstractModule */ $module = new $module(); } - $module->register(); + if ($this->features) { + $module->register($this->features[$module->provides()]); + } else { + $module->register(['enabled' => true]); + } } do_action('soil/init'); } + protected function features($features = []) + { + $modules = []; + + foreach ((array) $features as $module => $options) { + // add_theme_support('soil', ['module']) + if (is_int($module)) { + $module = $options; + $options = ['enabled' => true]; + } + + // add_theme_support('soil', ['module' => true]) + if (is_bool($options)) { + $options = ['enabled' => $options]; + } + + // add_theme_support('soil', ['module' => 'some-option']) + if (is_array($options) && isset($options[0]) && !isset($options[1])) { + $options = ['options' => $options[0]]; + } + + // if an option is specified, + // let's assume the module should be enabled + // add_theme_support('soil', ['module' => ['option' => 'value']]) + if (! isset($options['enabled'])) { + $options['enabled'] = true; + } + + $modules[$module] = (array) $options; + } + + return $modules; + } + public static function discoverModules($glob = __DIR__ . '/Modules/*Module.php', $namespace = __NAMESPACE__ . '\\Modules') { $namespace = rtrim($namespace, '\\'); diff --git a/tests/Unit/OptionsTest.php b/tests/Unit/OptionsTest.php new file mode 100644 index 00000000..2136b1dc --- /dev/null +++ b/tests/Unit/OptionsTest.php @@ -0,0 +1,159 @@ + 'bar']; + + $options = new Options($data); + + $this->assertNotEquals('baz', $options->get('foo', 'baz')); + $this->assertEquals('baz', $options->get('biz', 'baz')); + } + + /** @test */ + public function it_should_assume_indexed_array_is_list_of_boolean_keys() + { + $data = ['foo', 'bar']; + + $options = new Options($data); + + $this->assertTrue($options->get('foo')); + $this->assertTrue($options->get('bar')); + + $this->assertNull($options->get('biz')); + $options[] = 'biz'; + $this->assertTrue($options->get('biz')); + + $this->assertNull($options->get('baz')); + $options[12345] = 'baz'; + $this->assertTrue($options->get('baz')); + } + + /** @test */ + public function it_should_merge_data() + { + $data = [ + 'foo' => 'bar' + ]; + + $options = new Options($data); + + $options->merge(['biz' => 'baz']); + + $this->assertEquals($options->get('foo'), 'bar'); + $this->assertEquals($options->get('biz'), 'baz'); + } + + /** @test */ + public function it_should_not_overwrite_merge_data() + { + $data = [ + 'foo' => 'bar', + 'biz' => 'baz' + ]; + + $options = new Options($data); + + $this->assertEquals($options->get('biz'), 'baz'); + + $options->merge(['biz' => 'not-baz']); + + $this->assertNotEquals($options->get('biz'), 'not-baz'); + } + + /** @test */ + public function it_should_overwrite_merge_data() + { + $data = [ + 'foo' => 'bar', + 'biz' => 'baz' + ]; + + $options = new Options($data); + + $this->assertEquals($options->get('biz'), 'baz'); + + $options->forceMerge(['biz' => 'not-baz']); + + $this->assertEquals($options->get('biz'), 'not-baz'); + } + + /** @test */ + public function it_should_be_countable() + { + $data = [ + 'foo' => 'bar', + 'biz' => 'baz' + ]; + + $options = new Options($data); + + $this->assertEquals(2, count($options)); + } + + /** @test */ + public function it_should_behave_like_an_array() + { + $data = [ + 'foo' => 'bar', + 'biz' => 'baz' + ]; + + $options = new Options($data); + + $this->assertTrue(isset($options['foo'])); + $this->assertFalse(isset($options['bad-key'])); + + unset($options['foo']); + $this->assertFalse(isset($options['foo'])); + + $options['foo'] = 'bar'; + $this->assertEquals('bar', $options['foo']); + } + + /** @test */ + public function it_should_behave_like_an_object() + { + $data = [ + 'foo' => 'bar', + 'biz' => 'baz' + ]; + + $options = new Options($data); + + $this->assertTrue(isset($options->foo)); + $this->assertFalse(isset($options->bad_key)); + + unset($options->foo); + $this->assertFalse(isset($options->foo)); + + $options->foo = 'bar'; + $this->assertEquals('bar', $options->foo); + } + + public function it_should_be_iterable() + { + $data = [ + 'foo' => 'bar', + 'biz' => 'baz' + ]; + + $options = new Options($data); + $actual = []; + + foreach ($options as $key => $value) { + $this->assertEquals($data[$key], $value); + $actual[$key] = $value; + } + + $this->assertSame($data, $actual); + } +} diff --git a/tests/Unit/SoilTest.php b/tests/Unit/SoilTest.php index 2bded6a5..97e32c3f 100644 --- a/tests/Unit/SoilTest.php +++ b/tests/Unit/SoilTest.php @@ -17,12 +17,15 @@ class SoilTest extends TestCase /** @test */ public function it_should_register_modules_when_invoked() { - $module = m::mock(AbstractModule::class); + $module = m::mock(AbstractModule::class)->makePartial(); + + $module->shouldReceive('provides'); + $soil = new Soil([$module]); $module->shouldReceive('register') ->once() - ->withNoArgs(); + ->with(['enabled' => true]); $soil(); } @@ -30,7 +33,7 @@ public function it_should_register_modules_when_invoked() /** @test */ public function it_should_fire_init_hook_when_invoked() { - $module = StubModule::class; + $module = new StubModule(); $soil = new Soil([$module]); $soil(); From 32a73af6a071ce6e465413dbea695cffc5522b28 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 22 Aug 2020 10:08:08 -0700 Subject: [PATCH 12/22] tests(helpers): remove unused function --- tests/helpers.php | 5 ----- 1 file changed, 5 deletions(-) diff --git a/tests/helpers.php b/tests/helpers.php index ad17bbf8..e360b469 100644 --- a/tests/helpers.php +++ b/tests/helpers.php @@ -11,8 +11,3 @@ function fixture($fixture) { return __DIR__ . '/__fixtures__/' . $fixture; } - -function global_return($function, $return) -{ - $GLOBALS[$function] = $return; -} From 2b7d9df02e7214084075ac75288ac3d108d7e9d0 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 22 Aug 2020 12:29:20 -0700 Subject: [PATCH 13/22] fix(cleanup): remove embed wrap due to incompatibility with gutenberg --- src/Modules/CleanUpModule.php | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/Modules/CleanUpModule.php b/src/Modules/CleanUpModule.php index 65194dc8..75125642 100644 --- a/src/Modules/CleanUpModule.php +++ b/src/Modules/CleanUpModule.php @@ -216,22 +216,6 @@ public function bodyClass($classes) return $classes; } - /** - * Wrap embedded media as suggested by Readability - * - * @internal Used by `embed_oembed_html` - * - * @link https://gist.github.com/965956 - * @link http://www.readability.com/publishers/guidelines#publisher - * - * @param string $cache - * @return string - */ - public function embedWrap($cache) - { - return '
    ' . $cache . '
    '; - } - /** * Remove the default site tagline from RSS feed. * From d54191045111e3a4af29bd02569083c7df851d29 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 22 Aug 2020 12:30:47 -0700 Subject: [PATCH 14/22] feat(cleanup): tasks are grouped together and made optional --- src/Modules/CleanUpModule.php | 180 +++++++++++++++++++++++++++------- 1 file changed, 146 insertions(+), 34 deletions(-) diff --git a/src/Modules/CleanUpModule.php b/src/Modules/CleanUpModule.php index 75125642..03ecf451 100644 --- a/src/Modules/CleanUpModule.php +++ b/src/Modules/CleanUpModule.php @@ -38,6 +38,69 @@ class CleanUpModule extends AbstractModule */ protected $name = 'clean-up'; + /** + * Default options. + * + * @var array + */ + protected $defaults = [ + /** + * Enable this module. + * + * @var bool + */ + 'enabled' => true, + + /** + * Obscure and suppress WordPress information. + * + * @var bool + */ + 'wp_obscurity' => true, + + /** + * Disable WordPress emojis. + * + * @var bool + */ + 'disable_emojis' => true, + + /** + * Disable Gutenberg block library CSS. + * + * @var bool + */ + 'disable_gutenberg_block_css' => false, + + /** + * Disable extra RSS feeds. + * + * @var bool + */ + 'disable_extra_rss' => true, + + /** + * Disable recent comments CSS. + * + * @var bool + */ + 'disable_rececent_comments_css' => true, + + /** + * Disable gallery CSS. + * + * @var bool + */ + 'disable_gallery_css' => true, + + /** + * Clean HTML5 markup. + * + * @var bool + */ + 'clean_html5_markup' => true, + ]; + /** * Module handle. * @@ -45,66 +108,79 @@ class CleanUpModule extends AbstractModule */ public function handle() { - $this->filter('init', 'headCleanup'); - $this->filter('language_attributes', 'languageAttributes'); - $this->filter('body_class', 'bodyClass'); - $this->filter('embed_oembed_html', 'embedWrap'); - $this->filter('get_bloginfo_rss', 'removeDefaultSiteTagline'); - - $this->filters([ - 'get_avatar', // - 'comment_id_fields', // - 'post_thumbnail_html' // - ], 'removeSelfClosingTags'); + $tasks = [ + 'wp_obscurity' => 'wpObscurity', + 'disable_emojis' => 'disableEmojis', + 'disable_gutenberg_block_css' => 'disableGutenbergBlockCss', + 'disable_extra_rss' => 'disableExtraRss', + 'disable_rececent_comments_css' => 'disableRecentCommentsCss', + 'disable_gallery_css' => 'disableGalleryCss', + 'clean_html5_markup' => 'cleanHtmlMarkup', + ]; - if (class_exists(DOMDocument::class)) { - $this->filter('style_loader_tag', 'cleanStylesheetLinks'); - $this->filter('script_loader_tag', 'cleanScriptTags'); + foreach (array_filter($this->options->all()) as $option) { + if (isset($tasks[$option])) { + $this->{$tasks[$option]}(); + } } - - $this->removeCommentsFeed(); - $this->removeWordPressVersionFromRssFeeds(); } /** - * Clean up output section. - * - * @internal Used by `init` - * - * @link https://wpengineer.com/1438/wordpress-header/ + * Obscure and suppress WordPress information. * * @return void */ - public function headCleanup() + protected function wpObscurity() { - remove_action('wp_head', 'feed_links_extra', 3); + $this->filter('get_bloginfo_rss', 'removeDefaultSiteTagline'); + add_filter('the_generator', '__return_false'); remove_action('wp_head', 'rsd_link'); remove_action('wp_head', 'wlwmanifest_link'); remove_action('wp_head', 'adjacent_posts_rel_link_wp_head', 10); remove_action('wp_head', 'wp_generator'); remove_action('wp_head', 'wp_shortlink_wp_head', 10); + remove_action('wp_head', 'rest_output_link_wp_head', 10); + remove_action('wp_head', 'wp_oembed_add_discovery_links'); + remove_action('wp_head', 'wp_oembed_add_host_js'); + } + + /** + * Disable WordPress emojis. + * + * @return void + */ + protected function disableEmojis() + { remove_action('wp_head', 'print_emoji_detection_script', 7); remove_action('admin_print_scripts', 'print_emoji_detection_script'); remove_action('wp_print_styles', 'print_emoji_styles'); remove_action('admin_print_styles', 'print_emoji_styles'); - remove_action('wp_head', 'wp_oembed_add_discovery_links'); - remove_action('wp_head', 'wp_oembed_add_host_js'); - remove_action('wp_head', 'rest_output_link_wp_head', 10); remove_filter('the_content_feed', 'wp_staticize_emoji'); remove_filter('comment_text_rss', 'wp_staticize_emoji'); remove_filter('wp_mail', 'wp_staticize_emoji_for_email'); - add_filter('use_default_gallery_style', '__return_false'); add_filter('emoji_svg_url', '__return_false'); - add_filter('show_recent_comments_widget_style', '__return_false'); } /** - * Remove comments feed from . + * Disable Gutenberg block library CSS. * * @return void */ - public function removeCommentsFeed() + protected function disableGutenbergBlockCss() { + add_action('wp_enqueue_scripts', function () { + wp_dequeue_style('wp-block-library'); + }, 200); + } + + /** + * Disable extra RSS feeds. + * + * @return void + */ + protected function disableExtraRss() + { + remove_action('wp_head', 'feed_links_extra', 3); add_action('wp_head', 'ob_start', 1, 0); add_action('wp_head', function () { $pattern = '/.*' . preg_quote(esc_url(get_feed_link('comments_' . get_default_feed())), '/') . '.*[\r\n]+/'; @@ -113,13 +189,49 @@ public function removeCommentsFeed() } /** - * Remove the WordPress version from RSS feeds. + * Disable recent comments CSS. * * @return void */ - public function removeWordPressVersionFromRssFeeds() + protected function disableRecentCommentsCss() { - add_filter('the_generator', '__return_false'); + add_filter('show_recent_comments_widget_style', '__return_false'); + } + + /** + * Disable gallery CSS. + * + * @return void + */ + protected function disableGalleryCss() + { + add_filter('use_default_gallery_style', '__return_false'); + } + + /** + * Clean HTML5 markup. + * + * @return void + */ + protected function cleanHtmlMarkup() + { + $this->filter('body_class', 'bodyClass'); + $this->filter('language_attributes', 'languageAttributes'); + + if (class_exists(DOMDocument::class)) { + $this->filter('style_loader_tag', 'cleanStylesheetLinks'); + $this->filter('script_loader_tag', 'cleanScriptTags'); + } + + $this->filters([ + 'get_avatar', // + 'comment_id_fields', // + 'post_thumbnail_html', // + ], 'removeSelfClosingTags'); + + add_filter('site_icon_meta_tags', function ($meta_tags) { + return array_map([$this, 'site_icon_meta_tags'], $meta_tags); + }, 20); } /** From 78feddc4ef31ea6b1c1016ac53b47aaa469db7c7 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 22 Aug 2020 12:52:06 -0700 Subject: [PATCH 15/22] fix(soil): modules unspecified in features array should be skipped --- src/Soil.php | 17 ++++++++++++----- tests/Unit/SoilTest.php | 4 ++-- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/Soil.php b/src/Soil.php index 480abd91..e089f0f9 100644 --- a/src/Soil.php +++ b/src/Soil.php @@ -85,10 +85,14 @@ public function __invoke() apply_filters('soil/modules', (array) $this->modules) )); - if (! $this->features) { + if (!$this->features) { $this->features = isset($GLOBALS['_wp_theme_features']['soil'][0]) ? $this->features($GLOBALS['_wp_theme_features']['soil'][0]) - : []; + : null; + } + + if (!$this->features) { + return; } foreach ($modules as $module) { @@ -97,10 +101,13 @@ public function __invoke() $module = new $module(); } - if ($this->features) { - $module->register($this->features[$module->provides()]); - } else { + if (!$this->features) { $module->register(['enabled' => true]); + continue; + } + + if (isset($this->features[$module->provides()]) && $this->features[$module->provides()]) { + $module->register($this->features[$module->provides()]); } } diff --git a/tests/Unit/SoilTest.php b/tests/Unit/SoilTest.php index 97e32c3f..fdf54363 100644 --- a/tests/Unit/SoilTest.php +++ b/tests/Unit/SoilTest.php @@ -21,7 +21,7 @@ public function it_should_register_modules_when_invoked() $module->shouldReceive('provides'); - $soil = new Soil([$module]); + $soil = new Soil([$module], [$module->provides()]); $module->shouldReceive('register') ->once() @@ -34,7 +34,7 @@ public function it_should_register_modules_when_invoked() public function it_should_fire_init_hook_when_invoked() { $module = new StubModule(); - $soil = new Soil([$module]); + $soil = new Soil([$module], [$module->provides()]); $soil(); From 21dfe67aa84e82a88c7f87e6db103c30a7488d7c Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 22 Aug 2020 13:07:33 -0700 Subject: [PATCH 16/22] =?UTF-8?q?fix(cleanup):=20tasks=20should=20actually?= =?UTF-8?q?=20load=20=F0=9F=99=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/Modules/CleanUpModule.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Modules/CleanUpModule.php b/src/Modules/CleanUpModule.php index 03ecf451..01d7de38 100644 --- a/src/Modules/CleanUpModule.php +++ b/src/Modules/CleanUpModule.php @@ -70,7 +70,7 @@ class CleanUpModule extends AbstractModule * * @var bool */ - 'disable_gutenberg_block_css' => false, + 'disable_gutenberg_block_css' => true, /** * Disable extra RSS feeds. @@ -118,9 +118,11 @@ public function handle() 'clean_html5_markup' => 'cleanHtmlMarkup', ]; - foreach (array_filter($this->options->all()) as $option) { - if (isset($tasks[$option])) { - $this->{$tasks[$option]}(); + $enabled_tasks = array_keys(array_filter($this->options->all())); + + foreach ($enabled_tasks as $task) { + if (isset($tasks[$task])) { + $this->{$tasks[$task]}(); } } } From 555c2403dc1c4f922e9d4f4fccae9c728d720de4 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 22 Aug 2020 13:09:37 -0700 Subject: [PATCH 17/22] feat(woocommerce): add woocommerce-cleanup module --- src/Modules/CleanUpWooCommerceModule.php | 146 +++++++++++++++++++++++ 1 file changed, 146 insertions(+) create mode 100644 src/Modules/CleanUpWooCommerceModule.php diff --git a/src/Modules/CleanUpWooCommerceModule.php b/src/Modules/CleanUpWooCommerceModule.php new file mode 100644 index 00000000..80787863 --- /dev/null +++ b/src/Modules/CleanUpWooCommerceModule.php @@ -0,0 +1,146 @@ +filter('woocommerce_enqueue_styles', 'dequeueStyles'); + $this->filter('body_class', 'dequeueScripts'); + $this->filter('wp_print_styles', 'dequeueInlineStyles'); + $this->filter('init', 'removeGalleryNoscript'); + $this->filter('body_class', 'removeNoJS'); + } + + /** + * Dequeue styles. + * + * @internal Used by `woocommerce_enqueue_styles` + * + * @return void + */ + public function dequeueStyles() + { + return $this->isWooCommerce(); + } + + /** + * Dequeue inline styles. + * + * @internal Used by `wp_print_styles` + * + * @return void + */ + public function dequeueInlineStyles() + { + if ($this->isWooCommerce()) { + return; + } + + if (!wp_style_is('woocommerce-inline', 'enqueued')) { + return; + } + + wp_style_add_data('woocommerce-inline', 'after', ''); + } + + /** + * Dequeue scripts. + * + * @internal Used by `body_class` + * + * @param array $classes + * @return void + */ + public function dequeueScripts($classes) + { + if ($this->isWooCommerce()) { + return $classes; + } + + wp_dequeue_script('woocommerce'); + wp_dequeue_script('wc-cart-fragments'); + wp_dequeue_script('wc-add-to-cart'); + + return $classes; + } + + /** + * Don't show gallery if JS is disabled. + * + * @internal Used by `init` + * + * @return void + */ + public function removeGalleryNoscript() + { + if ($this->isWooCommerce()) { + return; + } + remove_action('wp_head', 'wc_gallery_noscript'); + } + + /** + * Disable No JS handling. + * + * @internal Used by `body_class` + * + * @param array $classes + * @return void + */ + public function removeNoJS($classes) + { + if ($this->isWooCommerce()) { + return $classes; + } + + remove_action('wp_footer', 'wc_no_js'); + + return $classes; + } + + /** + * Checks whether the current page is a WC page. + * + * @return bool + */ + protected function isWooCommerce() + { + return is_woocommerce() || is_cart() || is_checkout(); + } +} From 8ccb2e4b10d7ffa7e1e7fb81539975ecaa5ddcd8 Mon Sep 17 00:00:00 2001 From: Ben Word Date: Sat, 29 Aug 2020 15:55:21 -0600 Subject: [PATCH 18/22] feat(cleanup): use filter to remove comments feed --- src/Modules/CleanUpModule.php | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Modules/CleanUpModule.php b/src/Modules/CleanUpModule.php index 01d7de38..cb4bef5c 100644 --- a/src/Modules/CleanUpModule.php +++ b/src/Modules/CleanUpModule.php @@ -182,12 +182,7 @@ protected function disableGutenbergBlockCss() */ protected function disableExtraRss() { - remove_action('wp_head', 'feed_links_extra', 3); - add_action('wp_head', 'ob_start', 1, 0); - add_action('wp_head', function () { - $pattern = '/.*' . preg_quote(esc_url(get_feed_link('comments_' . get_default_feed())), '/') . '.*[\r\n]+/'; - echo preg_replace($pattern, '', ob_get_clean()); - }, 3, 0); + add_filter('feed_links_show_comments_feed', '__return_false'); } /** From e42ad8a93b1503a75ff428fb0bd1f0cb8b82f151 Mon Sep 17 00:00:00 2001 From: Ben Word Date: Sat, 29 Aug 2020 16:23:30 -0600 Subject: [PATCH 19/22] revert: woocommerce-cleanup module Ref: 555c240 --- src/Modules/CleanUpWooCommerceModule.php | 146 ----------------------- 1 file changed, 146 deletions(-) delete mode 100644 src/Modules/CleanUpWooCommerceModule.php diff --git a/src/Modules/CleanUpWooCommerceModule.php b/src/Modules/CleanUpWooCommerceModule.php deleted file mode 100644 index 80787863..00000000 --- a/src/Modules/CleanUpWooCommerceModule.php +++ /dev/null @@ -1,146 +0,0 @@ -filter('woocommerce_enqueue_styles', 'dequeueStyles'); - $this->filter('body_class', 'dequeueScripts'); - $this->filter('wp_print_styles', 'dequeueInlineStyles'); - $this->filter('init', 'removeGalleryNoscript'); - $this->filter('body_class', 'removeNoJS'); - } - - /** - * Dequeue styles. - * - * @internal Used by `woocommerce_enqueue_styles` - * - * @return void - */ - public function dequeueStyles() - { - return $this->isWooCommerce(); - } - - /** - * Dequeue inline styles. - * - * @internal Used by `wp_print_styles` - * - * @return void - */ - public function dequeueInlineStyles() - { - if ($this->isWooCommerce()) { - return; - } - - if (!wp_style_is('woocommerce-inline', 'enqueued')) { - return; - } - - wp_style_add_data('woocommerce-inline', 'after', ''); - } - - /** - * Dequeue scripts. - * - * @internal Used by `body_class` - * - * @param array $classes - * @return void - */ - public function dequeueScripts($classes) - { - if ($this->isWooCommerce()) { - return $classes; - } - - wp_dequeue_script('woocommerce'); - wp_dequeue_script('wc-cart-fragments'); - wp_dequeue_script('wc-add-to-cart'); - - return $classes; - } - - /** - * Don't show gallery if JS is disabled. - * - * @internal Used by `init` - * - * @return void - */ - public function removeGalleryNoscript() - { - if ($this->isWooCommerce()) { - return; - } - remove_action('wp_head', 'wc_gallery_noscript'); - } - - /** - * Disable No JS handling. - * - * @internal Used by `body_class` - * - * @param array $classes - * @return void - */ - public function removeNoJS($classes) - { - if ($this->isWooCommerce()) { - return $classes; - } - - remove_action('wp_footer', 'wc_no_js'); - - return $classes; - } - - /** - * Checks whether the current page is a WC page. - * - * @return bool - */ - protected function isWooCommerce() - { - return is_woocommerce() || is_cart() || is_checkout(); - } -} From 4a5b73dd8c3c60bbdb072e69abf46798fcefde79 Mon Sep 17 00:00:00 2001 From: Ben Word Date: Sat, 29 Aug 2020 17:01:37 -0600 Subject: [PATCH 20/22] Soil 4 --- CHANGELOG.md | 5 ++ README.md | 142 ++++++++++++++++++++++++++++++++++++++++++++++++++- soil.php | 2 +- 3 files changed, 147 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a1e7405c..8d568d0d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +### 4.0.0: August 29th, 2020 +* BREAKING CHANGE - Refactor entire code base +* Add options support for modules +* Remove oEmbed wrapper due to incompatibility with Gutenberg + ### 3.9.0: December 7th, 2019 * Enable beacon tracking for Google Analytics ([#243](https://github.com/roots/soil/pull/243)) * Add support for GitHub Updater plugin ([#241](https://github.com/roots/soil/pull/241)) diff --git a/README.md b/README.md index 9f8d7d56..99f6d434 100644 --- a/README.md +++ b/README.md @@ -93,7 +93,11 @@ add_theme_support('soil', [ 'disable-rest-api', 'disable-asset-versioning', 'disable-trackbacks', - 'google-analytics', + 'google-analytics', => [ + 'should_load' => WP_ENV === 'production', // Only load on production + 'google_analytics_id' => 'UA-XXXYYY', + 'anonymize_ip' => true, + ], 'js-to-footer', 'nav-walker', 'nice-search', @@ -101,6 +105,142 @@ add_theme_support('soil', [ ]); ``` +### Module options + +Soil 4 introduced support for options on some modules. + +
    +Full annotated list of features and options + +```php + +/** + * Enable features from Soil when plugin is activated + * @link https://roots.io/plugins/soil/ + */ +add_theme_support('soil', [ + /** + * Clean up WordPress + */ + 'clean-up' => [ + /** + * Obscure and suppress WordPress information. + */ + 'wp_obscurity', + + /** + * Disable WordPress emojis. + */ + 'disable_emojis', + + /** + * Disable Gutenberg block library CSS. + */ + 'disable_gutenberg_block_css', + + /** + * Disable extra RSS feeds. + */ + 'disable_extra_rss', + + /** + * Disable recent comments CSS. + */ + 'disable_rececent_comments_css', + + /** + * Disable gallery CSS. + */ + 'disable_gallery_css', + + /** + * Clean HTML5 markup. + */ + 'clean_html5_markup', + ], + + /** + * Disable WordPress REST API + */ + 'disable-rest-api', + + /** + * Remove version query string from all styles and scripts + */ + 'disable-asset-versioning', + + /** + * Disables trackbacks/pingbacks + */ + 'disable-trackbacks', + + /** + * Google Analytics + */ + 'google-analytics' => [ + /** + * This is to go live with GA. + * + * This should probably be false in non-production. + */ + 'should_load' => false, + + /** + * Google Analytics ID + * + * This is also known as your "property ID" or "measurement ID" + * + * Format: UA-XXXXX-Y + */ + 'google_analytics_id' => null, + + /** + * Optimize container ID + * + * Format: OPT-A1B2CD (previously: GTM-A1B2CD) + * + * @link https://support.google.com/optimize/answer/6262084 + */ + 'optimize_id' => null, + + /** + * Anonymize user IP addresses. + * + * This might be required depending on region. + * + * @link https://github.com/roots/soil/pull/206 + */ + 'anonymize_ip', + ], + + /** + * Moves all scripts to wp_footer action + */ + 'js-to-footer', + + /** + * Cleaner walker for wp_nav_menu() + */ + 'nav-walker', + + /** + * Redirects search results from /?s=query to /search/query/, converts %20 to + + * + * @link http://txfx.net/wordpress-plugins/nice-search/ + */ + 'nice-search', + + /** + * Convert absolute URLs to relative URLs + * + * Inspired by {@link http://www.456bereastreet.com/archive/201010/how_to_make_wordpress_urls_root_relative/} + */ + 'relative-urls', +]); +``` +
    + + ## Support Use the [Roots Discourse](https://discourse.roots.io/) to ask questions and get support. License is required. diff --git a/soil.php b/soil.php index ea135064..e43b0883 100644 --- a/soil.php +++ b/soil.php @@ -4,7 +4,7 @@ * Plugin Name: Soil * Plugin URI: https://roots.io/plugins/soil/ * Description: A collection of modules to apply theme-agnostic front-end modifications to WordPress. - * Version: 4.0.0-alpha.0 + * Version: 4.0.0 * Author: Roots * Author URI: https://roots.io/ * GitHub Plugin URI: https://github.com/roots/soil From a493f1c77c37d302a7952b77340d49445e19d3fc Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 29 Aug 2020 18:16:56 -0700 Subject: [PATCH 21/22] fix(navwalker): kjo accidentally mislabeled nav-walker --- src/Modules/NavWalkerModule.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Modules/NavWalkerModule.php b/src/Modules/NavWalkerModule.php index 8167617b..cb6e9392 100644 --- a/src/Modules/NavWalkerModule.php +++ b/src/Modules/NavWalkerModule.php @@ -14,7 +14,7 @@ class NavWalkerModule extends AbstractModule * * @var string */ - protected $name = 'js-to-footer'; + protected $name = 'nav-walker'; /** * Module handle. From 8fea81d43348805c3cc0fb80d8e98687a6b41a96 Mon Sep 17 00:00:00 2001 From: QWp6t Date: Sat, 29 Aug 2020 18:54:19 -0700 Subject: [PATCH 22/22] fix(helpers-urlcomp): handle base_urls without schemes --- src/helpers.php | 10 +++++++--- tests/Unit/Helpers/UrlCompareTest.php | 6 ++++++ 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/src/helpers.php b/src/helpers.php index 0a08b3bf..e09fcc3c 100644 --- a/src/helpers.php +++ b/src/helpers.php @@ -33,11 +33,15 @@ function compare_base_url($base_url, $input_url, $strict_scheme = true) $base_url = parse_url($base_url); - if (!isset($input_url['scheme'])) { - $input_url['scheme'] = $base_url['scheme']; + if (!isset($base_url['host'])) { + return false; + } + + if (!$strict_scheme || !isset($input_url['scheme']) || !isset($base_url['scheme'])) { + $input_url['scheme'] = $base_url['scheme'] = 'soil'; } - if ($strict_scheme && ($base_url['scheme'] !== $input_url['scheme'])) { + if (($base_url['scheme'] !== $input_url['scheme'])) { return false; } diff --git a/tests/Unit/Helpers/UrlCompareTest.php b/tests/Unit/Helpers/UrlCompareTest.php index 7048ee45..00f60a57 100644 --- a/tests/Unit/Helpers/UrlCompareTest.php +++ b/tests/Unit/Helpers/UrlCompareTest.php @@ -21,6 +21,9 @@ public function it_should_handle_relative_urls() { $this->assertTrue(compare_base_url('https://example.test', '/')); $this->assertTrue(compare_base_url('https://example.test', '/foobar')); + + $this->assertTrue(compare_base_url('/', '/foobar')); + $this->assertFalse(compare_base_url('/foobar', 'https://example.test/foobar')); } /** @test */ @@ -28,6 +31,9 @@ public function it_should_handle_url_without_scheme() { $this->assertFalse(compare_base_url('https://example.test', '//foobar.test')); $this->assertTrue(compare_base_url('https://example.test', '//example.test')); + + $this->assertFalse(compare_base_url('//foobar.test', 'https://example.test')); + $this->assertFalse(compare_base_url('//foobar.test', 'http://example.test')); } /** @test */