From e618ffcc370e73fb116848df920564169af39e5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Thu, 6 Jun 2024 13:53:02 +0200 Subject: [PATCH 01/17] Use autoloader, change min PHP to 7.2, add unit test framework --- .ddev/config.yaml | 6 +- .gitignore | 3 + CHANGELOG.md | 3 + composer.json | 18 +- composer.lock | 2423 ++++++++++++++--- multisite-enhancements.php | 140 +- phpcs.xml | 24 +- phpunit.xml.dist | 2 +- readme.txt | 4 +- src/class-add-admin-favicon.php | 5 +- src/class-add-blog-id.php | 3 - src/class-add-css.php | 3 - src/class-add-plugin-list.php | 3 - src/class-add-site-status-labels.php | 2 - src/class-add-ssl-identifier.php | 13 +- src/class-add-theme-list.php | 2 - src/class-admin-bar-tweaks.php | 13 +- src/class-change-footer-text.php | 3 - src/class-core.php | 3 - src/class-filtering-themes.php | 2 - src/class-multisite-add-new-plugin.php | 3 - src/settings.php | 2 - tests/phpunit/Unit/AbstractTestCase.php | 34 - .../Unit/MultisiteEnhancementsTest.php | 18 +- tests/phpunit/Unit/TestCase.php | 25 + tests/phpunit/bootstrap.php | 2 +- 26 files changed, 2207 insertions(+), 552 deletions(-) delete mode 100755 tests/phpunit/Unit/AbstractTestCase.php create mode 100755 tests/phpunit/Unit/TestCase.php diff --git a/.ddev/config.yaml b/.ddev/config.yaml index 3780ca2..d6228b8 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -1,7 +1,7 @@ name: multisite-enhancements type: php docroot: .ddev/wordpress -php_version: "8.3" +php_version: "7.2" nodejs_version: "18" webserver_type: apache-fpm router_http_port: "80" @@ -20,11 +20,11 @@ hooks: - exec-host: "mkdir -p .ddev/wordpress/wp-content/plugins/${DDEV_PROJECT}" web_environment: - - WP_VERSION=6.5.3 + - WP_VERSION=6.5.4 - WP_LOCALE=de_DE - WP_TITLE=DDEV Search and Replace Test - WP_MULTISITE=true - - WP_MULTISITE_SLUGS=seite1,seite2 + - WP_MULTISITE_SLUGS=seite1,seite2,site3,site4,site5 - ADMIN_USER=admin - ADMIN_PASS=admin - ADMIN_EMAIL=admin@example.com diff --git a/.gitignore b/.gitignore index c2c5f29..2c7bcda 100755 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,6 @@ vendor .idea/ *.ipr *.iws + +# PHP Unit +.phpunit.result.cache diff --git a/CHANGELOG.md b/CHANGELOG.md index f3c3bd0..5c9d461 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file. This projec * Fix php note for favicon functionality. [#65](https://github.com/bueltge/wordpress-multisite-enhancements/issues/65) * Change dashicons from lock/unlock to yes/no to optimize the visual difference of the icon to spot http usage easier. Probs @Zodiac1978 [#76](https://github.com/bueltge/wordpress-multisite-enhancements/pull/70) +## [1.7.0](https://github.com/bueltge/wordpress-multisite-enhancements/compare/1.6.0...1.6.1) - 2024-06- +* Update min PHP Version to 7.2 + ## [1.6.1](https://github.com/bueltge/wordpress-multisite-enhancements/compare/1.6.0...1.6.1) - 2021-01-20 * Fix path for css/js files. diff --git a/composer.json b/composer.json index 67ed1fc..14e4d4b 100644 --- a/composer.json +++ b/composer.json @@ -21,20 +21,18 @@ "issues": "https://github.com/bueltge/wordpress-multisite-enhancements/issues" }, "require": { - "php": ">=5.3", - "composer/installers": "^1" + "php": ">=7.2" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "*", "phpcompatibility/phpcompatibility-wp": "^2.1", "squizlabs/php_codesniffer": "^3", - "wp-coding-standards/wpcs": "*" + "wp-coding-standards/wpcs": "*", + "phpunit/phpunit": "^11", + "brain/monkey": "^2.6" }, "config": { - "sort-packages": true, "optimize-autoloader": true, "allow-plugins": { - "composer/installers": true, "dealerdirect/phpcodesniffer-composer-installer": true } }, @@ -46,16 +44,14 @@ } }, "autoload": { - "psr-0": { - "": "src/" - }, "classmap": [ + "src/", "multisite-enhancements.php" ] }, "scripts": { - "cs": "@php ./vendor/squizlabs/php_codesniffer/bin/phpcs", - "csf": "@php ./vendor/bin/phpcbf", + "cs": "@php ./vendor/bin/phpcs", + "cbf": "@php ./vendor/bin/phpcbf", "pu": "@php ./vendor/bin/phpunit", "qa": [ "@cs", diff --git a/composer.lock b/composer.lock index 036922a..4c7a881 100644 --- a/composer.lock +++ b/composer.lock @@ -4,47 +4,94 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "ca1b434391a13c58368ce9c11bcf86da", - "packages": [ + "content-hash": "153b59cec742c8a8cb657035e298d965", + "packages": [], + "packages-dev": [ { - "name": "composer/installers", - "version": "v1.12.0", + "name": "antecedent/patchwork", + "version": "2.1.28", "source": { "type": "git", - "url": "https://github.com/composer/installers.git", - "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19" + "url": "https://github.com/antecedent/patchwork.git", + "reference": "6b30aff81ebadf0f2feb9268d3e08385cebcc08d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d20a64ed3c94748397ff5973488761b22f6d3f19", - "reference": "d20a64ed3c94748397ff5973488761b22f6d3f19", + "url": "https://api.github.com/repos/antecedent/patchwork/zipball/6b30aff81ebadf0f2feb9268d3e08385cebcc08d", + "reference": "6b30aff81ebadf0f2feb9268d3e08385cebcc08d", "shasum": "" }, "require": { - "composer-plugin-api": "^1.0 || ^2.0" + "php": ">=5.4.0" }, - "replace": { - "roundcube/plugin-installer": "*", - "shama/baton": "*" + "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": "https://antecedent.github.io/patchwork/", + "keywords": [ + "aop", + "aspect", + "interception", + "monkeypatching", + "redefinition", + "runkit", + "testing" + ], + "support": { + "issues": "https://github.com/antecedent/patchwork/issues", + "source": "https://github.com/antecedent/patchwork/tree/2.1.28" + }, + "time": "2024-02-06T09:26:11+00:00" + }, + { + "name": "brain/monkey", + "version": "2.6.1", + "source": { + "type": "git", + "url": "https://github.com/Brain-WP/BrainMonkey.git", + "reference": "a31c84515bb0d49be9310f52ef1733980ea8ffbb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Brain-WP/BrainMonkey/zipball/a31c84515bb0d49be9310f52ef1733980ea8ffbb", + "reference": "a31c84515bb0d49be9310f52ef1733980ea8ffbb", + "shasum": "" + }, + "require": { + "antecedent/patchwork": "^2.1.17", + "mockery/mockery": "^1.3.5 || ^1.4.4", + "php": ">=5.6.0" }, "require-dev": { - "composer/composer": "1.6.* || ^2.0", - "composer/semver": "^1 || ^3", - "phpstan/phpstan": "^0.12.55", - "phpstan/phpstan-phpunit": "^0.12.16", - "symfony/phpunit-bridge": "^4.2 || ^5", - "symfony/process": "^2.3" + "dealerdirect/phpcodesniffer-composer-installer": "^0.7.1", + "phpcompatibility/php-compatibility": "^9.3.0", + "phpunit/phpunit": "^5.7.26 || ^6.0 || ^7.0 || >=8.0 <8.5.12 || ^8.5.14 || ^9.0" }, - "type": "composer-plugin", + "type": "library", "extra": { - "class": "Composer\\Installers\\Plugin", "branch-alias": { - "dev-main": "1.x-dev" + "dev-version/1": "1.x-dev", + "dev-master": "2.0.x-dev" } }, "autoload": { + "files": [ + "inc/api.php" + ], "psr-4": { - "Composer\\Installers\\": "src/Composer/Installers" + "Brain\\Monkey\\": "src/" } }, "notification-url": "https://packagist.org/downloads/", @@ -53,112 +100,31 @@ ], "authors": [ { - "name": "Kyle Robinson Young", - "email": "kyle@dontkry.com", - "homepage": "https://github.com/shama" + "name": "Giuseppe Mazzapica", + "email": "giuseppe.mazzapica@gmail.com", + "homepage": "https://gmazzap.me", + "role": "Developer" } ], - "description": "A multi-framework Composer library installer", - "homepage": "https://composer.github.io/installers/", + "description": "Mocking utility for PHP functions and WordPress plugin API", "keywords": [ - "Craft", - "Dolibarr", - "Eliasis", - "Hurad", - "ImageCMS", - "Kanboard", - "Lan Management System", - "MODX Evo", - "MantisBT", - "Mautic", - "Maya", - "OXID", - "Plentymarkets", - "Porto", - "RadPHP", - "SMF", - "Starbug", - "Thelia", - "Whmcs", - "WolfCMS", - "agl", - "aimeos", - "annotatecms", - "attogram", - "bitrix", - "cakephp", - "chef", - "cockpit", - "codeigniter", - "concrete5", - "croogo", - "dokuwiki", - "drupal", - "eZ Platform", - "elgg", - "expressionengine", - "fuelphp", - "grav", - "installer", - "itop", - "joomla", - "known", - "kohana", - "laravel", - "lavalite", - "lithium", - "magento", - "majima", - "mako", - "mediawiki", - "miaoxing", - "modulework", - "modx", - "moodle", - "osclass", - "pantheon", - "phpbb", - "piwik", - "ppi", - "processwire", - "puppet", - "pxcms", - "reindex", - "roundcube", - "shopware", - "silverstripe", - "sydes", - "sylius", - "symfony", - "tastyigniter", - "typo3", - "wordpress", - "yawik", - "zend", - "zikula" - ], - "support": { - "issues": "https://github.com/composer/installers/issues", - "source": "https://github.com/composer/installers/tree/v1.12.0" - }, - "funding": [ - { - "url": "https://packagist.com", - "type": "custom" - }, - { - "url": "https://github.com/composer", - "type": "github" - }, - { - "url": "https://tidelift.com/funding/github/packagist/composer/composer", - "type": "tidelift" - } + "Monkey Patching", + "interception", + "mock", + "mock functions", + "mockery", + "patchwork", + "redefinition", + "runkit", + "test", + "testing" ], - "time": "2021-09-13T08:19:44+00:00" - } - ], - "packages-dev": [ + "support": { + "issues": "https://github.com/Brain-WP/BrainMonkey/issues", + "source": "https://github.com/Brain-WP/BrainMonkey" + }, + "time": "2021-11-11T15:53:55+00:00" + }, { "name": "dealerdirect/phpcodesniffer-composer-installer", "version": "v1.0.0", @@ -238,374 +204,2089 @@ "time": "2023-01-05T11:28:13+00:00" }, { - "name": "phpcompatibility/php-compatibility", - "version": "9.3.5", + "name": "hamcrest/hamcrest-php", + "version": "v2.0.1", "source": { "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" + "url": "https://github.com/hamcrest/hamcrest-php.git", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", - "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", + "url": "https://api.github.com/repos/hamcrest/hamcrest-php/zipball/8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", + "reference": "8c3d0a3f6af734494ad8f6fbbee0ba92422859f3", "shasum": "" }, "require": { - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + "php": "^5.3|^7.0|^8.0" }, - "conflict": { - "squizlabs/php_codesniffer": "2.6.2" + "replace": { + "cordoval/hamcrest-php": "*", + "davedevelopment/hamcrest-php": "*", + "kodova/hamcrest-php": "*" }, "require-dev": { - "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + "phpunit/php-file-iterator": "^1.4 || ^2.0", + "phpunit/phpunit": "^4.8.36 || ^5.7 || ^6.5 || ^7.0" }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "2.1-dev" + } + }, + "autoload": { + "classmap": [ + "hamcrest" + ] }, - "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "homepage": "https://github.com/wimg", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" - } + "BSD-3-Clause" ], - "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", - "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "description": "This is the PHP port of Hamcrest Matchers", "keywords": [ - "compatibility", - "phpcs", - "standards" + "test" ], "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", - "source": "https://github.com/PHPCompatibility/PHPCompatibility" + "issues": "https://github.com/hamcrest/hamcrest-php/issues", + "source": "https://github.com/hamcrest/hamcrest-php/tree/v2.0.1" }, - "time": "2019-12-27T09:44:58+00:00" + "time": "2020-07-09T08:09:16+00:00" }, { - "name": "phpcompatibility/phpcompatibility-paragonie", - "version": "1.3.3", + "name": "mockery/mockery", + "version": "1.6.12", "source": { "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", - "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac" + "url": "https://github.com/mockery/mockery.git", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/293975b465e0e709b571cbf0c957c6c0a7b9a2ac", - "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac", + "url": "https://api.github.com/repos/mockery/mockery/zipball/1f4efdd7d3beafe9807b08156dfcb176d18f1699", + "reference": "1f4efdd7d3beafe9807b08156dfcb176d18f1699", "shasum": "" }, "require": { - "phpcompatibility/php-compatibility": "^9.0" + "hamcrest/hamcrest-php": "^2.0.1", + "lib-pcre": ">=7.0", + "php": ">=7.3" + }, + "conflict": { + "phpunit/phpunit": "<8.0" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0", - "paragonie/random_compat": "dev-master", - "paragonie/sodium_compat": "dev-master" + "phpunit/phpunit": "^8.5 || ^9.6.17", + "symplify/easy-coding-standard": "^12.1.14" }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + "type": "library", + "autoload": { + "files": [ + "library/helpers.php", + "library/Mockery.php" + ], + "psr-4": { + "Mockery\\": "library/Mockery" + } }, - "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "BSD-3-Clause" ], "authors": [ { - "name": "Wim Godden", - "role": "lead" + "name": "Pádraic Brady", + "email": "padraic.brady@gmail.com", + "homepage": "https://github.com/padraic", + "role": "Author" }, { - "name": "Juliette Reinders Folmer", - "role": "lead" + "name": "Dave Marshall", + "email": "dave.marshall@atstsolutions.co.uk", + "homepage": "https://davedevelopment.co.uk", + "role": "Developer" + }, + { + "name": "Nathanael Esayeas", + "email": "nathanael.esayeas@protonmail.com", + "homepage": "https://github.com/ghostwriter", + "role": "Lead Developer" } ], - "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", - "homepage": "http://phpcompatibility.com/", + "description": "Mockery is a simple yet flexible PHP mock object framework", + "homepage": "https://github.com/mockery/mockery", "keywords": [ - "compatibility", - "paragonie", - "phpcs", - "polyfill", - "standards", - "static analysis" + "BDD", + "TDD", + "library", + "mock", + "mock objects", + "mockery", + "stub", + "test", + "test double", + "testing" ], "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", - "security": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/security/policy", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" + "docs": "https://docs.mockery.io/", + "issues": "https://github.com/mockery/mockery/issues", + "rss": "https://github.com/mockery/mockery/releases.atom", + "security": "https://github.com/mockery/mockery/security/advisories", + "source": "https://github.com/mockery/mockery" }, - "funding": [ - { - "url": "https://github.com/PHPCompatibility", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", - "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" - } - ], - "time": "2024-04-24T21:30:46+00:00" + "time": "2024-05-16T03:13:13+00:00" }, { - "name": "phpcompatibility/phpcompatibility-wp", - "version": "2.1.5", + "name": "myclabs/deep-copy", + "version": "1.11.1", "source": { "type": "git", - "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", - "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082" + "url": "https://github.com/myclabs/DeepCopy.git", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/01c1ff2704a58e46f0cb1ca9d06aee07b3589082", - "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", + "reference": "7284c22080590fb39f2ffa3e9057f10a4ddd0e0c", "shasum": "" }, "require": { - "phpcompatibility/php-compatibility": "^9.0", - "phpcompatibility/phpcompatibility-paragonie": "^1.0" + "php": "^7.1 || ^8.0" + }, + "conflict": { + "doctrine/collections": "<1.6.8", + "doctrine/common": "<2.13.3 || >=3,<3.2.2" }, "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0" + "doctrine/collections": "^1.6.8", + "doctrine/common": "^2.13.3 || ^3.2.2", + "phpunit/phpunit": "^7.5.20 || ^8.5.23 || ^9.5.13" }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", - "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + "type": "library", + "autoload": { + "files": [ + "src/DeepCopy/deep_copy.php" + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, - "type": "phpcodesniffer-standard", "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" - ], - "authors": [ - { - "name": "Wim Godden", - "role": "lead" - }, - { - "name": "Juliette Reinders Folmer", - "role": "lead" - } + "MIT" ], - "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", - "homepage": "http://phpcompatibility.com/", + "description": "Create deep copies (clones) of your objects", "keywords": [ - "compatibility", - "phpcs", - "standards", - "static analysis", - "wordpress" + "clone", + "copy", + "duplicate", + "object", + "object graph" ], "support": { - "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", - "security": "https://github.com/PHPCompatibility/PHPCompatibilityWP/security/policy", - "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" + "issues": "https://github.com/myclabs/DeepCopy/issues", + "source": "https://github.com/myclabs/DeepCopy/tree/1.11.1" }, "funding": [ { - "url": "https://github.com/PHPCompatibility", - "type": "github" - }, - { - "url": "https://github.com/jrfnl", - "type": "github" - }, - { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" + "url": "https://tidelift.com/funding/github/packagist/myclabs/deep-copy", + "type": "tidelift" } ], - "time": "2024-04-24T21:37:59+00:00" + "time": "2023-03-08T13:26:56+00:00" }, { - "name": "phpcsstandards/phpcsextra", - "version": "1.2.1", + "name": "nikic/php-parser", + "version": "v5.0.2", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", - "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489" + "url": "https://github.com/nikic/PHP-Parser.git", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", - "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", + "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", "shasum": "" }, "require": { - "php": ">=5.4", - "phpcsstandards/phpcsutils": "^1.0.9", - "squizlabs/php_codesniffer": "^3.8.0" + "ext-ctype": "*", + "ext-json": "*", + "ext-tokenizer": "*", + "php": ">=7.4" }, "require-dev": { - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcsstandards/phpcsdevcs": "^1.1.6", - "phpcsstandards/phpcsdevtools": "^1.2.1", - "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + "ircmaxell/php-yacc": "^0.0.7", + "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" }, - "type": "phpcodesniffer-standard", + "bin": [ + "bin/php-parse" + ], + "type": "library", "extra": { "branch-alias": { - "dev-stable": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-master": "5.0-dev" + } + }, + "autoload": { + "psr-4": { + "PhpParser\\": "lib/PhpParser" } }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "BSD-3-Clause" ], "authors": [ { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, - { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHPCSExtra/graphs/contributors" + "name": "Nikita Popov" } ], - "description": "A collection of sniffs and standards for use with PHP_CodeSniffer.", + "description": "A PHP parser written in PHP", "keywords": [ - "PHP_CodeSniffer", - "phpcbf", - "phpcodesniffer-standard", - "phpcs", - "standards", - "static analysis" + "parser", + "php" ], "support": { - "issues": "https://github.com/PHPCSStandards/PHPCSExtra/issues", - "security": "https://github.com/PHPCSStandards/PHPCSExtra/security/policy", - "source": "https://github.com/PHPCSStandards/PHPCSExtra" + "issues": "https://github.com/nikic/PHP-Parser/issues", + "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" }, - "funding": [ - { - "url": "https://github.com/PHPCSStandards", - "type": "github" - }, - { + "time": "2024-03-05T20:51:40+00:00" + }, + { + "name": "phar-io/manifest", + "version": "2.0.4", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "54750ef60c58e43759730615a392c31c80e23176" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/54750ef60c58e43759730615a392c31c80e23176", + "reference": "54750ef60c58e43759730615a392c31c80e23176", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "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)", + "support": { + "issues": "https://github.com/phar-io/manifest/issues", + "source": "https://github.com/phar-io/manifest/tree/2.0.4" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:33:53+00:00" + }, + { + "name": "phar-io/version", + "version": "3.2.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "reference": "4f7fd7836c6f332bb2933569e566a0d6c4cbed74", + "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", + "support": { + "issues": "https://github.com/phar-io/version/issues", + "source": "https://github.com/phar-io/version/tree/3.2.1" + }, + "time": "2022-02-21T01:04:05+00:00" + }, + { + "name": "phpcompatibility/php-compatibility", + "version": "9.3.5", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibility.git", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibility/zipball/9fb324479acf6f39452e0655d2429cc0d3914243", + "reference": "9fb324479acf6f39452e0655d2429cc0d3914243", + "shasum": "" + }, + "require": { + "php": ">=5.3", + "squizlabs/php_codesniffer": "^2.3 || ^3.0.2" + }, + "conflict": { + "squizlabs/php_codesniffer": "2.6.2" + }, + "require-dev": { + "phpunit/phpunit": "~4.5 || ^5.0 || ^6.0 || ^7.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "homepage": "https://github.com/wimg", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCompatibility/PHPCompatibility/graphs/contributors" + } + ], + "description": "A set of sniffs for PHP_CodeSniffer that checks for PHP cross-version compatibility.", + "homepage": "http://techblog.wimgodden.be/tag/codesniffer/", + "keywords": [ + "compatibility", + "phpcs", + "standards" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibility/issues", + "source": "https://github.com/PHPCompatibility/PHPCompatibility" + }, + "time": "2019-12-27T09:44:58+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-paragonie", + "version": "1.3.3", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie.git", + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityParagonie/zipball/293975b465e0e709b571cbf0c957c6c0a7b9a2ac", + "reference": "293975b465e0e709b571cbf0c957c6c0a7b9a2ac", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0", + "paragonie/random_compat": "dev-master", + "paragonie/sodium_compat": "dev-master" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A set of rulesets for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by the Paragonie polyfill libraries.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "paragonie", + "phpcs", + "polyfill", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/issues", + "security": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie/security/policy", + "source": "https://github.com/PHPCompatibility/PHPCompatibilityParagonie" + }, + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { "url": "https://github.com/jrfnl", "type": "github" }, { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:30:46+00:00" + }, + { + "name": "phpcompatibility/phpcompatibility-wp", + "version": "2.1.5", + "source": { + "type": "git", + "url": "https://github.com/PHPCompatibility/PHPCompatibilityWP.git", + "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCompatibility/PHPCompatibilityWP/zipball/01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "reference": "01c1ff2704a58e46f0cb1ca9d06aee07b3589082", + "shasum": "" + }, + "require": { + "phpcompatibility/php-compatibility": "^9.0", + "phpcompatibility/phpcompatibility-paragonie": "^1.0" + }, + "require-dev": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0" + }, + "suggest": { + "dealerdirect/phpcodesniffer-composer-installer": "^1.0 || This Composer plugin will sort out the PHP_CodeSniffer 'installed_paths' automatically.", + "roave/security-advisories": "dev-master || Helps prevent installing dependencies with known security issues." + }, + "type": "phpcodesniffer-standard", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Wim Godden", + "role": "lead" + }, + { + "name": "Juliette Reinders Folmer", + "role": "lead" + } + ], + "description": "A ruleset for PHP_CodeSniffer to check for PHP cross-version compatibility issues in projects, while accounting for polyfills provided by WordPress.", + "homepage": "http://phpcompatibility.com/", + "keywords": [ + "compatibility", + "phpcs", + "standards", + "static analysis", + "wordpress" + ], + "support": { + "issues": "https://github.com/PHPCompatibility/PHPCompatibilityWP/issues", + "security": "https://github.com/PHPCompatibility/PHPCompatibilityWP/security/policy", + "source": "https://github.com/PHPCompatibility/PHPCompatibilityWP" + }, + "funding": [ + { + "url": "https://github.com/PHPCompatibility", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-04-24T21:37:59+00:00" + }, + { + "name": "phpcsstandards/phpcsextra", + "version": "1.2.1", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHPCSExtra.git", + "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSExtra/zipball/11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", + "reference": "11d387c6642b6e4acaf0bd9bf5203b8cca1ec489", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "phpcsstandards/phpcsutils": "^1.0.9", + "squizlabs/php_codesniffer": "^3.8.0" + }, + "require-dev": { + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcsstandards/phpcsdevcs": "^1.1.6", + "phpcsstandards/phpcsdevtools": "^1.2.1", + "phpunit/phpunit": "^4.5 || ^5.0 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-stable": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHPCSExtra/graphs/contributors" + } + ], + "description": "A collection of sniffs and standards for use with PHP_CodeSniffer.", + "keywords": [ + "PHP_CodeSniffer", + "phpcbf", + "phpcodesniffer-standard", + "phpcs", + "standards", + "static analysis" + ], + "support": { + "issues": "https://github.com/PHPCSStandards/PHPCSExtra/issues", + "security": "https://github.com/PHPCSStandards/PHPCSExtra/security/policy", + "source": "https://github.com/PHPCSStandards/PHPCSExtra" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2023-12-08T16:49:07+00:00" + }, + { + "name": "phpcsstandards/phpcsutils", + "version": "1.0.12", + "source": { + "type": "git", + "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", + "reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/87b233b00daf83fb70f40c9a28692be017ea7c6c", + "reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c", + "shasum": "" + }, + "require": { + "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", + "php": ">=5.4", + "squizlabs/php_codesniffer": "^3.10.0 || 4.0.x-dev@dev" + }, + "require-dev": { + "ext-filter": "*", + "php-parallel-lint/php-console-highlighter": "^1.0", + "php-parallel-lint/php-parallel-lint": "^1.3.2", + "phpcsstandards/phpcsdevcs": "^1.1.6", + "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0" + }, + "type": "phpcodesniffer-standard", + "extra": { + "branch-alias": { + "dev-stable": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "classmap": [ + "PHPCSUtils/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-3.0-or-later" + ], + "authors": [ + { + "name": "Juliette Reinders Folmer", + "homepage": "https://github.com/jrfnl", + "role": "lead" + }, + { + "name": "Contributors", + "homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors" + } + ], + "description": "A suite of utility functions for use with PHP_CodeSniffer", + "homepage": "https://phpcsutils.com/", + "keywords": [ + "PHP_CodeSniffer", + "phpcbf", + "phpcodesniffer-standard", + "phpcs", + "phpcs3", + "standards", + "static analysis", + "tokens", + "utility" + ], + "support": { + "docs": "https://phpcsutils.com/", + "issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues", + "security": "https://github.com/PHPCSStandards/PHPCSUtils/security/policy", + "source": "https://github.com/PHPCSStandards/PHPCSUtils" + }, + "funding": [ + { + "url": "https://github.com/PHPCSStandards", + "type": "github" + }, + { + "url": "https://github.com/jrfnl", + "type": "github" + }, + { + "url": "https://opencollective.com/php_codesniffer", + "type": "open_collective" + } + ], + "time": "2024-05-20T13:34:27+00:00" + }, + { + "name": "phpunit/php-code-coverage", + "version": "11.0.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-code-coverage.git", + "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-libxml": "*", + "ext-xmlwriter": "*", + "nikic/php-parser": "^5.0", + "php": ">=8.2", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-text-template": "^4.0", + "sebastian/code-unit-reverse-lookup": "^4.0", + "sebastian/complexity": "^4.0", + "sebastian/environment": "^7.0", + "sebastian/lines-of-code": "^3.0", + "sebastian/version": "^5.0", + "theseer/tokenizer": "^1.2.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcov": "PHP extension that provides line coverage", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.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 provides collection, processing, and rendering functionality for PHP code coverage information.", + "homepage": "https://github.com/sebastianbergmann/php-code-coverage", + "keywords": [ + "coverage", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", + "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.3" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-12T15:35:40+00:00" + }, + { + "name": "phpunit/php-file-iterator", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-file-iterator.git", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/99e95c94ad9500daca992354fa09d7b99abe2210", + "reference": "99e95c94ad9500daca992354fa09d7b99abe2210", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "FilterIterator implementation that filters files based on a list of suffixes.", + "homepage": "https://github.com/sebastianbergmann/php-file-iterator/", + "keywords": [ + "filesystem", + "iterator" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", + "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:05:04+00:00" + }, + { + "name": "phpunit/php-invoker", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-invoker.git", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "ext-pcntl": "*", + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-pcntl": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "Invoke callables with a timeout", + "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "keywords": [ + "process" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-invoker/issues", + "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", + "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:05:50+00:00" + }, + { + "name": "phpunit/php-text-template", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/d38f6cbff1cdb6f40b03c9811421561668cc133e", + "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.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" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:06:56+00:00" + }, + { + "name": "phpunit/php-timer", + "version": "7.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8a59d9e25720482ee7fcdf296595e08795b84dc5", + "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "security": "https://github.com/sebastianbergmann/php-timer/security/policy", + "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:08:01+00:00" + }, + { + "name": "phpunit/phpunit", + "version": "11.1.3", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/phpunit.git", + "reference": "d475be032238173ca3b0a516f5cc291d174708ae" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d475be032238173ca3b0a516f5cc291d174708ae", + "reference": "d475be032238173ca3b0a516f5cc291d174708ae", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-json": "*", + "ext-libxml": "*", + "ext-mbstring": "*", + "ext-xml": "*", + "ext-xmlwriter": "*", + "myclabs/deep-copy": "^1.10.1", + "phar-io/manifest": "^2.0.3", + "phar-io/version": "^3.0.2", + "php": ">=8.2", + "phpunit/php-code-coverage": "^11.0", + "phpunit/php-file-iterator": "^5.0", + "phpunit/php-invoker": "^5.0", + "phpunit/php-text-template": "^4.0", + "phpunit/php-timer": "^7.0", + "sebastian/cli-parser": "^3.0", + "sebastian/code-unit": "^3.0", + "sebastian/comparator": "^6.0", + "sebastian/diff": "^6.0", + "sebastian/environment": "^7.0", + "sebastian/exporter": "^6.0", + "sebastian/global-state": "^7.0", + "sebastian/object-enumerator": "^6.0", + "sebastian/type": "^5.0", + "sebastian/version": "^5.0" + }, + "suggest": { + "ext-soap": "To be able to generate mocks based on WSDL files" + }, + "bin": [ + "phpunit" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "11.1-dev" + } + }, + "autoload": { + "files": [ + "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "The PHP Unit Testing framework.", + "homepage": "https://phpunit.de/", + "keywords": [ + "phpunit", + "testing", + "xunit" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/phpunit/issues", + "security": "https://github.com/sebastianbergmann/phpunit/security/policy", + "source": "https://github.com/sebastianbergmann/phpunit/tree/11.1.3" + }, + "funding": [ + { + "url": "https://phpunit.de/sponsors.html", + "type": "custom" + }, + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/phpunit/phpunit", + "type": "tidelift" + } + ], + "time": "2024-04-24T06:34:25+00:00" + }, + { + "name": "sebastian/cli-parser", + "version": "3.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/cli-parser.git", + "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/00a74d5568694711f0222e54fb281e1d15fdf04a", + "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for parsing CLI options", + "homepage": "https://github.com/sebastianbergmann/cli-parser", + "support": { + "issues": "https://github.com/sebastianbergmann/cli-parser/issues", + "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", + "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:26:58+00:00" + }, + { + "name": "sebastian/code-unit", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit.git", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6634549cb8d702282a04a774e36a7477d2bd9015", + "reference": "6634549cb8d702282a04a774e36a7477d2bd9015", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Collection of value objects that represent the PHP code units", + "homepage": "https://github.com/sebastianbergmann/code-unit", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit/issues", + "security": "https://github.com/sebastianbergmann/code-unit/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:50:41+00:00" + }, + { + "name": "sebastian/code-unit-reverse-lookup", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "Looks up which function or method a line of code belongs to", + "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", + "support": { + "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", + "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:52:17+00:00" + }, + { + "name": "sebastian/comparator", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/comparator.git", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/diff": "^6.0", + "sebastian/exporter": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@2bepublished.at" + } + ], + "description": "Provides the functionality to compare PHP values for equality", + "homepage": "https://github.com/sebastianbergmann/comparator", + "keywords": [ + "comparator", + "compare", + "equality" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/comparator/issues", + "security": "https://github.com/sebastianbergmann/comparator/security/policy", + "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:53:45+00:00" + }, + { + "name": "sebastian/complexity", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/complexity.git", + "reference": "88a434ad86150e11a606ac4866b09130712671f0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/88a434ad86150e11a606ac4866b09130712671f0", + "reference": "88a434ad86150e11a606ac4866b09130712671f0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "4.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" + } + ], + "description": "Library for calculating the complexity of PHP code units", + "homepage": "https://github.com/sebastianbergmann/complexity", + "support": { + "issues": "https://github.com/sebastianbergmann/complexity/issues", + "security": "https://github.com/sebastianbergmann/complexity/security/policy", + "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T05:55:19+00:00" + }, + { + "name": "sebastian/diff", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/diff.git", + "reference": "ab83243ecc233de5655b76f577711de9f842e712" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712", + "reference": "ab83243ecc233de5655b76f577711de9f842e712", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0", + "symfony/process": "^4.2 || ^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Kore Nordmann", + "email": "mail@kore-nordmann.de" + } + ], + "description": "Diff implementation", + "homepage": "https://github.com/sebastianbergmann/diff", + "keywords": [ + "diff", + "udiff", + "unidiff", + "unified diff" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/diff/issues", + "security": "https://github.com/sebastianbergmann/diff/security/policy", + "source": "https://github.com/sebastianbergmann/diff/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:30:33+00:00" + }, + { + "name": "sebastian/environment", + "version": "7.1.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/environment.git", + "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "suggest": { + "ext-posix": "*" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Provides functionality to handle HHVM/PHP environments", + "homepage": "https://github.com/sebastianbergmann/environment", + "keywords": [ + "Xdebug", + "environment", + "hhvm" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/environment/issues", + "security": "https://github.com/sebastianbergmann/environment/security/policy", + "source": "https://github.com/sebastianbergmann/environment/tree/7.1.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-23T08:56:34+00:00" + }, + { + "name": "sebastian/exporter", + "version": "6.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/exporter.git", + "reference": "f291e5a317c321c0381fa9ecc796fa2d21b186da" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f291e5a317c321c0381fa9ecc796fa2d21b186da", + "reference": "f291e5a317c321c0381fa9ecc796fa2d21b186da", + "shasum": "" + }, + "require": { + "ext-mbstring": "*", + "php": ">=8.2", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Volker Dusch", + "email": "github@wallbash.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" + }, + { + "name": "Bernhard Schussek", + "email": "bschussek@gmail.com" + } + ], + "description": "Provides the functionality to export PHP variables for visualization", + "homepage": "https://www.github.com/sebastianbergmann/exporter", + "keywords": [ + "export", + "exporter" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/exporter/issues", + "security": "https://github.com/sebastianbergmann/exporter/security/policy", + "source": "https://github.com/sebastianbergmann/exporter/tree/6.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:28:20+00:00" + }, + { + "name": "sebastian/global-state", + "version": "7.0.1", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/global-state.git", + "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "shasum": "" + }, + "require": { + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" + }, + "require-dev": { + "ext-dom": "*", + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "7.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": "https://www.github.com/sebastianbergmann/global-state", + "keywords": [ + "global state" + ], + "support": { + "issues": "https://github.com/sebastianbergmann/global-state/issues", + "security": "https://github.com/sebastianbergmann/global-state/security/policy", + "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.1" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-03-02T07:32:10+00:00" + }, + { + "name": "sebastian/lines-of-code", + "version": "3.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/lines-of-code.git", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/376c5b3f6b43c78fdc049740bca76a7c846706c0", + "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0", + "shasum": "" + }, + "require": { + "nikic/php-parser": "^5.0", + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "3.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "lead" } ], - "time": "2023-12-08T16:49:07+00:00" + "description": "Library for counting the lines of code in PHP source code", + "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "support": { + "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", + "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", + "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:00:36+00:00" }, { - "name": "phpcsstandards/phpcsutils", - "version": "1.0.12", + "name": "sebastian/object-enumerator", + "version": "6.0.0", "source": { "type": "git", - "url": "https://github.com/PHPCSStandards/PHPCSUtils.git", - "reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/PHPCSStandards/PHPCSUtils/zipball/87b233b00daf83fb70f40c9a28692be017ea7c6c", - "reference": "87b233b00daf83fb70f40c9a28692be017ea7c6c", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", "shasum": "" }, "require": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.4.1 || ^0.5 || ^0.6.2 || ^0.7 || ^1.0", - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.10.0 || 4.0.x-dev@dev" + "php": ">=8.2", + "sebastian/object-reflector": "^4.0", + "sebastian/recursion-context": "^6.0" }, "require-dev": { - "ext-filter": "*", - "php-parallel-lint/php-console-highlighter": "^1.0", - "php-parallel-lint/php-parallel-lint": "^1.3.2", - "phpcsstandards/phpcsdevcs": "^1.1.6", - "yoast/phpunit-polyfills": "^1.1.0 || ^2.0.0" + "phpunit/phpunit": "^11.0" }, - "type": "phpcodesniffer-standard", + "type": "library", "extra": { "branch-alias": { - "dev-stable": "1.x-dev", - "dev-develop": "1.x-dev" + "dev-main": "6.0-dev" } }, "autoload": { "classmap": [ - "PHPCSUtils/" + "src/" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ - "LGPL-3.0-or-later" + "BSD-3-Clause" ], "authors": [ { - "name": "Juliette Reinders Folmer", - "homepage": "https://github.com/jrfnl", - "role": "lead" - }, + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "support": { + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.0" + }, + "funding": [ { - "name": "Contributors", - "homepage": "https://github.com/PHPCSStandards/PHPCSUtils/graphs/contributors" + "url": "https://github.com/sebastianbergmann", + "type": "github" } ], - "description": "A suite of utility functions for use with PHP_CodeSniffer", - "homepage": "https://phpcsutils.com/", - "keywords": [ - "PHP_CodeSniffer", - "phpcbf", - "phpcodesniffer-standard", - "phpcs", - "phpcs3", - "standards", - "static analysis", - "tokens", - "utility" + "time": "2024-02-02T06:01:29+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "4.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/bb2a6255d30853425fd38f032eb64ced9f7f132d", + "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "docs": "https://phpcsutils.com/", - "issues": "https://github.com/PHPCSStandards/PHPCSUtils/issues", - "security": "https://github.com/PHPCSStandards/PHPCSUtils/security/policy", - "source": "https://github.com/PHPCSStandards/PHPCSUtils" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.0" }, "funding": [ { - "url": "https://github.com/PHPCSStandards", + "url": "https://github.com/sebastianbergmann", "type": "github" + } + ], + "time": "2024-02-02T06:02:18+00:00" + }, + { + "name": "sebastian/recursion-context", + "version": "6.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "6.0-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" }, { - "url": "https://github.com/jrfnl", - "type": "github" + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" }, { - "url": "https://opencollective.com/php_codesniffer", - "type": "open_collective" + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "time": "2024-05-20T13:34:27+00:00" + "description": "Provides functionality to recursively process PHP variables", + "homepage": "https://github.com/sebastianbergmann/recursion-context", + "support": { + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:08:48+00:00" + }, + { + "name": "sebastian/type", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/type.git", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8502785eb3523ca0dd4afe9ca62235590020f3f", + "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "require-dev": { + "phpunit/phpunit": "^11.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "Collection of value objects that represent the types of the PHP type system", + "homepage": "https://github.com/sebastianbergmann/type", + "support": { + "issues": "https://github.com/sebastianbergmann/type/issues", + "security": "https://github.com/sebastianbergmann/type/security/policy", + "source": "https://github.com/sebastianbergmann/type/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:09:34+00:00" + }, + { + "name": "sebastian/version", + "version": "5.0.0", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/version.git", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/13999475d2cb1ab33cb73403ba356a814fdbb001", + "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001", + "shasum": "" + }, + "require": { + "php": ">=8.2" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "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": "Library that helps with managing the version number of Git-hosted PHP projects", + "homepage": "https://github.com/sebastianbergmann/version", + "support": { + "issues": "https://github.com/sebastianbergmann/version/issues", + "security": "https://github.com/sebastianbergmann/version/security/policy", + "source": "https://github.com/sebastianbergmann/version/tree/5.0.0" + }, + "funding": [ + { + "url": "https://github.com/sebastianbergmann", + "type": "github" + } + ], + "time": "2024-02-02T06:10:47+00:00" }, { "name": "squizlabs/php_codesniffer", @@ -687,6 +2368,56 @@ ], "time": "2024-05-22T21:24:41+00:00" }, + { + "name": "theseer/tokenizer", + "version": "1.2.3", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "reference": "737eda637ed5e28c3413cb1ebe8bb52cbf1ca7a2", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.2 || ^8.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "support": { + "issues": "https://github.com/theseer/tokenizer/issues", + "source": "https://github.com/theseer/tokenizer/tree/1.2.3" + }, + "funding": [ + { + "url": "https://github.com/theseer", + "type": "github" + } + ], + "time": "2024-03-03T12:36:25+00:00" + }, { "name": "wp-coding-standards/wpcs", "version": "3.1.0", @@ -760,7 +2491,7 @@ "prefer-stable": true, "prefer-lowest": false, "platform": { - "php": ">=5.3" + "php": ">=7.2" }, "platform-dev": [], "plugin-api-version": "2.6.0" diff --git a/multisite-enhancements.php b/multisite-enhancements.php index d35cb3b..1b515a5 100755 --- a/multisite-enhancements.php +++ b/multisite-enhancements.php @@ -1,16 +1,17 @@ -load_translation(); - // Since 2015-08-18 only PHP 5.3, use now __DIR__ as equivalent to dirname(__FILE__). - self::$file_base = __DIR__ . '/src'; self::load(); } @@ -77,80 +67,59 @@ public function load_translation() { } /** - * Load all files in folder src. - * Use the filter hook 'multisite_enhancements_autoload' to unset classes, there is not necessary for you. + * Autoload and init used functions. * * @since 0.0.1 */ public static function load() { - $file_base = self::$file_base; - define( 'MULTISITE_ENHANCEMENT_BASE', $file_base ); - - // Load configuration settings. - require_once $file_base . '/settings.php'; - - $autoload_paths = glob( "$file_base/*.php" ); - $autoload_files = array(); - - foreach ( $autoload_paths as $classnames => $path ) { - $path_split = explode( DIRECTORY_SEPARATOR, $path ); - $class = end( $path_split ); - $autoload_files[ $class ] = $path; - } - - $autoload_files = (array) apply_filters( 'multisite_enhancements_autoload', $autoload_files ); - - // Remove from autoload classes for disabled features. - $feature_modules = array( - 'class-add-admin-favicon.php' => array( 'add-favicon', 'remove-logo' ), - 'class-add-blog-id.php' => 'add-blog-id', - 'class-add-css.php' => 'add-css', - 'class-add-plugin-list.php' => 'add-plugin-list', - 'class-add-site-status-labels.php' => 'add-site-status', - 'class-add-ssl-identifier.php' => 'add-ssl-identifier', - 'class-add-theme-list.php' => 'add-theme-list', - 'class-admin-bar-tweaks.php' => 'add-manage-comments', - 'class-change-footer-text.php' => 'change-footer', - 'class-filtering-themes.php' => 'filtering-themes', - 'class-multisite-add-new-plugin.php' => 'add-new-plugin', + define( 'MULTISITE_ENHANCEMENT_BASE', __DIR__ . '/src' ); + + require_once __DIR__ . '/vendor/autoload.php'; + + add_action( 'init', array( 'Multisite_Enhancements_Settings', 'init' ) ); + add_action( 'init', array( 'Multisite_Core', 'init' ) ); + + $modules = array( + 'add-favicon' => array( 'init' => array( 'Multisite_Add_Admin_Favicon', 'init' ) ), + 'remove-logo' => array( 'init' => array( 'Multisite_Add_Admin_Favicon', 'init' ) ), + 'add-blog-id' => array( 'init' => array( 'Multisite_Add_Blog_Id', 'init' ) ), + 'add-css' => array( 'init' => array( 'Add_Css', 'init' ) ), + 'add-plugin-list' => array( 'init' => array( 'Multisite_Add_Plugin_List', 'init' ) ), + 'add-site-status' => array( 'init' => array( 'Multisite_Add_Site_Status_labels', 'init' ) ), + 'add-ssl-identifier' => array( + 'admin_init' => function () { + $multisite_add_ssh_identifier = new Bueltge\Multisite_Add_Ssh_Identifier\Multisite_Add_Ssh_Identifier(); + $multisite_add_ssh_identifier->init(); + }, + ), + 'add-theme-list' => array( 'init' => array( 'Multisite_Add_Theme_List', 'init' ) ), + 'add-manage-comments' => array( + 'init' => function () { + $multisite_admin_bar_tweaks = new Bueltge\Admin_Bar_Tweaks\Multisite_Admin_Bar_Tweaks(); + $multisite_admin_bar_tweaks->init(); + }, + ), + 'change-footer' => array( 'init' => array( 'Multisite_Change_Footer_Text', 'init' ) ), + 'filtering-themes' => array( 'admin_init' => array( 'Filtering_Themes', 'init' ) ), + 'add-new-plugin' => array( 'init' => array( 'Multisite_Add_New_Plugin', 'init' ) ), ); - foreach ( $feature_modules as $file => $settings ) { - if ( is_array( $settings ) ) { - $enabled = array_reduce( - $settings, - function ( $carry, $item ) { - return $carry || Multisite_Enhancements_Settings::is_feature_enabled( $item ); - }, - false - ); - } else { - $enabled = Multisite_Enhancements_Settings::is_feature_enabled( $settings ); - } - - if ( ! $enabled ) { - unset( $autoload_files[ $file ] ); + foreach ( $modules as $id => $hooks ) { + if ( Multisite_Enhancements_Settings::is_feature_enabled( $id ) ) { + foreach ( $hooks as $hook_name => $callback ) { + if ( ! has_action( $hook_name, $callback ) ) { + add_action( $hook_name, $callback ); + } + } } } - - // Load files. - foreach ( $autoload_files as $path ) { - /** - * Path of each file, that we load. - * - * @var string $path - */ - // phpcs:disable - require_once $path; - // phpcs: enable - } } /** * Load the object and get the current state. * - * @return String $class_object - * @since 0.0.1 + * @return Multisite_Enhancements $class_object + * @since 0.0.1 */ public static function get_object() { if ( null === self::$class_object ) { @@ -176,7 +145,7 @@ public function error_msg_no_multisite() { 'multisite-enhancements' ); ?> - ^/tests/* + - + + + + + @@ -16,13 +22,15 @@ - - - + + + *\.php$ + - + + + @@ -46,8 +54,4 @@ - - - - diff --git a/phpunit.xml.dist b/phpunit.xml.dist index 2895cda..bf93852 100755 --- a/phpunit.xml.dist +++ b/phpunit.xml.dist @@ -1,7 +1,7 @@ remove_node( 'wp-logo' ); } } - } // end class diff --git a/src/class-add-blog-id.php b/src/class-add-blog-id.php index 51a64d3..328096a 100755 --- a/src/class-add-blog-id.php +++ b/src/class-add-blog-id.php @@ -8,8 +8,6 @@ * @package multisite-enhancements */ -add_action( 'init', array( 'Multisite_Add_Blog_Id', 'init' ) ); - /** * View Blog and User ID in WordPress Multisite. * Class Multisite_Add_Blog_Id @@ -102,5 +100,4 @@ public function get_id( $columns ) { public function add_style() { echo ''; } - } // end class diff --git a/src/class-add-css.php b/src/class-add-css.php index 4f47d24..dad1719 100755 --- a/src/class-add-css.php +++ b/src/class-add-css.php @@ -13,8 +13,6 @@ * @package multisite-enhancements */ -add_action( 'init', array( 'Add_Css', 'init' ) ); - /** * On the network plugin and theme pages, add css to present the active column * If this class is loaded, modify the presentation of the column in order to @@ -62,5 +60,4 @@ public function enqueue_style( $hook ) { ); wp_enqueue_style( 'admin_column_css' ); } - } // end class diff --git a/src/class-add-plugin-list.php b/src/class-add-plugin-list.php index 636cbf1..05f3ec1 100755 --- a/src/class-add-plugin-list.php +++ b/src/class-add-plugin-list.php @@ -7,8 +7,6 @@ * @package WordPress */ -add_action( 'init', array( 'Multisite_Add_Plugin_List', 'init' ) ); - /** * Class Multisite_Add_Plugin_List */ @@ -375,5 +373,4 @@ public function is_deleted( $site_id ) { return (bool) get_blog_details( $site_id )->deleted; } - } // end class diff --git a/src/class-add-site-status-labels.php b/src/class-add-site-status-labels.php index 81dc707..db38afc 100755 --- a/src/class-add-site-status-labels.php +++ b/src/class-add-site-status-labels.php @@ -7,8 +7,6 @@ * @package WordPress */ -add_action( 'init', array( 'Multisite_Add_Site_Status_labels', 'init' ) ); - /** * Add status labels to sites. * diff --git a/src/class-add-ssl-identifier.php b/src/class-add-ssl-identifier.php index 563ff54..dba3690 100755 --- a/src/class-add-ssl-identifier.php +++ b/src/class-add-ssl-identifier.php @@ -9,16 +9,6 @@ namespace Bueltge\Multisite_Add_Ssh_Identifier; -add_action( 'admin_init', __NAMESPACE__ . '\\bootstrap' ); - -/** - * Create the instance of this class. - */ -function bootstrap() { - $multisite_add_ssh_identifier = new Multisite_Add_Ssh_Identifier(); - $multisite_add_ssh_identifier->init(); -} - /** * Class Multisite_Add_Ssh_Identifier */ @@ -46,7 +36,8 @@ public function init() { * * Multisite_Add_Ssh_Identifier constructor. */ - public function __construct() {} + public function __construct() { + } /** * Determines if SSL is used. diff --git a/src/class-add-theme-list.php b/src/class-add-theme-list.php index 0758594..3419985 100755 --- a/src/class-add-theme-list.php +++ b/src/class-add-theme-list.php @@ -7,8 +7,6 @@ * @package multisite-enhancement */ -add_action( 'init', array( 'Multisite_Add_Theme_List', 'init' ) ); - /** * On the network theme page, show which blog have the theme active. * diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index c5609e4..5098737 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -9,14 +9,6 @@ namespace Bueltge\Admin_Bar_Tweaks; -add_action( - 'init', - function () { - $multisite_admin_bar_tweaks = new Multisite_Admin_Bar_Tweaks(); - $multisite_admin_bar_tweaks->init(); - } -); - /** * Class Multisite_Admin_Bar_Tweaks */ @@ -65,8 +57,8 @@ public function enhance_network_blog_admin_bar() { $awaiting_mod = $awaiting_mod->moderated; $title = esc_html__( 'Manage Comments' ) - . '' . number_format_i18n( $awaiting_mod ) . ''; + . '' . number_format_i18n( $awaiting_mod ) . ''; $awaiting_title = esc_attr( sprintf( @@ -93,5 +85,4 @@ public function enhance_network_blog_admin_bar() { restore_current_blog(); } } - } // end class diff --git a/src/class-change-footer-text.php b/src/class-change-footer-text.php index 8bc94c6..53d92b6 100755 --- a/src/class-change-footer-text.php +++ b/src/class-change-footer-text.php @@ -20,8 +20,6 @@ * @package WordPress */ -add_action( 'init', array( 'Multisite_Change_Footer_Text', 'init' ) ); - /** * Class Multisite_Change_Footer_Text */ @@ -148,5 +146,4 @@ public function get_footer_text( $footer_text ) { */ return apply_filters( 'multisite_enhancements_admin_footer_text', $footer_text ); } - } // end class diff --git a/src/class-core.php b/src/class-core.php index 7cad1af..9d6ade3 100755 --- a/src/class-core.php +++ b/src/class-core.php @@ -7,8 +7,6 @@ * @package WordPress */ -add_action( 'init', array( 'Multisite_Core', 'init' ) ); - /** * Class Multisite_Core */ @@ -156,5 +154,4 @@ public static function get_blog_list( $start = 0, $num = 10, $details = false, $ return $blogs; } - } // end class diff --git a/src/class-filtering-themes.php b/src/class-filtering-themes.php index 89fd45d..d60594c 100755 --- a/src/class-filtering-themes.php +++ b/src/class-filtering-themes.php @@ -6,8 +6,6 @@ * @package WordPress */ -add_action( 'admin_init', array( 'Filtering_Themes', 'init' ) ); - /** * Class Filtering_Themes */ diff --git a/src/class-multisite-add-new-plugin.php b/src/class-multisite-add-new-plugin.php index 335d0f6..ba8e11f 100755 --- a/src/class-multisite-add-new-plugin.php +++ b/src/class-multisite-add-new-plugin.php @@ -7,8 +7,6 @@ * @package WordPress */ -add_action( 'init', array( 'Multisite_Add_New_Plugin', 'init' ) ); - /** * Class Multisite_Add_New_Plugin */ @@ -54,5 +52,4 @@ public function add_plugins_page() { 'plugin-install.php' ); } - } // end class diff --git a/src/settings.php b/src/settings.php index 16d6831..30bc28f 100644 --- a/src/settings.php +++ b/src/settings.php @@ -6,8 +6,6 @@ * @package multisite-enhancements */ -add_action( 'init', array( 'Multisite_Enhancements_Settings', 'init' ) ); - /** * Class Multisite_Enhancements_Settings */ diff --git a/tests/phpunit/Unit/AbstractTestCase.php b/tests/phpunit/Unit/AbstractTestCase.php deleted file mode 100755 index 64731b1..0000000 --- a/tests/phpunit/Unit/AbstractTestCase.php +++ /dev/null @@ -1,34 +0,0 @@ - Date: Thu, 6 Jun 2024 14:17:40 +0200 Subject: [PATCH 02/17] use phpunit 8 becasuse of PHP 7.2 --- composer.json | 2 +- composer.lock | 847 +++++++++++++++++++------------------------------- 2 files changed, 319 insertions(+), 530 deletions(-) diff --git a/composer.json b/composer.json index 14e4d4b..7a810f7 100644 --- a/composer.json +++ b/composer.json @@ -27,7 +27,7 @@ "phpcompatibility/phpcompatibility-wp": "^2.1", "squizlabs/php_codesniffer": "^3", "wp-coding-standards/wpcs": "*", - "phpunit/phpunit": "^11", + "phpunit/phpunit": "^8", "brain/monkey": "^2.6" }, "config": { diff --git a/composer.lock b/composer.lock index 4c7a881..db5279a 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "153b59cec742c8a8cb657035e298d965", + "content-hash": "00abe3dee94faa2c97e227a81fcf41b3", "packages": [], "packages-dev": [ { @@ -203,6 +203,76 @@ }, "time": "2023-01-05T11:28:13+00:00" }, + { + "name": "doctrine/instantiator", + "version": "1.5.0", + "source": { + "type": "git", + "url": "https://github.com/doctrine/instantiator.git", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/0a0fa9780f5d4e507415a065172d26a98d02047b", + "reference": "0a0fa9780f5d4e507415a065172d26a98d02047b", + "shasum": "" + }, + "require": { + "php": "^7.1 || ^8.0" + }, + "require-dev": { + "doctrine/coding-standard": "^9 || ^11", + "ext-pdo": "*", + "ext-phar": "*", + "phpbench/phpbench": "^0.16 || ^1", + "phpstan/phpstan": "^1.4", + "phpstan/phpstan-phpunit": "^1", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.30 || ^5.4" + }, + "type": "library", + "autoload": { + "psr-4": { + "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Marco Pivetta", + "email": "ocramius@gmail.com", + "homepage": "https://ocramius.github.io/" + } + ], + "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors", + "homepage": "https://www.doctrine-project.org/projects/instantiator.html", + "keywords": [ + "constructor", + "instantiate" + ], + "support": { + "issues": "https://github.com/doctrine/instantiator/issues", + "source": "https://github.com/doctrine/instantiator/tree/1.5.0" + }, + "funding": [ + { + "url": "https://www.doctrine-project.org/sponsorship.html", + "type": "custom" + }, + { + "url": "https://www.patreon.com/phpdoctrine", + "type": "patreon" + }, + { + "url": "https://tidelift.com/funding/github/packagist/doctrine%2Finstantiator", + "type": "tidelift" + } + ], + "time": "2022-12-30T00:15:36+00:00" + }, { "name": "hamcrest/hamcrest-php", "version": "v2.0.1", @@ -396,64 +466,6 @@ ], "time": "2023-03-08T13:26:56+00:00" }, - { - "name": "nikic/php-parser", - "version": "v5.0.2", - "source": { - "type": "git", - "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/139676794dc1e9231bf7bcd123cfc0c99182cb13", - "reference": "139676794dc1e9231bf7bcd123cfc0c99182cb13", - "shasum": "" - }, - "require": { - "ext-ctype": "*", - "ext-json": "*", - "ext-tokenizer": "*", - "php": ">=7.4" - }, - "require-dev": { - "ircmaxell/php-yacc": "^0.0.7", - "phpunit/phpunit": "^7.0 || ^8.0 || ^9.0" - }, - "bin": [ - "bin/php-parse" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.0-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" - ], - "support": { - "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v5.0.2" - }, - "time": "2024-03-05T20:51:40+00:00" - }, { "name": "phar-io/manifest", "version": "2.0.4", @@ -944,44 +956,40 @@ }, { "name": "phpunit/php-code-coverage", - "version": "11.0.3", + "version": "7.0.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92" + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/7e35a2cbcabac0e6865fd373742ea432a3c34f92", - "reference": "7e35a2cbcabac0e6865fd373742ea432a3c34f92", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", + "reference": "40a4ed114a4aea5afd6df8d0f0c9cd3033097f66", "shasum": "" }, "require": { "ext-dom": "*", - "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^5.0", - "php": ">=8.2", - "phpunit/php-file-iterator": "^5.0", - "phpunit/php-text-template": "^4.0", - "sebastian/code-unit-reverse-lookup": "^4.0", - "sebastian/complexity": "^4.0", - "sebastian/environment": "^7.0", - "sebastian/lines-of-code": "^3.0", - "sebastian/version": "^5.0", - "theseer/tokenizer": "^1.2.0" + "php": ">=7.2", + "phpunit/php-file-iterator": "^2.0.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.1.3 || ^4.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^4.2.2", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1.3" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.2.2" }, "suggest": { - "ext-pcov": "PHP extension that provides line coverage", - "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage" + "ext-xdebug": "^2.7.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "11.0-dev" + "dev-master": "7.0-dev" } }, "autoload": { @@ -1009,8 +1017,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "security": "https://github.com/sebastianbergmann/php-code-coverage/security/policy", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/11.0.3" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/7.0.17" }, "funding": [ { @@ -1018,32 +1025,32 @@ "type": "github" } ], - "time": "2024-03-12T15:35:40+00:00" + "time": "2024-03-02T06:09:37+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "5.0.0", + "version": "2.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "99e95c94ad9500daca992354fa09d7b99abe2210" + "reference": "69deeb8664f611f156a924154985fbd4911eb36b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/99e95c94ad9500daca992354fa09d7b99abe2210", - "reference": "99e95c94ad9500daca992354fa09d7b99abe2210", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/69deeb8664f611f156a924154985fbd4911eb36b", + "reference": "69deeb8664f611f156a924154985fbd4911eb36b", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -1070,8 +1077,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "security": "https://github.com/sebastianbergmann/php-file-iterator/security/policy", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/2.0.6" }, "funding": [ { @@ -1079,38 +1085,26 @@ "type": "github" } ], - "time": "2024-02-02T06:05:04+00:00" + "time": "2024-03-01T13:39:50+00:00" }, { - "name": "phpunit/php-invoker", - "version": "5.0.0", + "name": "phpunit/php-text-template", + "version": "1.2.1", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-invoker.git", - "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be" + "url": "https://github.com/sebastianbergmann/php-text-template.git", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-invoker/zipball/5d8d9355a16d8cc5a1305b0a85342cfa420612be", - "reference": "5d8d9355a16d8cc5a1305b0a85342cfa420612be", + "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686", + "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "ext-pcntl": "*", - "phpunit/phpunit": "^11.0" - }, - "suggest": { - "ext-pcntl": "*" + "php": ">=5.3.3" }, "type": "library", - "extra": { - "branch-alias": { - "dev-main": "5.0-dev" - } - }, "autoload": { "classmap": [ "src/" @@ -1127,48 +1121,41 @@ "role": "lead" } ], - "description": "Invoke callables with a timeout", - "homepage": "https://github.com/sebastianbergmann/php-invoker/", + "description": "Simple template engine.", + "homepage": "https://github.com/sebastianbergmann/php-text-template/", "keywords": [ - "process" + "template" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-invoker/issues", - "security": "https://github.com/sebastianbergmann/php-invoker/security/policy", - "source": "https://github.com/sebastianbergmann/php-invoker/tree/5.0.0" + "issues": "https://github.com/sebastianbergmann/php-text-template/issues", + "source": "https://github.com/sebastianbergmann/php-text-template/tree/1.2.1" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-02-02T06:05:50+00:00" + "time": "2015-06-21T13:50:34+00:00" }, { - "name": "phpunit/php-text-template", - "version": "4.0.0", + "name": "phpunit/php-timer", + "version": "2.1.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-text-template.git", - "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e" + "url": "https://github.com/sebastianbergmann/php-timer.git", + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/d38f6cbff1cdb6f40b03c9811421561668cc133e", - "reference": "d38f6cbff1cdb6f40b03c9811421561668cc133e", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/a691211e94ff39a34811abd521c31bd5b305b0bb", + "reference": "a691211e94ff39a34811abd521c31bd5b305b0bb", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "2.1-dev" } }, "autoload": { @@ -1187,15 +1174,14 @@ "role": "lead" } ], - "description": "Simple template engine.", - "homepage": "https://github.com/sebastianbergmann/php-text-template/", + "description": "Utility class for timing", + "homepage": "https://github.com/sebastianbergmann/php-timer/", "keywords": [ - "template" + "timer" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-text-template/issues", - "security": "https://github.com/sebastianbergmann/php-text-template/security/policy", - "source": "https://github.com/sebastianbergmann/php-text-template/tree/4.0.0" + "issues": "https://github.com/sebastianbergmann/php-timer/issues", + "source": "https://github.com/sebastianbergmann/php-timer/tree/2.1.4" }, "funding": [ { @@ -1203,32 +1189,33 @@ "type": "github" } ], - "time": "2024-02-02T06:06:56+00:00" + "time": "2024-03-01T13:42:41+00:00" }, { - "name": "phpunit/php-timer", - "version": "7.0.0", + "name": "phpunit/php-token-stream", + "version": "4.0.4", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5" + "url": "https://github.com/sebastianbergmann/php-token-stream.git", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8a59d9e25720482ee7fcdf296595e08795b84dc5", - "reference": "8a59d9e25720482ee7fcdf296595e08795b84dc5", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/a853a0e183b9db7eed023d7933a858fa1c8d25a3", + "reference": "a853a0e183b9db7eed023d7933a858fa1c8d25a3", "shasum": "" }, "require": { - "php": ">=8.2" + "ext-tokenizer": "*", + "php": "^7.3 || ^8.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^9.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { @@ -1243,19 +1230,17 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Utility class for timing", - "homepage": "https://github.com/sebastianbergmann/php-timer/", + "description": "Wrapper around PHP's tokenizer extension.", + "homepage": "https://github.com/sebastianbergmann/php-token-stream/", "keywords": [ - "timer" + "tokenizer" ], "support": { - "issues": "https://github.com/sebastianbergmann/php-timer/issues", - "security": "https://github.com/sebastianbergmann/php-timer/security/policy", - "source": "https://github.com/sebastianbergmann/php-timer/tree/7.0.0" + "issues": "https://github.com/sebastianbergmann/php-token-stream/issues", + "source": "https://github.com/sebastianbergmann/php-token-stream/tree/master" }, "funding": [ { @@ -1263,51 +1248,53 @@ "type": "github" } ], - "time": "2024-02-02T06:08:01+00:00" + "abandoned": true, + "time": "2020-08-04T08:28:15+00:00" }, { "name": "phpunit/phpunit", - "version": "11.1.3", + "version": "8.5.38", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "d475be032238173ca3b0a516f5cc291d174708ae" + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d475be032238173ca3b0a516f5cc291d174708ae", - "reference": "d475be032238173ca3b0a516f5cc291d174708ae", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/1ecad678646c817a29e55a32c930f3601c3f5a8c", + "reference": "1ecad678646c817a29e55a32c930f3601c3f5a8c", "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", + "myclabs/deep-copy": "^1.10.0", "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", - "php": ">=8.2", - "phpunit/php-code-coverage": "^11.0", - "phpunit/php-file-iterator": "^5.0", - "phpunit/php-invoker": "^5.0", - "phpunit/php-text-template": "^4.0", - "phpunit/php-timer": "^7.0", - "sebastian/cli-parser": "^3.0", - "sebastian/code-unit": "^3.0", - "sebastian/comparator": "^6.0", - "sebastian/diff": "^6.0", - "sebastian/environment": "^7.0", - "sebastian/exporter": "^6.0", - "sebastian/global-state": "^7.0", - "sebastian/object-enumerator": "^6.0", - "sebastian/type": "^5.0", - "sebastian/version": "^5.0" + "php": ">=7.2", + "phpunit/php-code-coverage": "^7.0.12", + "phpunit/php-file-iterator": "^2.0.4", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.1.2", + "sebastian/comparator": "^3.0.5", + "sebastian/diff": "^3.0.2", + "sebastian/environment": "^4.2.3", + "sebastian/exporter": "^3.1.5", + "sebastian/global-state": "^3.0.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^2.0.1", + "sebastian/type": "^1.1.3", + "sebastian/version": "^2.0.1" }, "suggest": { - "ext-soap": "To be able to generate mocks based on WSDL files" + "ext-soap": "To be able to generate mocks based on WSDL files", + "ext-xdebug": "PHP extension that provides line coverage as well as branch and path coverage", + "phpunit/php-invoker": "To allow enforcing time limits" }, "bin": [ "phpunit" @@ -1315,13 +1302,10 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "11.1-dev" + "dev-master": "8.5-dev" } }, "autoload": { - "files": [ - "src/Framework/Assert/Functions.php" - ], "classmap": [ "src/" ] @@ -1347,7 +1331,7 @@ "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", "security": "https://github.com/sebastianbergmann/phpunit/security/policy", - "source": "https://github.com/sebastianbergmann/phpunit/tree/11.1.3" + "source": "https://github.com/sebastianbergmann/phpunit/tree/8.5.38" }, "funding": [ { @@ -1363,146 +1347,32 @@ "type": "tidelift" } ], - "time": "2024-04-24T06:34:25+00:00" - }, - { - "name": "sebastian/cli-parser", - "version": "3.0.1", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/cli-parser.git", - "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/cli-parser/zipball/00a74d5568694711f0222e54fb281e1d15fdf04a", - "reference": "00a74d5568694711f0222e54fb281e1d15fdf04a", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for parsing CLI options", - "homepage": "https://github.com/sebastianbergmann/cli-parser", - "support": { - "issues": "https://github.com/sebastianbergmann/cli-parser/issues", - "security": "https://github.com/sebastianbergmann/cli-parser/security/policy", - "source": "https://github.com/sebastianbergmann/cli-parser/tree/3.0.1" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-03-02T07:26:58+00:00" - }, - { - "name": "sebastian/code-unit", - "version": "3.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/code-unit.git", - "reference": "6634549cb8d702282a04a774e36a7477d2bd9015" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit/zipball/6634549cb8d702282a04a774e36a7477d2bd9015", - "reference": "6634549cb8d702282a04a774e36a7477d2bd9015", - "shasum": "" - }, - "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "3.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Collection of value objects that represent the PHP code units", - "homepage": "https://github.com/sebastianbergmann/code-unit", - "support": { - "issues": "https://github.com/sebastianbergmann/code-unit/issues", - "security": "https://github.com/sebastianbergmann/code-unit/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit/tree/3.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-02-02T05:50:41+00:00" + "time": "2024-04-05T04:31:23+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "4.0.0", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d" + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/df80c875d3e459b45c6039e4d9b71d4fbccae25d", - "reference": "df80c875d3e459b45c6039e4d9b71d4fbccae25d", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", + "reference": "92a1a52e86d34cde6caa54f1b5ffa9fda18e5d54", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=5.6" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "1.0.x-dev" } }, "autoload": { @@ -1524,8 +1394,7 @@ "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", "support": { "issues": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/issues", - "security": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/security/policy", - "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/tree/1.0.3" }, "funding": [ { @@ -1533,36 +1402,34 @@ "type": "github" } ], - "time": "2024-02-02T05:52:17+00:00" + "time": "2024-03-01T13:45:45+00:00" }, { "name": "sebastian/comparator", - "version": "6.0.0", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8" + "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/bd0f2fa5b9257c69903537b266ccb80fcf940db8", - "reference": "bd0f2fa5b9257c69903537b266ccb80fcf940db8", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/1dc7ceb4a24aede938c7af2a9ed1de09609ca770", + "reference": "1dc7ceb4a24aede938c7af2a9ed1de09609ca770", "shasum": "" }, "require": { - "ext-dom": "*", - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/diff": "^6.0", - "sebastian/exporter": "^6.0" + "php": ">=7.1", + "sebastian/diff": "^3.0", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1601,66 +1468,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/comparator/issues", - "security": "https://github.com/sebastianbergmann/comparator/security/policy", - "source": "https://github.com/sebastianbergmann/comparator/tree/6.0.0" - }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-02-02T05:53:45+00:00" - }, - { - "name": "sebastian/complexity", - "version": "4.0.0", - "source": { - "type": "git", - "url": "https://github.com/sebastianbergmann/complexity.git", - "reference": "88a434ad86150e11a606ac4866b09130712671f0" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/complexity/zipball/88a434ad86150e11a606ac4866b09130712671f0", - "reference": "88a434ad86150e11a606ac4866b09130712671f0", - "shasum": "" - }, - "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-main": "4.0-dev" - } - }, - "autoload": { - "classmap": [ - "src/" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" - } - ], - "description": "Library for calculating the complexity of PHP code units", - "homepage": "https://github.com/sebastianbergmann/complexity", - "support": { - "issues": "https://github.com/sebastianbergmann/complexity/issues", - "security": "https://github.com/sebastianbergmann/complexity/security/policy", - "source": "https://github.com/sebastianbergmann/complexity/tree/4.0.0" + "source": "https://github.com/sebastianbergmann/comparator/tree/3.0.5" }, "funding": [ { @@ -1668,33 +1476,33 @@ "type": "github" } ], - "time": "2024-02-02T05:55:19+00:00" + "time": "2022-09-14T12:31:48+00:00" }, { "name": "sebastian/diff", - "version": "6.0.1", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "ab83243ecc233de5655b76f577711de9f842e712" + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ab83243ecc233de5655b76f577711de9f842e712", - "reference": "ab83243ecc233de5655b76f577711de9f842e712", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/98ff311ca519c3aa73ccd3de053bdb377171d7b6", + "reference": "98ff311ca519c3aa73ccd3de053bdb377171d7b6", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^11.0", - "symfony/process": "^4.2 || ^5" + "phpunit/phpunit": "^7.5 || ^8.0", + "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1726,8 +1534,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/diff/issues", - "security": "https://github.com/sebastianbergmann/diff/security/policy", - "source": "https://github.com/sebastianbergmann/diff/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/diff/tree/3.0.6" }, "funding": [ { @@ -1735,27 +1542,27 @@ "type": "github" } ], - "time": "2024-03-02T07:30:33+00:00" + "time": "2024-03-02T06:16:36+00:00" }, { "name": "sebastian/environment", - "version": "7.1.0", + "version": "4.2.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a" + "reference": "56932f6049a0482853056ffd617c91ffcc754205" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/4eb3a442574d0e9d141aab209cd4aaf25701b09a", - "reference": "4eb3a442574d0e9d141aab209cd4aaf25701b09a", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/56932f6049a0482853056ffd617c91ffcc754205", + "reference": "56932f6049a0482853056ffd617c91ffcc754205", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^7.5" }, "suggest": { "ext-posix": "*" @@ -1763,7 +1570,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "7.1-dev" + "dev-master": "4.2-dev" } }, "autoload": { @@ -1782,7 +1589,7 @@ } ], "description": "Provides functionality to handle HHVM/PHP environments", - "homepage": "https://github.com/sebastianbergmann/environment", + "homepage": "http://www.github.com/sebastianbergmann/environment", "keywords": [ "Xdebug", "environment", @@ -1790,8 +1597,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/environment/issues", - "security": "https://github.com/sebastianbergmann/environment/security/policy", - "source": "https://github.com/sebastianbergmann/environment/tree/7.1.0" + "source": "https://github.com/sebastianbergmann/environment/tree/4.2.5" }, "funding": [ { @@ -1799,34 +1605,34 @@ "type": "github" } ], - "time": "2024-03-23T08:56:34+00:00" + "time": "2024-03-01T13:49:59+00:00" }, { "name": "sebastian/exporter", - "version": "6.0.1", + "version": "3.1.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "f291e5a317c321c0381fa9ecc796fa2d21b186da" + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/f291e5a317c321c0381fa9ecc796fa2d21b186da", - "reference": "f291e5a317c321c0381fa9ecc796fa2d21b186da", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/1939bc8fd1d39adcfa88c5b35335910869214c56", + "reference": "1939bc8fd1d39adcfa88c5b35335910869214c56", "shasum": "" }, "require": { - "ext-mbstring": "*", - "php": ">=8.2", - "sebastian/recursion-context": "^6.0" + "php": ">=7.2", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "ext-mbstring": "*", + "phpunit/phpunit": "^8.5" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1861,15 +1667,14 @@ } ], "description": "Provides the functionality to export PHP variables for visualization", - "homepage": "https://www.github.com/sebastianbergmann/exporter", + "homepage": "http://www.github.com/sebastianbergmann/exporter", "keywords": [ "export", "exporter" ], "support": { "issues": "https://github.com/sebastianbergmann/exporter/issues", - "security": "https://github.com/sebastianbergmann/exporter/security/policy", - "source": "https://github.com/sebastianbergmann/exporter/tree/6.0.1" + "source": "https://github.com/sebastianbergmann/exporter/tree/3.1.6" }, "funding": [ { @@ -1877,35 +1682,38 @@ "type": "github" } ], - "time": "2024-03-02T07:28:20+00:00" + "time": "2024-03-02T06:21:38+00:00" }, { "name": "sebastian/global-state", - "version": "7.0.1", + "version": "3.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e" + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", - "reference": "c3a307e832f2e69c7ef869e31fc644fde0e7cb3e", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/91c7c47047a971f02de57ed6f040087ef110c5d9", + "reference": "91c7c47047a971f02de57ed6f040087ef110c5d9", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "php": ">=7.2", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-dom": "*", - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.0" + }, + "suggest": { + "ext-uopz": "*" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "7.0-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1924,14 +1732,13 @@ } ], "description": "Snapshotting of global state", - "homepage": "https://www.github.com/sebastianbergmann/global-state", + "homepage": "http://www.github.com/sebastianbergmann/global-state", "keywords": [ "global state" ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "security": "https://github.com/sebastianbergmann/global-state/security/policy", - "source": "https://github.com/sebastianbergmann/global-state/tree/7.0.1" + "source": "https://github.com/sebastianbergmann/global-state/tree/3.0.5" }, "funding": [ { @@ -1939,33 +1746,34 @@ "type": "github" } ], - "time": "2024-03-02T07:32:10+00:00" + "time": "2024-03-02T06:13:16+00:00" }, { - "name": "sebastian/lines-of-code", - "version": "3.0.0", + "name": "sebastian/object-enumerator", + "version": "3.0.5", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/lines-of-code.git", - "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0" + "url": "https://github.com/sebastianbergmann/object-enumerator.git", + "reference": "ac5b293dba925751b808e02923399fb44ff0d541" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/lines-of-code/zipball/376c5b3f6b43c78fdc049740bca76a7c846706c0", - "reference": "376c5b3f6b43c78fdc049740bca76a7c846706c0", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/ac5b293dba925751b808e02923399fb44ff0d541", + "reference": "ac5b293dba925751b808e02923399fb44ff0d541", "shasum": "" }, "require": { - "nikic/php-parser": "^5.0", - "php": ">=8.2" + "php": ">=7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "3.0-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1980,16 +1788,14 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sebastian@phpunit.de", - "role": "lead" + "email": "sebastian@phpunit.de" } ], - "description": "Library for counting the lines of code in PHP source code", - "homepage": "https://github.com/sebastianbergmann/lines-of-code", + "description": "Traverses array structures and object graphs to enumerate all referenced objects", + "homepage": "https://github.com/sebastianbergmann/object-enumerator/", "support": { - "issues": "https://github.com/sebastianbergmann/lines-of-code/issues", - "security": "https://github.com/sebastianbergmann/lines-of-code/security/policy", - "source": "https://github.com/sebastianbergmann/lines-of-code/tree/3.0.0" + "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", + "source": "https://github.com/sebastianbergmann/object-enumerator/tree/3.0.5" }, "funding": [ { @@ -1997,34 +1803,32 @@ "type": "github" } ], - "time": "2024-02-02T06:00:36+00:00" + "time": "2024-03-01T13:54:02+00:00" }, { - "name": "sebastian/object-enumerator", - "version": "6.0.0", + "name": "sebastian/object-reflector", + "version": "1.1.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678" + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", - "reference": "f75f6c460da0bbd9668f43a3dde0ec0ba7faa678", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/1d439c229e61f244ff1f211e5c99737f90c67def", + "reference": "1d439c229e61f244ff1f211e5c99737f90c67def", "shasum": "" }, "require": { - "php": ">=8.2", - "sebastian/object-reflector": "^4.0", - "sebastian/recursion-context": "^6.0" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "1.1-dev" } }, "autoload": { @@ -2042,12 +1846,11 @@ "email": "sebastian@phpunit.de" } ], - "description": "Traverses array structures and object graphs to enumerate all referenced objects", - "homepage": "https://github.com/sebastianbergmann/object-enumerator/", + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", "support": { - "issues": "https://github.com/sebastianbergmann/object-enumerator/issues", - "security": "https://github.com/sebastianbergmann/object-enumerator/security/policy", - "source": "https://github.com/sebastianbergmann/object-enumerator/tree/6.0.0" + "issues": "https://github.com/sebastianbergmann/object-reflector/issues", + "source": "https://github.com/sebastianbergmann/object-reflector/tree/1.1.3" }, "funding": [ { @@ -2055,32 +1858,32 @@ "type": "github" } ], - "time": "2024-02-02T06:01:29+00:00" + "time": "2024-03-01T13:56:04+00:00" }, { - "name": "sebastian/object-reflector", - "version": "4.0.0", + "name": "sebastian/recursion-context", + "version": "3.0.2", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/object-reflector.git", - "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d" + "url": "https://github.com/sebastianbergmann/recursion-context.git", + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/bb2a6255d30853425fd38f032eb64ced9f7f132d", - "reference": "bb2a6255d30853425fd38f032eb64ced9f7f132d", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/9bfd3c6f1f08c026f542032dfb42813544f7d64c", + "reference": "9bfd3c6f1f08c026f542032dfb42813544f7d64c", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.0" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "4.0-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -2096,14 +1899,21 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" + }, + { + "name": "Jeff Welch", + "email": "whatthejeff@gmail.com" + }, + { + "name": "Adam Harvey", + "email": "aharvey@php.net" } ], - "description": "Allows reflection of object attributes, including inherited and non-public ones", - "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "description": "Provides functionality to recursively process PHP variables", + "homepage": "http://www.github.com/sebastianbergmann/recursion-context", "support": { - "issues": "https://github.com/sebastianbergmann/object-reflector/issues", - "security": "https://github.com/sebastianbergmann/object-reflector/security/policy", - "source": "https://github.com/sebastianbergmann/object-reflector/tree/4.0.0" + "issues": "https://github.com/sebastianbergmann/recursion-context/issues", + "source": "https://github.com/sebastianbergmann/recursion-context/tree/3.0.2" }, "funding": [ { @@ -2111,32 +1921,29 @@ "type": "github" } ], - "time": "2024-02-02T06:02:18+00:00" + "time": "2024-03-01T14:07:30+00:00" }, { - "name": "sebastian/recursion-context", - "version": "6.0.0", + "name": "sebastian/resource-operations", + "version": "2.0.3", "source": { "type": "git", - "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4" + "url": "https://github.com/sebastianbergmann/resource-operations.git", + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b75224967b5a466925c6d54e68edd0edf8dd4ed4", - "reference": "b75224967b5a466925c6d54e68edd0edf8dd4ed4", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/72a7f7674d053d548003b16ff5a106e7e0e06eee", + "reference": "72a7f7674d053d548003b16ff5a106e7e0e06eee", "shasum": "" }, "require": { - "php": ">=8.2" - }, - "require-dev": { - "phpunit/phpunit": "^11.0" + "php": ">=7.1" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "6.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -2152,22 +1959,12 @@ { "name": "Sebastian Bergmann", "email": "sebastian@phpunit.de" - }, - { - "name": "Jeff Welch", - "email": "whatthejeff@gmail.com" - }, - { - "name": "Adam Harvey", - "email": "aharvey@php.net" } ], - "description": "Provides functionality to recursively process PHP variables", - "homepage": "https://github.com/sebastianbergmann/recursion-context", + "description": "Provides a list of PHP built-in functions that operate on resources", + "homepage": "https://www.github.com/sebastianbergmann/resource-operations", "support": { - "issues": "https://github.com/sebastianbergmann/recursion-context/issues", - "security": "https://github.com/sebastianbergmann/recursion-context/security/policy", - "source": "https://github.com/sebastianbergmann/recursion-context/tree/6.0.0" + "source": "https://github.com/sebastianbergmann/resource-operations/tree/2.0.3" }, "funding": [ { @@ -2175,32 +1972,32 @@ "type": "github" } ], - "time": "2024-02-02T06:08:48+00:00" + "time": "2024-03-01T13:59:09+00:00" }, { "name": "sebastian/type", - "version": "5.0.0", + "version": "1.1.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f" + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b8502785eb3523ca0dd4afe9ca62235590020f3f", - "reference": "b8502785eb3523ca0dd4afe9ca62235590020f3f", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/18f071c3a29892b037d35e6b20ddf3ea39b42874", + "reference": "18f071c3a29892b037d35e6b20ddf3ea39b42874", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=7.2" }, "require-dev": { - "phpunit/phpunit": "^11.0" + "phpunit/phpunit": "^8.2" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "1.1-dev" } }, "autoload": { @@ -2223,8 +2020,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "security": "https://github.com/sebastianbergmann/type/security/policy", - "source": "https://github.com/sebastianbergmann/type/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/1.1.5" }, "funding": [ { @@ -2232,29 +2028,29 @@ "type": "github" } ], - "time": "2024-02-02T06:09:34+00:00" + "time": "2024-03-01T14:04:07+00:00" }, { "name": "sebastian/version", - "version": "5.0.0", + "version": "2.0.1", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/version.git", - "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001" + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/13999475d2cb1ab33cb73403ba356a814fdbb001", - "reference": "13999475d2cb1ab33cb73403ba356a814fdbb001", + "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/99732be0ddb3361e16ad77b68ba41efc8e979019", + "reference": "99732be0ddb3361e16ad77b68ba41efc8e979019", "shasum": "" }, "require": { - "php": ">=8.2" + "php": ">=5.6" }, "type": "library", "extra": { "branch-alias": { - "dev-main": "5.0-dev" + "dev-master": "2.0.x-dev" } }, "autoload": { @@ -2277,16 +2073,9 @@ "homepage": "https://github.com/sebastianbergmann/version", "support": { "issues": "https://github.com/sebastianbergmann/version/issues", - "security": "https://github.com/sebastianbergmann/version/security/policy", - "source": "https://github.com/sebastianbergmann/version/tree/5.0.0" + "source": "https://github.com/sebastianbergmann/version/tree/master" }, - "funding": [ - { - "url": "https://github.com/sebastianbergmann", - "type": "github" - } - ], - "time": "2024-02-02T06:10:47+00:00" + "time": "2016-10-03T07:35:21+00:00" }, { "name": "squizlabs/php_codesniffer", From e55333cf41fb9269829612e1d679de8411cb570c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Thu, 6 Jun 2024 15:03:00 +0200 Subject: [PATCH 03/17] improve ddev orchestration --- .../web/orchestrate.d/10_wp_install.sh | 20 +-------- .../20_cleanup_default_plugins.sh | 1 - .../orchestrate.d/50_setup_test_content.sh | 41 +++++++++++++++++++ .../web/orchestrate.d/50_setup_whoops.sh | 5 --- .ddev/config.yaml | 4 +- 5 files changed, 44 insertions(+), 27 deletions(-) create mode 100644 .ddev/commands/web/orchestrate.d/50_setup_test_content.sh delete mode 100644 .ddev/commands/web/orchestrate.d/50_setup_whoops.sh diff --git a/.ddev/commands/web/orchestrate.d/10_wp_install.sh b/.ddev/commands/web/orchestrate.d/10_wp_install.sh index b742099..dfbdc84 100644 --- a/.ddev/commands/web/orchestrate.d/10_wp_install.sh +++ b/.ddev/commands/web/orchestrate.d/10_wp_install.sh @@ -5,28 +5,12 @@ if [ ! -z "${RECREATE_ENV}" ]; then wp db clean --yes fi -if [ "${WP_MULTISITE}" = "true" ]; then - wp core multisite-install \ - --title="${WP_TITLE}" \ - --admin_user="${ADMIN_USER}" \ - --admin_password="${ADMIN_PASS}" \ - --url="${DDEV_PRIMARY_URL}" \ - --admin_email="${ADMIN_EMAIL}" \ - --skip-email - -readarray -d , -t slugs <<< "${WP_MULTISITE_SLUGS},"; unset "slugs[-1]"; -for slug in "${slugs[@]}"; do - if [ ! -z "${slug}" ]; then - wp site create --slug="${slug}" - fi -done -else - wp core install \ +wp core multisite-install \ --title="${WP_TITLE}" \ --admin_user="${ADMIN_USER}" \ --admin_password="${ADMIN_PASS}" \ --url="${DDEV_PRIMARY_URL}" \ --admin_email="${ADMIN_EMAIL}" \ --skip-email -fi + diff --git a/.ddev/commands/web/orchestrate.d/20_cleanup_default_plugins.sh b/.ddev/commands/web/orchestrate.d/20_cleanup_default_plugins.sh index 82e06dc..b61babb 100644 --- a/.ddev/commands/web/orchestrate.d/20_cleanup_default_plugins.sh +++ b/.ddev/commands/web/orchestrate.d/20_cleanup_default_plugins.sh @@ -1,4 +1,3 @@ #!/bin/bash wp plugin is-installed akismet && wp plugin uninstall akismet -wp plugin is-installed hello && wp plugin uninstall hello diff --git a/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh b/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh new file mode 100644 index 0000000..8c72522 --- /dev/null +++ b/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh @@ -0,0 +1,41 @@ +#!/bin/bash + +pushd "${DDEV_DOCROOT}" + +wp user create usite1 usite1@example.com --role=administrator --porcelain --url="${DDEV_PRIMARY_URL}/site1" +wp user create usite2 usite2@example.com --role=administrator --porcelain --url="${DDEV_PRIMARY_URL}/site2" +wp user create usite3 usite3@example.com --role=administrator --porcelain --url="${DDEV_PRIMARY_URL}/site3" +wp user create usite4 usite4@example.com --role=administrator --porcelain --url="${DDEV_PRIMARY_URL}/site4" +wp user create usite5 usite5@example.com --role=administrator --porcelain --url="${DDEV_PRIMARY_URL}/site5" + +wp site create --slug="site1" --email=usite1@example.com +wp site create --slug="site2" --email=usite2@example.com +wp site create --slug="site3" --email=usite3@example.com +wp site create --slug="site4" --email=usite4@example.com +wp site create --slug="site5" --email=usite5@example.com + +wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site1" +wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site2" +wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site3" +wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site4" +wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site5" + +wp plugin activate hello --url="${DDEV_PRIMARY_URL}/site2" +wp plugin activate hello --url="${DDEV_PRIMARY_URL}/site4" + +wp theme install twentytwentyone --force +wp theme install twentytwentytwo --force +wp theme install twentytwentythree --force +wp theme install twentytwentyfour --force + +wp theme enable twentytwentyfour --network +wp theme enable twentytwentythree --network +wp theme enable twentytwentytwo --network +wp theme enable twentytwentyone --network + +wp theme activate twentytwentyfour --url="${DDEV_PRIMARY_URL}/site4" +wp theme activate twentytwentythree --url="${DDEV_PRIMARY_URL}/site3" +wp theme activate twentytwentytwo --url="${DDEV_PRIMARY_URL}/site2" +wp theme activate twentytwentyone --url="${DDEV_PRIMARY_URL}/site1" + + diff --git a/.ddev/commands/web/orchestrate.d/50_setup_whoops.sh b/.ddev/commands/web/orchestrate.d/50_setup_whoops.sh deleted file mode 100644 index 95342c3..0000000 --- a/.ddev/commands/web/orchestrate.d/50_setup_whoops.sh +++ /dev/null @@ -1,5 +0,0 @@ -#!/bin/bash - -pushd "${DDEV_DOCROOT}" - -wp plugin install https://github.com/Rarst/wps/releases/latest/download/wps.zip --activate-network diff --git a/.ddev/config.yaml b/.ddev/config.yaml index d6228b8..cafe917 100644 --- a/.ddev/config.yaml +++ b/.ddev/config.yaml @@ -22,9 +22,7 @@ hooks: web_environment: - WP_VERSION=6.5.4 - WP_LOCALE=de_DE - - WP_TITLE=DDEV Search and Replace Test - - WP_MULTISITE=true - - WP_MULTISITE_SLUGS=seite1,seite2,site3,site4,site5 + - WP_TITLE=DDEV Multisite Enhancements Test - ADMIN_USER=admin - ADMIN_PASS=admin - ADMIN_EMAIL=admin@example.com From 5562517f796193a48427a49ef60897ea25dbb131 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Thu, 6 Jun 2024 15:44:36 +0200 Subject: [PATCH 04/17] improve ddev orchestration --- .ddev/commands/favicon1.ico | Bin 0 -> 67646 bytes .ddev/commands/favicon2.ico | Bin 0 -> 67646 bytes .ddev/commands/favicon3.ico | Bin 0 -> 67646 bytes .ddev/commands/favicon4.ico | Bin 0 -> 67646 bytes .ddev/commands/favicon5.ico | Bin 0 -> 67646 bytes .../web/orchestrate.d/50_setup_test_content.sh | 5 +++++ 6 files changed, 5 insertions(+) create mode 100644 .ddev/commands/favicon1.ico create mode 100644 .ddev/commands/favicon2.ico create mode 100644 .ddev/commands/favicon3.ico create mode 100644 .ddev/commands/favicon4.ico create mode 100644 .ddev/commands/favicon5.ico diff --git a/.ddev/commands/favicon1.ico b/.ddev/commands/favicon1.ico new file mode 100644 index 0000000000000000000000000000000000000000..1555c6dc166bc0893d1dcba4c7d409ae457d33f2 GIT binary patch literal 67646 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 CR!21e literal 0 HcmV?d00001 diff --git a/.ddev/commands/favicon3.ico b/.ddev/commands/favicon3.ico new file mode 100644 index 0000000000000000000000000000000000000000..aa025008d28d704e4cf6c4042a67880baab8c520 GIT binary patch literal 67646 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 k_cLtmU%MGaX2YAd Date: Fri, 7 Jun 2024 08:48:01 +0200 Subject: [PATCH 05/17] add user switching plugin --- .ddev/commands/web/orchestrate.d/50_setup_test_content.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh b/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh index b3fbb8e..4d05a92 100644 --- a/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh +++ b/.ddev/commands/web/orchestrate.d/50_setup_test_content.sh @@ -20,6 +20,8 @@ wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site3" wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site4" wp user set-role ${ADMIN_USER} administrator --url="${DDEV_PRIMARY_URL}/site5" +wp plugin install user-switching --force --activate-network --version=1.7.0 + wp plugin activate hello --url="${DDEV_PRIMARY_URL}/site2" wp plugin activate hello --url="${DDEV_PRIMARY_URL}/site4" From 2f8eefe9ab7f345cb216b4c7cc49e809b83735e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Fri, 7 Jun 2024 13:11:45 +0200 Subject: [PATCH 06/17] add last user login function --- multisite-enhancements.php | 6 ++ src/class-add-user-last-login.php | 121 ++++++++++++++++++++++++++++++ src/settings.php | 2 + 3 files changed, 129 insertions(+) create mode 100644 src/class-add-user-last-login.php diff --git a/multisite-enhancements.php b/multisite-enhancements.php index 1b515a5..d209a7e 100755 --- a/multisite-enhancements.php +++ b/multisite-enhancements.php @@ -102,6 +102,12 @@ public static function load() { 'change-footer' => array( 'init' => array( 'Multisite_Change_Footer_Text', 'init' ) ), 'filtering-themes' => array( 'admin_init' => array( 'Filtering_Themes', 'init' ) ), 'add-new-plugin' => array( 'init' => array( 'Multisite_Add_New_Plugin', 'init' ) ), + 'add-user-last-login' => array( + 'init' => function () { + $multisite_add_user_last_login = new Bueltge\User_Last_Login\Add_User_Last_Login(); + $multisite_add_user_last_login->init(); + }, + ), ); foreach ( $modules as $id => $hooks ) { diff --git a/src/class-add-user-last-login.php b/src/class-add-user-last-login.php new file mode 100644 index 0000000..1af6e43 --- /dev/null +++ b/src/class-add-user-last-login.php @@ -0,0 +1,121 @@ +get( 'orderby' ) || ! current_user_can( 'list_users' ) ) { + return; + } + + // Must use a meta query to account for users who have never logged in. + $meta_query = array( + 'relation' => 'OR', + 'last_logged_in_never' => array( + 'key' => 'last_logged_in', + 'compare' => 'NOT EXISTS', + ), + 'last_logged_in' => array( + 'key' => 'last_logged_in', + 'type' => 'DATE', + ), + ); + + $query->set( 'orderby', 'last_logged_in' ); + $query->set( 'meta_query', $meta_query ); + } + + /** + * Display colum content + * + * @param string $value Value form before. + * @param string $column current column name. + * @param int $user_id user ID to display information for. + * + * @return string + */ + public function manage_users_custom_column( $value, $column, $user_id ) { + if ( 'last-logged-in' !== $column || ! current_user_can( 'list_users' ) ) { + return $value; + } + + $last_login = \DateTime::createFromFormat( 'Y-m-d H:i:s', get_user_meta( $user_id, 'last_logged_in', true ), new \DateTimeZone( 'UTC' ) ); + + if ( ! $last_login ) { + return 'Never since registering'; + } + + $last_login->setTimezone( wp_timezone() ); + return '' . $last_login->format( 'd. F Y' ) . ''; + } + + /** + * Record the last date a user logged in. + * + * Note: This might be before they agree to the new TOS, which is recorded separately. + * + * @param string $auth_cookie Authentication cookie value. + * @param int $expire The time the login grace period expires as a UNIX timestamp. + * Default is 12 hours past the cookie's expiration time. + * @param int $expiration The time when the authentication cookie expires as a UNIX timestamp. + * Default is 14 days from now. + * @param int $user_id User ID. + * + * @throws \Exception + */ + public function record_last_logged_in( $auth_cookie, $expire, $expiration, $user_id ) { + $login_at = new \DateTime( 'now', new \DateTimeZone( 'UTC' ) ); + update_user_meta( $user_id, 'last_logged_in', $login_at->format( 'Y-m-d H:i:s' ) ); + } +} diff --git a/src/settings.php b/src/settings.php index 30bc28f..4667516 100644 --- a/src/settings.php +++ b/src/settings.php @@ -33,6 +33,7 @@ class Multisite_Enhancements_Settings { 'add-ssl-identifier' => 1, 'add-manage-comments' => 1, 'add-new-plugin' => 1, + 'add-user-last-login' => 1, 'filtering-themes' => 1, 'change-footer' => 1, 'delete-settings' => 1, @@ -197,6 +198,7 @@ public function settings_fields_callback( $args ) { 'add-ssl-identifier' => esc_html__( 'Add an icon to identify the SSL protocol on each site in the network Sites page', 'multisite-enhancements' ), 'add-manage-comments' => esc_html__( 'Add new "Manage Comments" item with count of comments waiting for moderation in "My Sites" menu', 'multisite-enhancements' ), 'add-new-plugin' => esc_html__( 'Enables an "Add New" link under the Plugins menu of each blog, for network admins', 'multisite-enhancements' ), + 'add-user-last-login' => esc_html__( 'Recorde last logins and add displaying of last login to admin user list', 'multisite-enhancements' ), 'filtering-themes' => esc_html__( 'Add simple javascript to filter the theme list on network and single site theme page of WordPress backend', 'multisite-enhancements' ), 'change-footer' => esc_html__( 'Enhance the admin footer text with RAM, SQL queries and PHP version information', 'multisite-enhancements' ), ), From eacb7ce7dcddd61311d2ce0517153faffef38a29 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Fri, 7 Jun 2024 13:18:57 +0200 Subject: [PATCH 07/17] fix wrong type --- readme.txt | 2 +- src/class-add-user-last-login.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/readme.txt b/readme.txt index bd794fe..92d064b 100755 --- a/readme.txt +++ b/readme.txt @@ -2,7 +2,7 @@ Contributors: Bueltge, inpsyde, danielhuesken Tags: multisite, administration, admin bar, network, Requires at least: 4.6 -Tested up to: 5.7 +Tested up to: 6.5.4 Requires PHP: 7.2 Stable tag: 1.6.1 License: GPLv2 or later diff --git a/src/class-add-user-last-login.php b/src/class-add-user-last-login.php index 1af6e43..212ebec 100644 --- a/src/class-add-user-last-login.php +++ b/src/class-add-user-last-login.php @@ -50,11 +50,11 @@ public function manage_users_sortable_columns( array $columns ) { /** * Filter users for sorting * - * @param \WP_Query $query User query. + * @param \WP_User_Query $query User query. * * @return void */ - public function pre_get_users( \WP_Query $query ) { + public function pre_get_users( \WP_User_Query $query ) { if ( ! is_network_admin() || 'last-logged-in' !== $query->get( 'orderby' ) || ! current_user_can( 'list_users' ) ) { return; } From bd115d70a912e00bbe9ff47fe4b42bdefaab7928 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Fri, 7 Jun 2024 14:33:03 +0200 Subject: [PATCH 08/17] Hold objects in main class and use statig methods to get/set them --- multisite-enhancements.php | 122 +++++++++++++------------ src/class-add-admin-favicon.php | 22 +---- src/class-add-blog-id.php | 17 +--- src/class-add-css.php | 15 +-- src/class-add-plugin-list.php | 20 +--- src/class-add-site-status-labels.php | 15 +-- src/class-add-ssl-identifier.php | 8 -- src/class-add-theme-list.php | 26 ++---- src/class-admin-bar-tweaks.php | 8 -- src/class-change-footer-text.php | 20 +--- src/class-core.php | 6 -- src/class-filtering-themes.php | 13 +-- src/class-multisite-add-new-plugin.php | 15 +-- src/core.php | 2 +- src/settings.php | 21 +---- 15 files changed, 92 insertions(+), 238 deletions(-) diff --git a/multisite-enhancements.php b/multisite-enhancements.php index d209a7e..ef6b36e 100755 --- a/multisite-enhancements.php +++ b/multisite-enhancements.php @@ -16,42 +16,22 @@ * @package multisite-enhancement */ -! defined( 'ABSPATH' ) && exit; -// phpcs:disable -add_filter( 'plugins_loaded', array( 'Multisite_Enhancements', 'get_object' ) ); +if ( function_exists( 'add_action' ) ) { + add_action( 'plugins_loaded', array( Multisite_Enhancements::get_object(), 'load' ) ); +} /** * Class Multisite_Enhancements. * Plugin wrapper to list as plugin in WordPress environment and load all necessary files. */ class Multisite_Enhancements { -// phpcs:enable + /** * The class object. * - * @since 0.0.1 - * @var String + * @var array */ - protected static $class_object; - - /** - * Init function to register all used hooks. - * - * @since 0.0.1 - */ - public function __construct() { - - // This check prevents using this plugin not in a multisite. - if ( function_exists( 'is_multisite' ) && ! is_multisite() ) { - add_filter( 'admin_notices', array( $this, 'error_msg_no_multisite' ) ); - - return; - } - - $this->load_translation(); - - self::load(); - } + private static $class_objects = array(); /** * Load translation file. @@ -71,48 +51,50 @@ public function load_translation() { * * @since 0.0.1 */ - public static function load() { + public function load() { define( 'MULTISITE_ENHANCEMENT_BASE', __DIR__ . '/src' ); + if ( function_exists( 'is_multisite' ) && ! is_multisite() ) { + add_filter( 'admin_notices', array( $this, 'error_msg_no_multisite' ) ); + + return; + } + + $this->load_translation(); + require_once __DIR__ . '/vendor/autoload.php'; - add_action( 'init', array( 'Multisite_Enhancements_Settings', 'init' ) ); - add_action( 'init', array( 'Multisite_Core', 'init' ) ); + add_action( 'init', array( self::set_object( new Multisite_Enhancements_Settings() ), 'init' ) ); + add_action( 'init', array( self::set_object( new Multisite_Core() ), 'init' ) ); $modules = array( - 'add-favicon' => array( 'init' => array( 'Multisite_Add_Admin_Favicon', 'init' ) ), - 'remove-logo' => array( 'init' => array( 'Multisite_Add_Admin_Favicon', 'init' ) ), - 'add-blog-id' => array( 'init' => array( 'Multisite_Add_Blog_Id', 'init' ) ), - 'add-css' => array( 'init' => array( 'Add_Css', 'init' ) ), - 'add-plugin-list' => array( 'init' => array( 'Multisite_Add_Plugin_List', 'init' ) ), - 'add-site-status' => array( 'init' => array( 'Multisite_Add_Site_Status_labels', 'init' ) ), + 'add-favicon' => array( 'init' => array( Multisite_Add_Admin_Favicon::class, 'init' ) ), + 'remove-logo' => array( 'init' => array( Multisite_Add_Admin_Favicon::class, 'init' ) ), + 'add-blog-id' => array( 'init' => array( Multisite_Add_Blog_Id::class, 'init' ) ), + 'add-css' => array( 'init' => array( Add_Css::class, 'init' ) ), + 'add-plugin-list' => array( 'init' => array( Multisite_Add_Plugin_List::class, 'init' ) ), + 'add-site-status' => array( 'init' => array( Multisite_Add_Site_Status_labels::class, 'init' ) ), 'add-ssl-identifier' => array( - 'admin_init' => function () { - $multisite_add_ssh_identifier = new Bueltge\Multisite_Add_Ssh_Identifier\Multisite_Add_Ssh_Identifier(); - $multisite_add_ssh_identifier->init(); - }, + 'admin_init' => array( Bueltge\Multisite_Add_Ssh_Identifier\Multisite_Add_Ssh_Identifier::class, 'init' ), ), - 'add-theme-list' => array( 'init' => array( 'Multisite_Add_Theme_List', 'init' ) ), + 'add-theme-list' => array( 'init' => array( Multisite_Add_Theme_List::class, 'init' ) ), 'add-manage-comments' => array( - 'init' => function () { - $multisite_admin_bar_tweaks = new Bueltge\Admin_Bar_Tweaks\Multisite_Admin_Bar_Tweaks(); - $multisite_admin_bar_tweaks->init(); - }, + 'init' => array( Bueltge\Admin_Bar_Tweaks\Multisite_Admin_Bar_Tweaks::class, 'init' ), ), - 'change-footer' => array( 'init' => array( 'Multisite_Change_Footer_Text', 'init' ) ), - 'filtering-themes' => array( 'admin_init' => array( 'Filtering_Themes', 'init' ) ), - 'add-new-plugin' => array( 'init' => array( 'Multisite_Add_New_Plugin', 'init' ) ), + 'change-footer' => array( 'init' => array( Multisite_Change_Footer_Text::class, 'init' ) ), + 'filtering-themes' => array( 'admin_init' => array( Filtering_Themes::class, 'init' ) ), + 'add-new-plugin' => array( 'init' => array( Multisite_Add_New_Plugin::class, 'init' ) ), 'add-user-last-login' => array( - 'init' => function () { - $multisite_add_user_last_login = new Bueltge\User_Last_Login\Add_User_Last_Login(); - $multisite_add_user_last_login->init(); - }, + 'init' => array( Bueltge\User_Last_Login\Add_User_Last_Login::class, 'init' ), ), ); foreach ( $modules as $id => $hooks ) { if ( Multisite_Enhancements_Settings::is_feature_enabled( $id ) ) { foreach ( $hooks as $hook_name => $callback ) { + if ( is_string( $callback[0] ) && class_exists( $callback[0] ) ) { + $callback[0] = self::set_object( new $callback[0]() ); + } if ( ! has_action( $hook_name, $callback ) ) { add_action( $hook_name, $callback ); } @@ -122,17 +104,43 @@ public static function load() { } /** - * Load the object and get the current state. + * Load objects for all plugin classes, default for this class. * - * @return Multisite_Enhancements $class_object + * @param string $class_name FQN of the class to get object from. + * @return object|null $class_object * @since 0.0.1 */ - public static function get_object() { - if ( null === self::$class_object ) { - self::$class_object = new self(); + public static function get_object( string $class_name = '' ): ?object { + if ( '' === $class_name ) { + $class_name = __CLASS__; + } + + if ( isset( self::$class_objects[ $class_name ] ) ) { + return self::$class_objects[ $class_name ]; } - return self::$class_object; + if ( __CLASS__ === $class_name ) { + self::set_object( new self() ); + return self::get_object( __CLASS__ ); + } + + return null; + } + + /** + * Store objects for all plugin classes, default for this class. + * + * @param object $class_object The object to store. + * @return object + */ + public static function set_object( object $class_object ): object { + $class_name = get_class( $class_object ); + + if ( isset( self::$class_objects[ $class_name ] ) ) { + return self::$class_objects[ $class_name ]; + } + self::$class_objects[ $class_name ] = $class_object; + return self::get_object( $class_name ); } /** diff --git a/src/class-add-admin-favicon.php b/src/class-add-admin-favicon.php index 24ad665..9d672de 100755 --- a/src/class-add-admin-favicon.php +++ b/src/class-add-admin-favicon.php @@ -47,15 +47,11 @@ class Multisite_Add_Admin_Favicon { */ protected static $remove_wp_admin_bar = true; + /** - * Init function to register all used hooks. - * - * Use the filter hook to add hooks, there will add the markup - * Hook: multisite_enhancements_favicon - * - * @since 0.0.2 + * Initialize the class. */ - public function __construct() { + public function init() { /** * Hooks for add favicon markup. @@ -75,18 +71,6 @@ public function __construct() { add_action( 'admin_bar_menu', array( $this, 'change_admin_bar_menu' ), 25 ); } - /** - * Initialize the class. - */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - // phpcs:enable - } - } - /** * Create markup, if favicon is exist in active theme folder. * diff --git a/src/class-add-blog-id.php b/src/class-add-blog-id.php index 328096a..3854b18 100755 --- a/src/class-add-blog-id.php +++ b/src/class-add-blog-id.php @@ -17,21 +17,7 @@ class Multisite_Add_Blog_Id { /** * Init the class. */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - // phpcs:enable - } - } - - /** - * Init function to register all used hooks. - * - * @since 0.0.1 - */ - public function __construct() { + public function init() { if ( ! is_network_admin() ) { return; } @@ -48,6 +34,7 @@ public function __construct() { add_action( 'admin_print_styles-users.php', array( $this, 'add_style' ) ); } + /** * Echo the site id of each site. * diff --git a/src/class-add-css.php b/src/class-add-css.php index dad1719..71eff5d 100755 --- a/src/class-add-css.php +++ b/src/class-add-css.php @@ -22,23 +22,12 @@ */ class Add_Css { - /** - * Init function to register all used hooks. - */ - public function __construct() { - add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_style' ) ); - } /** * Initialize the class. */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - // phpcs:enable - } + public function init() { + add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_style' ) ); } /** diff --git a/src/class-add-plugin-list.php b/src/class-add-plugin-list.php index 05f3ec1..07027eb 100755 --- a/src/class-add-plugin-list.php +++ b/src/class-add-plugin-list.php @@ -67,11 +67,9 @@ class Multisite_Add_Plugin_List { private $blogs_plugins; /** - * Init function to register all used hooks. - * - * @since 0.0.1 + * Initialize the class. */ - public function __construct() { + public function init() { add_action( 'load-plugins.php', array( $this, 'development_helper' ) ); // Fires after a plugin has been activated; but not on silently activated, like update. @@ -94,18 +92,6 @@ public function __construct() { add_action( 'manage_plugins_custom_column', array( $this, 'manage_plugins_custom_column' ), 10, 3 ); } - /** - * Initialize the class. - */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - // phpcs:enable - } - } - /** * Print Network Admin Notices to inform, that the transient are deleted. * @@ -185,7 +171,7 @@ public function manage_plugins_custom_column( $column_name, $plugin_file, $plugi $output .= '

'; $is_list_hidden = false; // Hide the list of sites if the class isn"t loaded or there's less or equal to 4 sites. - if ( $active_count > 4 && class_exists( 'Add_Css', false ) ) { + if ( $active_count > 4 && class_exists( Add_Css::class, false ) ) { $output .= sprintf( // Translators: The placeholder will be replaced by the count and the toggle link of sites there use that plugin. _n( 'Active on %2$s %1$d site %3$s', 'Active on %2$s %1$d sites %3$s', $active_count, 'multisite-enhancements' ), diff --git a/src/class-add-site-status-labels.php b/src/class-add-site-status-labels.php index db38afc..3d5f1fb 100755 --- a/src/class-add-site-status-labels.php +++ b/src/class-add-site-status-labels.php @@ -17,20 +17,7 @@ class Multisite_Add_Site_Status_labels { /** * Initialize the class. */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - } - } - - /** - * Init function to register all used hooks. - * - * @since 2015-07-14 - */ - public function __construct() { + public function init() { if ( ! current_user_can( 'manage_network' ) ) { return; } diff --git a/src/class-add-ssl-identifier.php b/src/class-add-ssl-identifier.php index dba3690..a2695cf 100755 --- a/src/class-add-ssl-identifier.php +++ b/src/class-add-ssl-identifier.php @@ -31,14 +31,6 @@ public function init() { add_action( 'admin_print_styles-sites.php', array( $this, 'add_style' ) ); } - /** - * Constructor. - * - * Multisite_Add_Ssh_Identifier constructor. - */ - public function __construct() { - } - /** * Determines if SSL is used. * diff --git a/src/class-add-theme-list.php b/src/class-add-theme-list.php index 3419985..fef0da4 100755 --- a/src/class-add-theme-list.php +++ b/src/class-add-theme-list.php @@ -62,11 +62,9 @@ class Multisite_Add_Theme_List { private $blogs_themes; /** - * Init function to register all used hooks. - * - * @since 0.0.2 + * Initialize the class. */ - public function __construct() { + public function init() { // Delete transient on themes page. add_action( 'load-themes.php', array( $this, 'development_helper' ) ); @@ -92,17 +90,6 @@ public function __construct() { add_action( 'update_site_option_allowedthemes', array( $this, 'clear_themes_site_transient' ), 10, 1 ); } - /** - * Initialize the class. - */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - } - } - /** * Print Network Admin Notices to inform, that the transient are deleted. * @@ -136,13 +123,12 @@ public function add_themes_column( $columns ) { * Get data for each row on each theme. * Print the string about the usage. * - * @param String $column_name Name of the column. - * @param String $theme_key Path to the theme file. + * @param String $column_name Name of the column. + * @param String $theme_key Path to the theme file. * @param array|\WP_Theme $theme_data An array of theme data. * * @return null * @since 0.0.2 - * */ public function manage_themes_custom_column( $column_name, $theme_key, \WP_Theme $theme_data ) { if ( 'active_blogs' !== $column_name ) { @@ -187,7 +173,7 @@ public function manage_themes_custom_column( $column_name, $theme_key, \WP_Theme $is_list_hidden = false; // Hide the list of sites if the class isn"t loaded or there's less or equal to 4 sites. - if ( class_exists( 'Add_Css', false ) && $active_count > 4 ) { + if ( class_exists( Add_Css::class, false ) && $active_count > 4 ) { $output .= sprintf( // Translators: The placeholder will be replaced by the count and the toggle link of sites there use that themes. _n( @@ -216,7 +202,7 @@ public function manage_themes_custom_column( $column_name, $theme_key, \WP_Theme // Check the site for archived and deleted. $class = ''; - $hint = ''; + $hint = ''; if ( $this->is_archived( $key ) ) { $class = ' class="site-archived"'; $hint = ', ' . esc_attr__( 'Archived' ); diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index 5098737..66db827 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -14,14 +14,6 @@ */ class Multisite_Admin_Bar_Tweaks { - - /** - * Init function to register all used hooks. - * - * @since 0.0.1 - */ - public function __construct() { } - /** * Initialize this class. */ diff --git a/src/class-change-footer-text.php b/src/class-change-footer-text.php index 53d92b6..80e1511 100755 --- a/src/class-change-footer-text.php +++ b/src/class-change-footer-text.php @@ -44,25 +44,7 @@ class Multisite_Change_Footer_Text { /** * Initialize the class. */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - // phpcs:enable - } - } - - /** - * Init function to register all used hooks. - * - * Use the filter hook to change capability to view the new text on admin footer - * Hook: multisite_enhancements_admin_footer_text_capability - * - * @since 0.0.2 - */ - public function __construct() { - + public function init() { /** * Use this filter to change capability to view the new text on admin footer. * diff --git a/src/class-core.php b/src/class-core.php index 9d6ade3..0700e46 100755 --- a/src/class-core.php +++ b/src/class-core.php @@ -16,12 +16,6 @@ class Multisite_Core { * Init the class. */ public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - // phpcs:enable - } } /** diff --git a/src/class-filtering-themes.php b/src/class-filtering-themes.php index d60594c..79ed5c5 100755 --- a/src/class-filtering-themes.php +++ b/src/class-filtering-themes.php @@ -14,20 +14,11 @@ class Filtering_Themes { /** * Init the class. */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - $GLOBALS[ $class ] = new $class(); - } - } - - /** - * Filtering_Plugins constructor. - */ - public function __construct() { + public function init() { add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_script' ) ); } + /** * Enqueue scripts. * diff --git a/src/class-multisite-add-new-plugin.php b/src/class-multisite-add-new-plugin.php index ba8e11f..3bb10f5 100755 --- a/src/class-multisite-add-new-plugin.php +++ b/src/class-multisite-add-new-plugin.php @@ -15,20 +15,7 @@ class Multisite_Add_New_Plugin { /** * Init the class. */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - $GLOBALS[ $class ] = new $class(); - } - } - - /** - * Init function to register all used hooks. - * - * @since 0.0.1 - */ - public function __construct() { - + public function init() { // Only on each blog, not network admin. if ( is_network_admin() ) { return; diff --git a/src/core.php b/src/core.php index c54a0ac..b3359fd 100755 --- a/src/core.php +++ b/src/core.php @@ -36,7 +36,7 @@ function get_blog_list( $start = 0, $num = 10, $expires = 86400 ) { return false; } - if ( ! class_exists( 'Multisite_Core' ) ) { + if ( ! class_exists( Multisite_Core::class ) ) { require_once __DIR__ . '/class-core.php'; new Multisite_Core(); } diff --git a/src/settings.php b/src/settings.php index 4667516..31740a8 100644 --- a/src/settings.php +++ b/src/settings.php @@ -39,10 +39,11 @@ class Multisite_Enhancements_Settings { 'delete-settings' => 1, ); + /** - * Init function to register all used hooks. + * Initialize the class. */ - public function __construct() { + public function init() { // Register settings. add_action( 'admin_init', array( $this, 'settings_init' ) ); // Add menu item in the network Settings menu. @@ -51,17 +52,6 @@ public function __construct() { add_action( 'network_admin_edit_wpme_update_settings', array( $this, 'update_settings' ) ); } - /** - * Initialize the class. - */ - public static function init() { - $class = __CLASS__; - if ( empty( $GLOBALS[ $class ] ) ) { - // phpcs:disable - $GLOBALS[ $class ] = new $class(); - } - } - /** * Check if a feature is enabled * @@ -214,8 +204,8 @@ public function settings_fields_callback( $args ) {

@@ -269,5 +259,4 @@ public function update_settings() { ); exit; } - } // end class From b5a4b0efcc26a0b34a3570b6307f464bcc8ce03a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Fri, 7 Jun 2024 15:38:28 +0200 Subject: [PATCH 09/17] changed Namespace --- composer.json | 2 +- multisite-enhancements.php | 32 ++++++------- phpcs.xml | 2 +- src/class-add-admin-favicon.php | 16 ++++--- src/class-add-blog-id.php | 6 ++- src/class-add-css.php | 2 + src/class-add-plugin-list.php | 10 ++-- src/class-add-site-status-labels.php | 12 +++-- src/class-add-ssl-identifier.php | 6 +-- src/class-add-theme-list.php | 12 +++-- src/class-add-user-last-login.php | 9 ++-- src/class-admin-bar-tweaks.php | 8 ++-- src/class-change-footer-text.php | 8 ++-- src/class-core.php | 10 ++-- src/class-filtering-themes.php | 4 +- src/class-multisite-add-new-plugin.php | 6 ++- src/{settings.php => class-settings.php} | 47 ++++++++----------- src/core.php | 46 ------------------ .../Unit/MultisiteEnhancementsTest.php | 2 +- tests/phpunit/Unit/TestCase.php | 2 +- uninstall.php | 6 ++- 21 files changed, 108 insertions(+), 140 deletions(-) rename src/{settings.php => class-settings.php} (83%) delete mode 100755 src/core.php diff --git a/composer.json b/composer.json index 7a810f7..bc76c38 100644 --- a/composer.json +++ b/composer.json @@ -40,7 +40,7 @@ "prefer-stable": true, "autoload-dev": { "psr-4": { - "MultisiteEnhancements\\Tests\\": "tests/phpunit/" + "Multisite_Enhancements\\Tests\\": "tests/phpunit/" } }, "autoload": { diff --git a/multisite-enhancements.php b/multisite-enhancements.php index ef6b36e..bc4b723 100755 --- a/multisite-enhancements.php +++ b/multisite-enhancements.php @@ -64,33 +64,33 @@ public function load() { require_once __DIR__ . '/vendor/autoload.php'; - add_action( 'init', array( self::set_object( new Multisite_Enhancements_Settings() ), 'init' ) ); - add_action( 'init', array( self::set_object( new Multisite_Core() ), 'init' ) ); + add_action( 'init', array( self::set_object( new Multisite_Enhancements\Settings() ), 'init' ) ); + add_action( 'init', array( self::set_object( new Multisite_Enhancements\Core() ), 'init' ) ); $modules = array( - 'add-favicon' => array( 'init' => array( Multisite_Add_Admin_Favicon::class, 'init' ) ), - 'remove-logo' => array( 'init' => array( Multisite_Add_Admin_Favicon::class, 'init' ) ), - 'add-blog-id' => array( 'init' => array( Multisite_Add_Blog_Id::class, 'init' ) ), - 'add-css' => array( 'init' => array( Add_Css::class, 'init' ) ), - 'add-plugin-list' => array( 'init' => array( Multisite_Add_Plugin_List::class, 'init' ) ), - 'add-site-status' => array( 'init' => array( Multisite_Add_Site_Status_labels::class, 'init' ) ), + 'add-favicon' => array( 'init' => array( Multisite_Enhancements\Add_Admin_Favicon::class, 'init' ) ), + 'remove-logo' => array( 'init' => array( Multisite_Enhancements\Add_Admin_Favicon::class, 'init' ) ), + 'add-blog-id' => array( 'init' => array( Multisite_Enhancements\Add_Blog_Id::class, 'init' ) ), + 'add-css' => array( 'init' => array( Multisite_Enhancements\Add_Css::class, 'init' ) ), + 'add-plugin-list' => array( 'init' => array( Multisite_Enhancements\Add_Plugin_List::class, 'init' ) ), + 'add-site-status' => array( 'init' => array( Multisite_Enhancements\Add_Site_Status_Labels::class, 'init' ) ), 'add-ssl-identifier' => array( - 'admin_init' => array( Bueltge\Multisite_Add_Ssh_Identifier\Multisite_Add_Ssh_Identifier::class, 'init' ), + 'admin_init' => array( Multisite_Enhancements\Add_Ssh_Identifier::class, 'init' ), ), - 'add-theme-list' => array( 'init' => array( Multisite_Add_Theme_List::class, 'init' ) ), + 'add-theme-list' => array( 'init' => array( Multisite_Enhancements\Add_Theme_List::class, 'init' ) ), 'add-manage-comments' => array( - 'init' => array( Bueltge\Admin_Bar_Tweaks\Multisite_Admin_Bar_Tweaks::class, 'init' ), + 'init' => array( Multisite_Enhancements\Admin_Bar_Tweaks::class, 'init' ), ), - 'change-footer' => array( 'init' => array( Multisite_Change_Footer_Text::class, 'init' ) ), - 'filtering-themes' => array( 'admin_init' => array( Filtering_Themes::class, 'init' ) ), - 'add-new-plugin' => array( 'init' => array( Multisite_Add_New_Plugin::class, 'init' ) ), + 'change-footer' => array( 'init' => array( Multisite_Enhancements\Change_Footer_Text::class, 'init' ) ), + 'filtering-themes' => array( 'admin_init' => array( Multisite_Enhancements\Filtering_Themes::class, 'init' ) ), + 'add-new-plugin' => array( 'init' => array( Multisite_Enhancements\Multisite_Add_New_Plugin::class, 'init' ) ), 'add-user-last-login' => array( - 'init' => array( Bueltge\User_Last_Login\Add_User_Last_Login::class, 'init' ), + 'init' => array( Multisite_Enhancements\Add_User_Last_Login::class, 'init' ), ), ); foreach ( $modules as $id => $hooks ) { - if ( Multisite_Enhancements_Settings::is_feature_enabled( $id ) ) { + if ( Multisite_Enhancements\Settings::is_feature_enabled( $id ) ) { foreach ( $hooks as $hook_name => $callback ) { if ( is_string( $callback[0] ) && class_exists( $callback[0] ) ) { $callback[0] = self::set_object( new $callback[0]() ); diff --git a/phpcs.xml b/phpcs.xml index 0e72ee9..290e40b 100755 --- a/phpcs.xml +++ b/phpcs.xml @@ -38,7 +38,7 @@ - + diff --git a/src/class-add-admin-favicon.php b/src/class-add-admin-favicon.php index 9d672de..7fe7c8f 100755 --- a/src/class-add-admin-favicon.php +++ b/src/class-add-admin-favicon.php @@ -22,12 +22,14 @@ * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** * Add Favicon from theme folder to the admin area to easier identify the blog. * - * Class Multisite_Add_Admin_Favicon + * Class Add_Admin_Favicon */ -class Multisite_Add_Admin_Favicon { +class Add_Admin_Favicon { /** * Define Hooks for add the favicon markup. @@ -80,7 +82,7 @@ public function init() { * @since 0.0.2 */ public function set_favicon() { - if ( ! Multisite_Enhancements_Settings::is_feature_enabled( 'add-favicon' ) ) { + if ( ! Settings::is_feature_enabled( 'add-favicon' ) ) { return; } @@ -163,7 +165,7 @@ public function set_admin_bar_blog_icon() { // Only usable if the feature is enabled, the user is logged in and use the admin bar. if ( ! is_user_logged_in() || ! is_admin_bar_showing() || - ! Multisite_Enhancements_Settings::is_feature_enabled( 'add-favicon' ) ) { + ! Settings::is_feature_enabled( 'add-favicon' ) ) { return; } $user_id = get_current_user_id(); @@ -194,7 +196,7 @@ public function set_admin_bar_blog_icon() { if ( 0 !== $site_icon_id ) { switch_to_blog( $blog_id ); $url_data = wp_get_attachment_image_src( $site_icon_id, array( 32, 32 ) ); - if ( $url_data !== false && ! is_null( $url_data[0] ) ) { + if ( false !== $url_data && ! is_null( $url_data[0] ) ) { $custom_icon = esc_url( $url_data[0] ); } restore_current_blog(); @@ -240,7 +242,7 @@ public function set_admin_bar_blog_icon() { * Use the filter hook to change the default to remove the "W" logo and his sublinks * Hook: multisite_enhancements_remove_wp_admin_bar * - * @param WP_Admin_Bar $admin_bar WP_Admin_Bar instance, passed by reference. + * @param \WP_Admin_Bar $admin_bar WP_Admin_Bar instance, passed by reference. * * @since 0.0.2 */ @@ -251,7 +253,7 @@ public function change_admin_bar_menu( $admin_bar ) { * * @type bool */ - if ( Multisite_Enhancements_Settings::is_feature_enabled( 'remove-logo' ) && + if ( Settings::is_feature_enabled( 'remove-logo' ) && apply_filters( 'multisite_enhancements_remove_wp_admin_bar', self::$remove_wp_admin_bar diff --git a/src/class-add-blog-id.php b/src/class-add-blog-id.php index 3854b18..ce9c06e 100755 --- a/src/class-add-blog-id.php +++ b/src/class-add-blog-id.php @@ -8,11 +8,13 @@ * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** * View Blog and User ID in WordPress Multisite. - * Class Multisite_Add_Blog_Id + * Class Add_Blog_Id */ -class Multisite_Add_Blog_Id { +class Add_Blog_Id { /** * Init the class. diff --git a/src/class-add-css.php b/src/class-add-css.php index 71eff5d..b73f9a2 100755 --- a/src/class-add-css.php +++ b/src/class-add-css.php @@ -13,6 +13,8 @@ * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** * On the network plugin and theme pages, add css to present the active column * If this class is loaded, modify the presentation of the column in order to diff --git a/src/class-add-plugin-list.php b/src/class-add-plugin-list.php index 07027eb..9beff6d 100755 --- a/src/class-add-plugin-list.php +++ b/src/class-add-plugin-list.php @@ -4,13 +4,15 @@ * * @since 2013-07-19 * @version 2019-11-14 - * @package WordPress + * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** - * Class Multisite_Add_Plugin_List + * Class Add_Plugin_List */ -class Multisite_Add_Plugin_List { +class Add_Plugin_List { /** * On this plugin status will not show the not or activated status in the table of plugins. @@ -268,7 +270,7 @@ public function get_blogs_plugins() { // Cannot load data from transient, so load from DB and set transient. $this->blogs_plugins = array(); - $blogs = (array) Multisite_Core::get_blog_list( 0, $this->sites_limit ); + $blogs = (array) Core::get_blog_list( 0, $this->sites_limit ); /** * Data to each site of the network, blogs. diff --git a/src/class-add-site-status-labels.php b/src/class-add-site-status-labels.php index 3d5f1fb..11f8898 100755 --- a/src/class-add-site-status-labels.php +++ b/src/class-add-site-status-labels.php @@ -4,15 +4,17 @@ * * @since 2015-07-14 * @version 2019-11-14 - * @package WordPress + * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** * Add status labels to sites. * - * Class Multisite_Add_Site_Status_labels + * Class Add_Site_Status_labels */ -class Multisite_Add_Site_Status_labels { +class Add_Site_Status_Labels { /** * Initialize the class. @@ -68,11 +70,11 @@ public function is_site_live( $site_id ) { * * Use the filter hook 'multisite_enhancements_status_label' to change style, dashicon, markup. * - * @param WP_Admin_Bar $admin_bar All necessary admin bar items. + * @param \WP_Admin_Bar $admin_bar All necessary admin bar items. * * @return mixed */ - public function add_status_label( WP_Admin_Bar $admin_bar ) { + public function add_status_label( \WP_Admin_Bar $admin_bar ) { foreach ( $admin_bar->user->blogs as $key => $blog ) { $url_hint = ''; $live_hint = ''; diff --git a/src/class-add-ssl-identifier.php b/src/class-add-ssl-identifier.php index a2695cf..42a24d9 100755 --- a/src/class-add-ssl-identifier.php +++ b/src/class-add-ssl-identifier.php @@ -7,12 +7,12 @@ * @package multisite-enhancements */ -namespace Bueltge\Multisite_Add_Ssh_Identifier; +namespace Multisite_Enhancements; /** - * Class Multisite_Add_Ssh_Identifier + * Class Add_Ssh_Identifier */ -class Multisite_Add_Ssh_Identifier { +class Add_Ssh_Identifier { /** * Set column name to identifier the column. diff --git a/src/class-add-theme-list.php b/src/class-add-theme-list.php index fef0da4..e3f1e7c 100755 --- a/src/class-add-theme-list.php +++ b/src/class-add-theme-list.php @@ -7,12 +7,14 @@ * @package multisite-enhancement */ +namespace Multisite_Enhancements; + /** * On the network theme page, show which blog have the theme active. * - * Class Multisite_Add_Theme_List + * Class Add_Theme_List */ -class Multisite_Add_Theme_List { +class Add_Theme_List { /** * String for the transient string, there save the blog themes. @@ -273,7 +275,7 @@ public function get_blogs_themes() { // Cannot load data from transient, so load from DB and set transient. $this->blogs_themes = array(); - $blogs = (array) Multisite_Core::get_blog_list( 0, $this->sites_limit ); + $blogs = (array) Core::get_blog_list( 0, $this->sites_limit ); /** * Data to each site of the network, blogs. @@ -341,11 +343,11 @@ public function clear_themes_site_transient() { /** * Check, the current theme have a parent value and is a child theme. * - * @param array|WP_Theme $theme_data An array of theme data. + * @param \WP_Theme $theme_data An array of theme data. * * @return bool */ - public function is_child( WP_Theme $theme_data ) { + public function is_child( \WP_Theme $theme_data ) { return (bool) $theme_data->parent(); } diff --git a/src/class-add-user-last-login.php b/src/class-add-user-last-login.php index 212ebec..f19e48e 100644 --- a/src/class-add-user-last-login.php +++ b/src/class-add-user-last-login.php @@ -1,11 +1,14 @@ get_results( $wpdb->prepare( " diff --git a/src/class-filtering-themes.php b/src/class-filtering-themes.php index 79ed5c5..f33e963 100755 --- a/src/class-filtering-themes.php +++ b/src/class-filtering-themes.php @@ -3,9 +3,11 @@ * Add simple javascript to filter the theme list on network and single site theme page of WordPress back end. * * @since 2016-10-05 - * @package WordPress + * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** * Class Filtering_Themes */ diff --git a/src/class-multisite-add-new-plugin.php b/src/class-multisite-add-new-plugin.php index 3bb10f5..5c39603 100755 --- a/src/class-multisite-add-new-plugin.php +++ b/src/class-multisite-add-new-plugin.php @@ -4,11 +4,13 @@ * * @since 2013-07-19 * @version 2016-01-15 - * @package WordPress + * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** - * Class Multisite_Add_New_Plugin + * Class Add_New_Plugin */ class Multisite_Add_New_Plugin { diff --git a/src/settings.php b/src/class-settings.php similarity index 83% rename from src/settings.php rename to src/class-settings.php index 31740a8..d0dceff 100644 --- a/src/settings.php +++ b/src/class-settings.php @@ -6,10 +6,12 @@ * @package multisite-enhancements */ +namespace Multisite_Enhancements; + /** - * Class Multisite_Enhancements_Settings + * Class Settings */ -class Multisite_Enhancements_Settings { +class Settings { /** * Database option name @@ -55,7 +57,7 @@ public function init() { /** * Check if a feature is enabled * - * @param string $key Key of desired setting to check + * @param string $key Key of desired setting to check. * * @return boolean */ @@ -71,29 +73,25 @@ public function settings_init() { return; } - // register database option register_setting( - 'wpme_options', // group name, used in settings_fields() call - self::OPTION_NAME // database option name + 'wpme_options', + self::OPTION_NAME ); - // register configuration page section add_settings_section( - 'wpme_general', // unique ID - esc_html__( 'General configuration', 'multisite-enhancements' ), // section title - array( $this, 'settings_section_callback' ), // callback to render the section's HTML - 'wpme_config' // config page slug - used in do_settings_sections() call + 'wpme_general', + esc_html__( 'General configuration', 'multisite-enhancements' ), + array( $this, 'settings_section_callback' ), + 'wpme_config' ); - // register form field groups - add_settings_field( - 'enable_features', // unique ID - esc_html__( 'Plugin features', 'multisite-enhancements' ), // field label + 'enable_features', + esc_html__( 'Plugin features', 'multisite-enhancements' ), array( $this, 'settings_fields_callback' ), - 'wpme_config', // config page slug - 'wpme_general', // section ID where the field will be shown - array( // arguments passed to the callback function ('label_for' and 'class' go here, when needed) + 'wpme_config', + 'wpme_general', + array( 'group' => 'features', ) ); @@ -133,7 +131,6 @@ public function settings_page_callback() { return; } - // check if coming from the update function if ( isset( $_GET['updated'] ) ) { ?>
@@ -141,17 +138,13 @@ public function settings_page_callback() {

@@ -162,7 +155,7 @@ public function settings_page_callback() { /** * Configuration sections callback * - * @param array $args array with following keys: title, id, callback - defined by add_settings_section() + * @param array $args array with following keys: title, id, callback - defined by add_settings_section(). */ public function settings_section_callback( $args ) { if ( 'wpme_general' === $args['id'] ) { @@ -173,7 +166,7 @@ public function settings_section_callback( $args ) { /** * Configuration fields callback * - * @param array $args arguments defined by add_settings_field() + * @param array $args arguments defined by add_settings_field(). */ public function settings_fields_callback( $args ) { $settings = array( @@ -216,7 +209,7 @@ public function settings_fields_callback( $args ) { /** * Load settings from database and merge them with default values * - * @param string [ $key] Key of an specific setting desired (optional). + * @param string $key Key of an specific setting desired (optional). * * @return string|array Value of setting selected by $key or full array of settings. */ @@ -244,10 +237,8 @@ public function update_settings() { $options[ $key ] = (int) isset( $options[ $key ] ); } - // update option on database update_site_option( self::OPTION_NAME, $options ); - // redirect back to our options page wp_redirect( add_query_arg( array( diff --git a/src/core.php b/src/core.php deleted file mode 100755 index b3359fd..0000000 --- a/src/core.php +++ /dev/null @@ -1,46 +0,0 @@ - Date: Fri, 7 Jun 2024 16:22:15 +0200 Subject: [PATCH 10/17] phpcs fixes --- src/class-add-plugin-list.php | 23 +++++++++++++---------- src/class-add-theme-list.php | 15 +++++++++------ src/class-admin-bar-tweaks.php | 2 ++ src/class-core.php | 2 +- src/class-settings.php | 9 +++++++-- 5 files changed, 32 insertions(+), 19 deletions(-) diff --git a/src/class-add-plugin-list.php b/src/class-add-plugin-list.php index 9beff6d..e231aab 100755 --- a/src/class-add-plugin-list.php +++ b/src/class-add-plugin-list.php @@ -121,13 +121,15 @@ public function notice_about_clear_cache() { */ public function add_plugins_column( $columns ) { - // If not set, then no changes on output. - if ( ! array_key_exists( 'plugin_status', $_GET ) ) { - $_GET['plugin_status'] = ''; + $status = ''; + //phpcs:ignore WordPress.Security.NonceVerification.Recommended + if ( isset( $_GET['plugin_status'] ) ) { + //phpcs:ignore WordPress.Security.NonceVerification.Recommended + $status = esc_attr( wp_unslash( sanitize_key( $_GET['plugin_status'] ) ) ); } // Not useful on different selections. - if ( ! in_array( esc_attr( $_GET['plugin_status'] ), self::$excluded_plugin_status, true ) ) { + if ( ! in_array( $status, self::$excluded_plugin_status, true ) ) { // Translators: Active in is the head of the table column on plugin list. $columns['active_blogs'] = _x( 'Usage', 'column name', 'multisite-enhancements' ); } @@ -145,7 +147,7 @@ public function add_plugins_column( $columns ) { * @param String $plugin_file Path to the plugin file. * @param array $plugin_data An array of plugin data. * - * @return void + * @return null */ public function manage_plugins_custom_column( $column_name, $plugin_file, $plugin_data ) { if ( 'active_blogs' !== $column_name ) { @@ -160,14 +162,14 @@ public function manage_plugins_custom_column( $column_name, $plugin_file, $plugi if ( $active_on_network ) { // We don't need to check any further for network active plugins. // Translators: The plugin is network wide active, the string is for each plugin possible. - $output .= __( 'Network Activated', 'multisite-enhancements' ); + $output .= '' . __( 'Network Activated', 'multisite-enhancements' ) . ''; // List Blogs, there is activated. } else { // Is this plugin active on any blogs in this network. $active_on_blogs = $this->is_plugin_active_on_blogs( $plugin_file ); if ( ! $active_on_blogs ) { // Translators: The plugin is not activated, the string is for each plugin possible. - $output .= __( 'Not Activated', 'multisite-enhancements' ); + $output .= '' . __( 'Not Activated', 'multisite-enhancements' ) . ''; } else { $active_count = count( $active_on_blogs ); $output .= '

'; @@ -206,6 +208,7 @@ public function manage_plugins_custom_column( $column_name, $plugin_file, $plugi } $output .= ''; $output .= '' + //phpcs:ignore Universal.Operators.DisallowShortTernary.Found . ( trim( $value['name'] ) ?: $value['path'] ) . '' . $hint . ''; } $output .= ''; @@ -260,12 +263,12 @@ public function is_plugin_active_on_blogs( $plugin_file ) { */ public function get_blogs_plugins() { - // See if the data is present in the variable first. if ( $this->blogs_plugins ) { return $this->blogs_plugins; + } - // If not, see if we can load data from the transient. - } elseif ( false === ( $this->blogs_plugins = get_site_transient( self::$site_transient_blogs_plugins ) ) ) { + $this->blogs_plugins = get_site_transient( self::$site_transient_blogs_plugins ); + if ( false === $this->blogs_plugins ) { // Cannot load data from transient, so load from DB and set transient. $this->blogs_plugins = array(); diff --git a/src/class-add-theme-list.php b/src/class-add-theme-list.php index e3f1e7c..51605b9 100755 --- a/src/class-add-theme-list.php +++ b/src/class-add-theme-list.php @@ -103,7 +103,7 @@ public function notice_about_clear_cache() { 'Multisite Enhancements: Theme usage information is not cached while WP_DEBUG is true.', 'multisite-enhancements' ); - printf( '

%2$s

', $class, esc_attr( $message ) ); + printf( '

%2$s

', esc_attr( $class ), esc_attr( $message ) ); } /** @@ -166,7 +166,7 @@ public function manage_themes_custom_column( $column_name, $theme_key, \WP_Theme if ( ! $active_on_blogs ) { // Translators: The theme is not activated, the string is for each plugin possible. - $output .= __( 'Not Activated', 'multisite-enhancements' ); + $output .= '' . __( 'Not Activated', 'multisite-enhancements' ) . ''; $output .= $child_context; $output .= $parent_context; } else { @@ -207,15 +207,18 @@ public function manage_themes_custom_column( $column_name, $theme_key, \WP_Theme $hint = ''; if ( $this->is_archived( $key ) ) { $class = ' class="site-archived"'; - $hint = ', ' . esc_attr__( 'Archived' ); + //phpcs:ignore WordPress.WP.I18n.MissingArgDomain + $hint = ', ' . esc_attr__( 'Archived' ); } if ( $this->is_deleted( $key ) ) { $class = ' class="site-deleted"'; + //phpcs:ignore WordPress.WP.I18n.MissingArgDomain $hint .= ', ' . esc_attr__( 'Deleted' ); } $output .= ''; $output .= '' + //phpcs:ignore Universal.Operators.DisallowShortTernary.Found . ( trim( $value['name'] ) ?: $value['path'] ) . '' . $hint . ''; $output .= ''; } @@ -265,12 +268,12 @@ public function is_theme_active_on_blogs( $theme_key ) { */ public function get_blogs_themes() { - // See if the data is present in the variable first. if ( $this->blogs_themes ) { return $this->blogs_themes; + } - // If not, see if we can load data from the transient. - } elseif ( false === ( $this->blogs_themes = get_site_transient( self::$site_transient_blogs_themes ) ) ) { + $this->blogs_themes = get_site_transient( self::$site_transient_blogs_themes ); + if ( false === $this->blogs_themes ) { // Cannot load data from transient, so load from DB and set transient. $this->blogs_themes = array(); diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index 0b6dc24..5721153 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -48,12 +48,14 @@ public function enhance_network_blog_admin_bar() { $awaiting_mod = wp_count_comments(); $awaiting_mod = $awaiting_mod->moderated; + // phpcs:ignore WordPress.WP.I18n.MissingArgDomain $title = esc_html__( 'Manage Comments' ) . '' . number_format_i18n( $awaiting_mod ) . ''; $awaiting_title = esc_attr( sprintf( + // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment, WordPress.WP.I18n.MissingArgDomain _n( '%s comment awaiting moderation', '%s comments awaiting moderation', diff --git a/src/class-core.php b/src/class-core.php index 2ed4b53..e4c9235 100755 --- a/src/class-core.php +++ b/src/class-core.php @@ -77,7 +77,7 @@ public static function get_blog_list( $start = 0, $num = 10, $details = false, $ $limit = ''; } - // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared $blogs = $wpdb->get_results( $wpdb->prepare( " diff --git a/src/class-settings.php b/src/class-settings.php index d0dceff..c07577c 100644 --- a/src/class-settings.php +++ b/src/class-settings.php @@ -131,6 +131,7 @@ public function settings_page_callback() { return; } + //phpcs:ignore WordPress.Security.NonceVerification.Recommended if ( isset( $_GET['updated'] ) ) { ?>
@@ -231,7 +232,11 @@ public function update_settings() { // check the referer to make sure the data comes from our options page. check_admin_referer( 'wpme_options-options' ); - $options = $_POST['wpme_options']; + if ( ! isset( $_POST['wpme_options'] ) && ! is_array( $_POST['wpme_options'] ) ) { + return; + } + // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized + $options = wp_unslash( $_POST['wpme_options'] ); foreach ( array_keys( self::$default_options ) as $key ) { $options[ $key ] = (int) isset( $options[ $key ] ); @@ -239,7 +244,7 @@ public function update_settings() { update_site_option( self::OPTION_NAME, $options ); - wp_redirect( + wp_safe_redirect( add_query_arg( array( 'page' => 'wpme_config', From 04d4ec3b40b51fd07f20bc1f06bf8b6c16f66dcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Fri, 7 Jun 2024 16:28:56 +0200 Subject: [PATCH 11/17] add changelog entry's --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5c9d461..3f9cf7f 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,9 @@ All notable changes to this project will be documented in this file. This projec * Change dashicons from lock/unlock to yes/no to optimize the visual difference of the icon to spot http usage easier. Probs @Zodiac1978 [#76](https://github.com/bueltge/wordpress-multisite-enhancements/pull/70) ## [1.7.0](https://github.com/bueltge/wordpress-multisite-enhancements/compare/1.6.0...1.6.1) - 2024-06- +* Added functionalty to see when a user last time logs in * Update min PHP Version to 7.2 +* Added Namespace, Autoloading, and many more PHP improvements ## [1.6.1](https://github.com/bueltge/wordpress-multisite-enhancements/compare/1.6.0...1.6.1) - 2021-01-20 * Fix path for css/js files. From 8790578623ae8642ab4b0dfaed4eb224d0fb08e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Fri, 7 Jun 2024 16:41:10 +0200 Subject: [PATCH 12/17] Update git workflow --- .github/workflows/code-style.yml | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/.github/workflows/code-style.yml b/.github/workflows/code-style.yml index f544d11..b34b93c 100644 --- a/.github/workflows/code-style.yml +++ b/.github/workflows/code-style.yml @@ -13,7 +13,7 @@ jobs: strategy: matrix: - php-versions: ['5.6', '7.2', '7.3', '7.4', '8.0'] + php-versions: ['7.2', '7.3', '7.4', '8.0', '8.1', '8.2', '8.3'] steps: - uses: actions/checkout@v2 @@ -46,4 +46,7 @@ jobs: run: composer install -q -n -a --no-progress --prefer-dist - name: Run phpCS Scripts from composer.json - run: composer cs \ No newline at end of file + run: composer cs + + - name: Run Unit Test from composer.json + run: composer pu From 3ec21fc3647308e93e7b0bcaf6fa6bd1a8a76203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Mon, 10 Jun 2024 11:17:07 +0200 Subject: [PATCH 13/17] Added some tests --- src/class-settings.php | 6 +- .../Unit/MultisiteEnhancementsTest.php | 70 +++++++++++++++++-- tests/phpunit/Unit/TestCase.php | 10 +++ tests/phpunit/bootstrap.php | 11 +-- 4 files changed, 82 insertions(+), 15 deletions(-) diff --git a/src/class-settings.php b/src/class-settings.php index c07577c..5b2f757 100644 --- a/src/class-settings.php +++ b/src/class-settings.php @@ -24,7 +24,7 @@ class Settings { * * @var int[] */ - protected static $default_options = array( + const DEFAULT_OPTIONS = array( 'remove-logo' => 1, 'add-favicon' => 1, 'add-blog-id' => 1, @@ -216,7 +216,7 @@ public function settings_fields_callback( $args ) { */ public static function get_settings( $key = null ) { $options = get_site_option( self::OPTION_NAME ); - $options = wp_parse_args( $options, self::$default_options ); + $options = wp_parse_args( $options, self::DEFAULT_OPTIONS ); if ( isset( $key ) ) { return $options[ $key ]; @@ -238,7 +238,7 @@ public function update_settings() { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized $options = wp_unslash( $_POST['wpme_options'] ); - foreach ( array_keys( self::$default_options ) as $key ) { + foreach ( array_keys( self::DEFAULT_OPTIONS ) as $key ) { $options[ $key ] = (int) isset( $options[ $key ] ); } diff --git a/tests/phpunit/Unit/MultisiteEnhancementsTest.php b/tests/phpunit/Unit/MultisiteEnhancementsTest.php index 2118a49..2fda016 100755 --- a/tests/phpunit/Unit/MultisiteEnhancementsTest.php +++ b/tests/phpunit/Unit/MultisiteEnhancementsTest.php @@ -2,17 +2,79 @@ namespace Multisite_Enhancements\Tests\Unit; +use Brain\Monkey\Functions; + /** * First Test */ class MultisiteEnhancementsTest extends TestCase { + + /** + * Test getting and setting objects + * + * @return void + */ + public function testContainer() { + + $object = \Multisite_Enhancements::get_object( 'TestClassName' ); + $this->assertNull( $object ); + + $object = new \stdClass(); + $std_object_0 = \Multisite_Enhancements::set_object( $object ); + $this->assertInstanceOf( \stdClass::class, $std_object_0 ); + $std_object_1 = \Multisite_Enhancements::get_object( \stdClass::class ); + $this->assertInstanceOf( \stdClass::class, $std_object_1 ); + + $plugin = \Multisite_Enhancements::get_object(); + $this->assertInstanceOf( \Multisite_Enhancements::class, $plugin ); + } + + /** + * Test the load method + * + * @return void + */ + public function testLoad() { + + $mock_settings = \Mockery::mock( 'alias:' . \Multisite_Enhancements\Settings::class ); + $mock_settings->shouldReceive( 'is_feature_enabled' )->andReturn( true ); + + Functions\when( 'is_multisite' )->justReturn( true ); + Functions\when( 'load_plugin_textdomain' )->justReturn( true ); + + $plugin = \Multisite_Enhancements::get_object(); + $plugin->load(); + + if ( defined( 'MULTISITE_ENHANCEMENT_BASE' ) ) { + $this->assertEquals( realpath( __DIR__ . '/../../../src' ), MULTISITE_ENHANCEMENT_BASE ); + } else { + $this->fail( 'Const MULTISITE_ENHANCEMENT_BASE not defined!' ); + } + + $settings_object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Settings::class ); + self::assertNotFalse( has_action( 'init', [ $settings_object, 'init' ] ) ); + $core_object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Core::class ); + self::assertNotFalse( has_action( 'init', [ $core_object, 'init' ] ) ); + + $object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Add_Admin_Favicon::class ); + self::assertNotFalse( has_action( 'init', [ $object, 'init' ] ) ); + $object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Add_Blog_Id::class ); + self::assertNotFalse( has_action( 'init', [ $object, 'init' ] ) ); + $object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Filtering_Themes::class ); + self::assertNotFalse( has_action( 'admin_init', [ $object, 'init' ] ) ); + } + /** - * First Test + * Test the load of Translations * * @return void */ - public function testBasicInstantiation() { - $plugin = new \Multisite_Enhancements(); - static::assertInstanceOf( \Multisite_Enhancements::class, $plugin ); + public function testLoadTranslations() { + + $plugin = \Multisite_Enhancements::get_object(); + + Functions\expect( 'load_plugin_textdomain' )->once()->with( 'multisite-enhancements', false, basename( dirname( __DIR__, 3 ) ) . '/languages/' ); + + $plugin->load_translation(); } } diff --git a/tests/phpunit/Unit/TestCase.php b/tests/phpunit/Unit/TestCase.php index c3d365b..3502379 100755 --- a/tests/phpunit/Unit/TestCase.php +++ b/tests/phpunit/Unit/TestCase.php @@ -13,6 +13,16 @@ class TestCase extends \PHPUnit\Framework\TestCase { // Adds Mockery expectations to the PHPUnit assertions count. use MockeryPHPUnitIntegration; + /** + * Set up for tests + * + * @return void + */ + protected function setUp(): void { + parent::setUp(); + Monkey\setUp(); + } + /** * Tears down the environment. * diff --git a/tests/phpunit/bootstrap.php b/tests/phpunit/bootstrap.php index 2c9db76..70d74ba 100755 --- a/tests/phpunit/bootstrap.php +++ b/tests/phpunit/bootstrap.php @@ -1,12 +1,7 @@ Date: Mon, 10 Jun 2024 12:01:53 +0200 Subject: [PATCH 14/17] Removed not longer needed code because of requirements --- CHANGELOG.md | 8 +- multisite-enhancements.php | 1 - src/class-add-admin-favicon.php | 16 +- src/class-add-plugin-list.php | 26 +-- src/class-add-theme-list.php | 18 ++- src/class-admin-bar-tweaks.php | 2 +- src/class-change-footer-text.php | 14 +- src/class-core.php | 151 ------------------ .../Unit/MultisiteEnhancementsTest.php | 2 - 9 files changed, 36 insertions(+), 202 deletions(-) delete mode 100755 src/class-core.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f9cf7f..bfac894 100755 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,11 +6,9 @@ All notable changes to this project will be documented in this file. This projec * Enhance the footer information to make more clear about the memory values. [#71](https://github.com/bueltge/wordpress-multisite-enhancements/issues/71) * Fix php note for favicon functionality. [#65](https://github.com/bueltge/wordpress-multisite-enhancements/issues/65) * Change dashicons from lock/unlock to yes/no to optimize the visual difference of the icon to spot http usage easier. Probs @Zodiac1978 [#76](https://github.com/bueltge/wordpress-multisite-enhancements/pull/70) - -## [1.7.0](https://github.com/bueltge/wordpress-multisite-enhancements/compare/1.6.0...1.6.1) - 2024-06- -* Added functionalty to see when a user last time logs in -* Update min PHP Version to 7.2 -* Added Namespace, Autoloading, and many more PHP improvements +* Added functionality to see when a user last time logs in +* Update minimum PHP Version to 7.2 +* Added Namespace, Autoloading, and many more PHP improvements and cleanups ## [1.6.1](https://github.com/bueltge/wordpress-multisite-enhancements/compare/1.6.0...1.6.1) - 2021-01-20 * Fix path for css/js files. diff --git a/multisite-enhancements.php b/multisite-enhancements.php index bc4b723..3a4dfaa 100755 --- a/multisite-enhancements.php +++ b/multisite-enhancements.php @@ -65,7 +65,6 @@ public function load() { require_once __DIR__ . '/vendor/autoload.php'; add_action( 'init', array( self::set_object( new Multisite_Enhancements\Settings() ), 'init' ) ); - add_action( 'init', array( self::set_object( new Multisite_Enhancements\Core() ), 'init' ) ); $modules = array( 'add-favicon' => array( 'init' => array( Multisite_Enhancements\Add_Admin_Favicon::class, 'init' ) ), diff --git a/src/class-add-admin-favicon.php b/src/class-add-admin-favicon.php index 7fe7c8f..548e01c 100755 --- a/src/class-add-admin-favicon.php +++ b/src/class-add-admin-favicon.php @@ -37,18 +37,10 @@ class Add_Admin_Favicon { * @since 0.0.2 * @var array */ - protected static $favicon_hooks = array( + const FAVICON_HOOKS = array( 'admin_head', 'wp_head', ); - /** - * Filter to remove "W" logo incl. sublinks from admin bar. - * - * @since 0.0.2 - * @var Boolean - */ - protected static $remove_wp_admin_bar = true; - /** * Initialize the class. @@ -58,9 +50,9 @@ public function init() { /** * Hooks for add favicon markup. * - * @type array + * @type array of filters */ - $hooks = (array) apply_filters( 'multisite_enhancements_favicon', self::$favicon_hooks ); + $hooks = (array) apply_filters( 'multisite_enhancements_favicon', self::FAVICON_HOOKS ); foreach ( $hooks as $hook ) { add_action( esc_attr( $hook ), array( $this, 'set_favicon' ) ); @@ -256,7 +248,7 @@ public function change_admin_bar_menu( $admin_bar ) { if ( Settings::is_feature_enabled( 'remove-logo' ) && apply_filters( 'multisite_enhancements_remove_wp_admin_bar', - self::$remove_wp_admin_bar + true ) ) { $admin_bar->remove_node( 'wp-logo' ); diff --git a/src/class-add-plugin-list.php b/src/class-add-plugin-list.php index e231aab..6a2aa9f 100755 --- a/src/class-add-plugin-list.php +++ b/src/class-add-plugin-list.php @@ -20,20 +20,20 @@ class Add_Plugin_List { * @since 01/03/2014 * @var array */ - protected static $excluded_plugin_status = array( 'dropins', 'mustuse' ); + const EXCLUDED_PLUGIN_STATUS = array( 'dropins', 'mustuse' ); /** * String for the transient string, there save the blog plugins. * * @since 2015-02-21 * @var string */ - protected static $site_transient_blogs_plugins = 'blogs_plugins'; + const SITE_TRANSIENT_BLOGS_PLUGINS = 'blogs_plugins'; /** * Define the allowed html tags for wp_kses. * * @var array */ - protected static $wp_kses_allowed_html = array( + const WP_KSES_ALLOWED_HTML = array( 'br' => array(), 'span' => array( 'class' => array(), @@ -129,7 +129,7 @@ public function add_plugins_column( $columns ) { } // Not useful on different selections. - if ( ! in_array( $status, self::$excluded_plugin_status, true ) ) { + if ( ! in_array( $status, self::EXCLUDED_PLUGIN_STATUS, true ) ) { // Translators: Active in is the head of the table column on plugin list. $columns['active_blogs'] = _x( 'Usage', 'column name', 'multisite-enhancements' ); } @@ -146,12 +146,10 @@ public function add_plugins_column( $columns ) { * @param String $column_name Name of the column. * @param String $plugin_file Path to the plugin file. * @param array $plugin_data An array of plugin data. - * - * @return null */ public function manage_plugins_custom_column( $column_name, $plugin_file, $plugin_data ) { if ( 'active_blogs' !== $column_name ) { - return null; + return; } // Is this plugin network activated. if ( ! function_exists( 'is_plugin_active_for_network' ) ) { @@ -223,7 +221,7 @@ public function manage_plugins_custom_column( $column_name, $plugin_file, $plugi . esc_attr__( 'Network Only', 'multisite-enhancements' ) . ''; } - echo wp_kses( $output, self::$wp_kses_allowed_html ); + echo wp_kses( $output, self::WP_KSES_ALLOWED_HTML ); } /** @@ -267,13 +265,17 @@ public function get_blogs_plugins() { return $this->blogs_plugins; } - $this->blogs_plugins = get_site_transient( self::$site_transient_blogs_plugins ); + $this->blogs_plugins = get_site_transient( self::SITE_TRANSIENT_BLOGS_PLUGINS ); if ( false === $this->blogs_plugins ) { // Cannot load data from transient, so load from DB and set transient. $this->blogs_plugins = array(); - $blogs = (array) Core::get_blog_list( 0, $this->sites_limit ); + $blogs = (array) get_sites( + array( + 'number' => $this->sites_limit, + ) + ); /** * Data to each site of the network, blogs. @@ -305,7 +307,7 @@ public function get_blogs_plugins() { } if ( ! $this->development_helper() ) { - set_site_transient( self::$site_transient_blogs_plugins, $this->blogs_plugins ); + set_site_transient( self::SITE_TRANSIENT_BLOGS_PLUGINS, $this->blogs_plugins ); } } @@ -336,7 +338,7 @@ public function development_helper() { * @since 2015-02-25 */ public function clear_plugins_site_transient() { - delete_site_transient( self::$site_transient_blogs_plugins ); + delete_site_transient( self::SITE_TRANSIENT_BLOGS_PLUGINS ); } /** diff --git a/src/class-add-theme-list.php b/src/class-add-theme-list.php index 51605b9..abaf305 100755 --- a/src/class-add-theme-list.php +++ b/src/class-add-theme-list.php @@ -22,13 +22,13 @@ class Add_Theme_List { * @since 2015-02-21 * @var string */ - protected static $site_transient_blogs_themes = 'blogs_themes'; + const SITE_TRANSIENT_BLOGS_THEMES = 'blogs_themes'; /** * Define the allowed html tags for wp_kses. * * @var array */ - protected static $wp_kses_allowed_html = array( + const WP_KSES_ALLOWED_HTML = array( 'br' => array(), 'span' => array( 'class' => array(), @@ -228,7 +228,7 @@ public function manage_themes_custom_column( $column_name, $theme_key, \WP_Theme $output .= $parent_context; } - echo wp_kses( $output, self::$wp_kses_allowed_html ); + echo wp_kses( $output, self::WP_KSES_ALLOWED_HTML ); } /** @@ -272,13 +272,17 @@ public function get_blogs_themes() { return $this->blogs_themes; } - $this->blogs_themes = get_site_transient( self::$site_transient_blogs_themes ); + $this->blogs_themes = get_site_transient( self::SITE_TRANSIENT_BLOGS_THEMES ); if ( false === $this->blogs_themes ) { // Cannot load data from transient, so load from DB and set transient. $this->blogs_themes = array(); - $blogs = (array) Core::get_blog_list( 0, $this->sites_limit ); + $blogs = (array) get_sites( + array( + 'number' => $this->sites_limit, + ) + ); /** * Data to each site of the network, blogs. @@ -309,7 +313,7 @@ public function get_blogs_themes() { } if ( ! $this->development_helper() ) { - set_site_transient( self::$site_transient_blogs_themes, $this->blogs_themes ); + set_site_transient( self::SITE_TRANSIENT_BLOGS_THEMES, $this->blogs_themes ); } } @@ -340,7 +344,7 @@ public function development_helper() { * @since 2015-02-21 */ public function clear_themes_site_transient() { - delete_site_transient( self::$site_transient_blogs_themes ); + delete_site_transient( self::SITE_TRANSIENT_BLOGS_THEMES ); } /** diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index 5721153..b758dcc 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -33,7 +33,7 @@ public function enhance_network_blog_admin_bar() { * The Toolbar API class. */ global $wp_admin_bar; - if ( ! isset( $wp_admin_bar->user->blogs ) || ! Multisite_Enhancements_Settings::is_feature_enabled( 'add-manage-comments' ) ) { + if ( ! isset( $wp_admin_bar->user->blogs ) || ! Settings::is_feature_enabled( 'add-manage-comments' ) ) { return; } diff --git a/src/class-change-footer-text.php b/src/class-change-footer-text.php index 165c563..e8e168a 100755 --- a/src/class-change-footer-text.php +++ b/src/class-change-footer-text.php @@ -33,15 +33,7 @@ class Change_Footer_Text { * @since 0.0.2 * @var String */ - protected static $capability = 'manage_options'; - - /** - * Filter to reset admin footer message. - * - * @since 0.0.2 - * @var Boolean - */ - protected static $reset_footer_text = true; + const CAPABILITY = 'manage_options'; /** * Initialize the class. @@ -54,7 +46,7 @@ public function init() { */ $capability = apply_filters( 'multisite_enhancements_admin_footer_text_capability', - self::$capability + self::CAPABILITY ); // Get default content for non admins. @@ -85,7 +77,7 @@ public function get_footer_text( $footer_text ) { */ if ( apply_filters( 'multisite_enhancements_reset_admin_footer_text', - self::$reset_footer_text + true ) ) { $footer_text = ''; diff --git a/src/class-core.php b/src/class-core.php deleted file mode 100755 index e4c9235..0000000 --- a/src/class-core.php +++ /dev/null @@ -1,151 +0,0 @@ - $num, - ) - ); - } - - // For WordPress smaller version 4.6.0, available since WordPress 3.7. - // phpcs:disable WordPress.WP.DeprecatedFunctions.wp_get_sitesFound - if ( function_exists( 'wp_get_sites' ) ) { - return wp_get_sites( - array( - 'limit' => $num, - ) - ); - } - // phpcs:enable - - // Get blog list from cache. - $blogs = get_site_transient( 'multisite_blog_list' ); - - // For debugging purpose. - if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - $blogs = false; - } - - if ( false === $blogs ) { - global $wpdb; - - // Add limit for select. - $limit = "LIMIT $start, $num"; - if ( 'all' === $num ) { - $limit = ''; - } - - // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared - $blogs = $wpdb->get_results( - $wpdb->prepare( - " - SELECT blog_id, domain, path - FROM $wpdb->blogs - WHERE site_id = %d - AND public = '1' - AND archived = '0' - AND mature = '0' - AND spam = '0' - AND deleted = '0' - ORDER BY registered ASC - $limit - ", - $wpdb->siteid - ), - ARRAY_A - ); - // phpcs:enable - - // Set the Transient cache. - set_site_transient( 'multisite_blog_list', $blogs, $expires ); - } - - // Only if usable, set via var. - if ( true === $details ) { - /** - * Get data to each site in the network. - * - * @var array $blog_list - */ - $blog_list = get_site_transient( 'multisite_blog_list_details' ); - - // For debugging purpose. - if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) { - $blog_list = false; - } - - if ( false === $blog_list ) { - global $wpdb; - /** - * The data details of each site of the network. - * - * @var array $blog_details - */ - foreach ( (array) $blogs as $blog_details ) { - // phpcs:disable - $blog_list[ $blog_details['blog_id'] ] = $blog_details; - $blog_list[ $blog_details['blog_id'] ]['postcount'] = $wpdb->get_var( - 'SELECT COUNT(ID) - FROM ' . $wpdb->get_blog_prefix( $blog_details['blog_id'] ) . "posts - WHERE post_status='publish' - AND post_type='post'" - ); - // phpcs:enable - } - - // Set the Transient cache. - set_site_transient( 'multisite_blog_list_details', $blog_list, $expires ); - } - unset( $blogs ); - $blogs = $blog_list; - } - - if ( false === is_array( $blogs ) ) { - return array(); - } - - return $blogs; - } -} // end class diff --git a/tests/phpunit/Unit/MultisiteEnhancementsTest.php b/tests/phpunit/Unit/MultisiteEnhancementsTest.php index 2fda016..e13ce60 100755 --- a/tests/phpunit/Unit/MultisiteEnhancementsTest.php +++ b/tests/phpunit/Unit/MultisiteEnhancementsTest.php @@ -53,8 +53,6 @@ public function testLoad() { $settings_object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Settings::class ); self::assertNotFalse( has_action( 'init', [ $settings_object, 'init' ] ) ); - $core_object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Core::class ); - self::assertNotFalse( has_action( 'init', [ $core_object, 'init' ] ) ); $object = \Multisite_Enhancements::get_object( \Multisite_Enhancements\Add_Admin_Favicon::class ); self::assertNotFalse( has_action( 'init', [ $object, 'init' ] ) ); From 12fdc96a669f9d420b043d904d271d8375e945a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Mon, 10 Jun 2024 12:37:55 +0200 Subject: [PATCH 15/17] Fix admin bar tweaks not working anymore --- src/class-admin-bar-tweaks.php | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index b758dcc..fef3c31 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -18,7 +18,7 @@ class Admin_Bar_Tweaks { * Initialize this class. */ public function init() { - add_action( 'init', array( $this, 'enhance_network_blog_admin_bar' ) ); + add_action( 'admin_bar_menu', array( $this, 'enhance_network_blog_admin_bar' ), 500 ); } /** @@ -26,13 +26,12 @@ public function init() { * * Add new 'Manage Comment' Item with count of comments, there wait for moderate * + * @param \WP_Admin_Bar $wp_admin_bar The admin bar object. + * * @since 0.0.1 */ - public function enhance_network_blog_admin_bar() { - /** - * The Toolbar API class. - */ - global $wp_admin_bar; + public function enhance_network_blog_admin_bar( \WP_Admin_Bar $wp_admin_bar ) { + if ( ! isset( $wp_admin_bar->user->blogs ) || ! Settings::is_feature_enabled( 'add-manage-comments' ) ) { return; } From bf2326f10db890ed3427272a735d6e25cbef20ec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Mon, 10 Jun 2024 13:02:28 +0200 Subject: [PATCH 16/17] Updating admin bar instead of removing and adding --- src/class-admin-bar-tweaks.php | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index fef3c31..043d027 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -39,20 +39,19 @@ public function enhance_network_blog_admin_bar( \WP_Admin_Bar $wp_admin_bar ) { foreach ( (array) $wp_admin_bar->user->blogs as $blog ) { switch_to_blog( $blog->userblog_id ); - $menu_id = 'blog-' . $blog->userblog_id; + $menu_id = 'blog-' . $blog->userblog_id . '-c'; if ( current_user_can( 'edit_posts' ) ) { - $wp_admin_bar->remove_node( $menu_id . '-c' ); + $comment_node = $wp_admin_bar->get_node( $menu_id ); $awaiting_mod = wp_count_comments(); $awaiting_mod = $awaiting_mod->moderated; // phpcs:ignore WordPress.WP.I18n.MissingArgDomain - $title = esc_html__( 'Manage Comments' ) - . '' . number_format_i18n( $awaiting_mod ) . ''; - $awaiting_title = esc_attr( + $comment_node->meta['title'] = esc_attr( sprintf( // phpcs:ignore WordPress.WP.I18n.MissingTranslatorsComment, WordPress.WP.I18n.MissingArgDomain _n( @@ -64,15 +63,7 @@ public function enhance_network_blog_admin_bar( \WP_Admin_Bar $wp_admin_bar ) { ) ); - $wp_admin_bar->add_menu( - array( - 'parent' => $menu_id, - 'id' => $menu_id . '-comments', - 'title' => $title, - 'href' => admin_url( 'edit-comments.php' ), - 'meta' => array( 'title' => $awaiting_title ), - ) - ); + $wp_admin_bar->add_node( (array) $comment_node ); } restore_current_blog(); From 9063da7b1fd0a3c691f99953d5a7484d6fed9993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20H=C3=BCsken?= Date: Mon, 10 Jun 2024 13:04:28 +0200 Subject: [PATCH 17/17] Updating admin bar instead of removing and adding --- src/class-admin-bar-tweaks.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/class-admin-bar-tweaks.php b/src/class-admin-bar-tweaks.php index 043d027..0027727 100755 --- a/src/class-admin-bar-tweaks.php +++ b/src/class-admin-bar-tweaks.php @@ -43,6 +43,9 @@ public function enhance_network_blog_admin_bar( \WP_Admin_Bar $wp_admin_bar ) { if ( current_user_can( 'edit_posts' ) ) { $comment_node = $wp_admin_bar->get_node( $menu_id ); + if ( ! $comment_node ) { + continue; + } $awaiting_mod = wp_count_comments(); $awaiting_mod = $awaiting_mod->moderated;