diff --git a/.gitignore b/.gitignore index aadd5c9..8ff21e5 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ vendor/bin vendor/dealerdirect vendor/squizlabs vendor/wp-coding-standards +vendor diff --git a/CHANGES.md b/CHANGES.md index 38cf218..e950691 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,5 +1,10 @@ [unreleased] +#### 1.8.0 / 2023-04-07 +* update to work natively with `|` format in `Requires Plugins` header +* split PD and PDv2 into different classes +* add more tests + #### 1.7.9 / 2023-04-05 * update action link to keep `Cannot Activate | Manage Dependencies` together * fix for multisite plugin card diff --git a/README.md b/README.md index 880ff9a..fef3771 100644 --- a/README.md +++ b/README.md @@ -16,6 +16,7 @@ Parses a 'Requires Plugins' header and adds a Dependencies tab in the plugin ins My solution to [#22316](https://core.trac.wordpress.org/ticket/22316). Feature plugin version of [PR #3032](https://github.com/WordPress/wordpress-develop/pull/3032) * Parses the **Requires Plugins** header that defines plugin dependencies using a comma separated list of wp.org slugs. +* Plugins not in dot org may use the format `|` in the **Requires Plugins** header. `URI` should return a JSON compatible with the `plugins_api()` response. * Displays a single admin notice with link to **Plugins > Add New > Dependencies** if not all plugin dependencies have been installed. * Adds a new view/tab to plugins install page ( **Plugins > Add New** ) titled **Dependencies** that contains plugin cards for all plugin dependencies. * This view also lists which plugins require which plugin dependencies in the plugin card, though that feature requires the filter below to function. 😅 diff --git a/composer.json b/composer.json index 8db6373..f7b1676 100644 --- a/composer.json +++ b/composer.json @@ -17,8 +17,7 @@ }, "prefer-stable": true, "require": { - "php": ">=5.6", - "afragen/add-plugin-dependency-api": "^0" + "php": ">=5.6" }, "require-dev": { "dealerdirect/phpcodesniffer-composer-installer": "^0.7.0", diff --git a/composer.lock b/composer.lock index 51f7db3..c83cfdb 100644 --- a/composer.lock +++ b/composer.lock @@ -4,57 +4,8 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "1f7d49ad879858c2b055a48c2ffc5ca2", - "packages": [ - { - "name": "afragen/add-plugin-dependency-api", - "version": "0.4.8", - "source": { - "type": "git", - "url": "https://github.com/afragen/add-plugin-dependency-api.git", - "reference": "f88b8161528e7893a9de305077a52403a4c37e4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/afragen/add-plugin-dependency-api/zipball/f88b8161528e7893a9de305077a52403a4c37e4d", - "reference": "f88b8161528e7893a9de305077a52403a4c37e4d", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "type": "library", - "autoload": { - "files": [ - "add-plugin-dependency-api.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andy Fragen", - "email": "andy@thefragens.com", - "homepage": "https://thefragens.com", - "role": "Developer" - } - ], - "description": "Library that helps WordPress plugin dependency management.", - "support": { - "issues": "https://github.com/afragen/add-plugin-dependency-api/issues", - "source": "https://github.com/afragen/add-plugin-dependency-api" - }, - "funding": [ - { - "url": "https://github.com/afragen", - "type": "github" - } - ], - "time": "2023-03-18T20:03:48+00:00" - } - ], + "content-hash": "e3d0e86b6c57880e64432f5d09feba4b", + "packages": [], "packages-dev": [ { "name": "dealerdirect/phpcodesniffer-composer-installer", diff --git a/plugin.php b/plugin.php index 121a3c0..73809fe 100644 --- a/plugin.php +++ b/plugin.php @@ -13,7 +13,7 @@ * Plugin URI: https://wordpress.org/plugins/wp-plugin-dependencies * Description: Parses 'Requires Plugins' header, add plugin install dependencies tab, and information about dependencies. * Author: Andy Fragen, Colin Stewart - * Version: 1.7.9 + * Version: 1.8.0 * License: MIT * Network: true * Requires at least: 6.0 @@ -32,34 +32,25 @@ die; } -// Deactivate plugin when committed to core. +// TODO: update with correct version. if ( version_compare( get_bloginfo( 'version' ), '6.3-alpha-99999', '>=' ) ) { - deactivate_plugins( __FILE__ ); + define( 'WP_PLUGIN_DEPENDENCIES1_COMMITTED', true ); +} else { + define( 'WP_PLUGIN_DEPENDENCIES1_COMMITTED', false ); } -// Load the Composer autoloader. -if ( file_exists( __DIR__ . '/vendor/autoload.php' ) ) { - require __DIR__ . '/vendor/autoload.php'; +// TODO: update with correct version. +if ( version_compare( get_bloginfo( 'version' ), '6.3-beta-1', '>=' ) ) { + define( 'WP_PLUGIN_DEPENDENCIES2_COMMITTED', true ); } else { - deactivate_plugins( __FILE__ ); - - wp_die( - wp_kses_post( - __( 'Plugin Dependencies is missing required composer dependencies.', 'wp-plugin-dependencies' ) - ) - ); + define( 'WP_PLUGIN_DEPENDENCIES2_COMMITTED', false ); } -// Add the sites with REST endpoints that return plugins_api() data when passed `slug` query arg. -add_filter( - 'plugin_dependency_endpoints', - function () { - return array( - 'https://git-updater.com/wp-json/git-updater/v1/plugins-api/', - 'https://pub.thefragens.com/gravityforms.json', - ); - } -); +// Deactivate plugin when committed to core. +if ( WP_PLUGIN_DEPENDENCIES2_COMMITTED ) { + require_once ABSPATH . 'wp-admin/includes/plugin.php'; + deactivate_plugins( __FILE__ ); +} /** * Class Init @@ -72,22 +63,26 @@ class Init { * @return void */ public function __construct() { - require_once __DIR__ . '/wp-admin/includes/class-wp-plugin-dependencies.php'; - - add_filter( 'install_plugins_tabs', array( $this, 'add_install_tab' ), 10, 1 ); - add_filter( 'install_plugins_table_api_args_dependencies', array( $this, 'add_install_dependency_args' ), 10, 1 ); - - add_action( 'install_plugins_dependencies', 'display_plugins_table' ); - add_action( - 'install_plugins_table_header', - function() { - // phpcs:ignore WordPress.Security.NonceVerification.Recommended - $tab = isset( $_GET['tab'] ) ? sanitize_title_with_dashes( wp_unslash( $_GET['tab'] ) ) : ''; - if ( 'dependencies' === $tab ) { - echo '

' . esc_html__( 'These suggestions are based on dependencies required by installed plugins.' ) . '

'; + if ( ! WP_PLUGIN_DEPENDENCIES1_COMMITTED ) { + require_once __DIR__ . '/wp-admin/includes/class-wp-plugin-dependencies.php'; + + add_filter( 'install_plugins_tabs', array( $this, 'add_install_tab' ), 10, 1 ); + add_filter( 'install_plugins_table_api_args_dependencies', array( $this, 'add_install_dependency_args' ), 10, 1 ); + + add_action( 'install_plugins_dependencies', 'display_plugins_table' ); + add_action( + 'install_plugins_table_header', + function() { + // phpcs:ignore WordPress.Security.NonceVerification.Recommended + $tab = isset( $_GET['tab'] ) ? sanitize_title_with_dashes( wp_unslash( $_GET['tab'] ) ) : ''; + if ( 'dependencies' === $tab ) { + echo '

' . esc_html__( 'These suggestions are based on dependencies required by installed plugins.' ) . '

'; + } } - } - ); + ); + } + + require_once __DIR__ . '/wp-admin/includes/class-wp-plugin-dependencies-2.php'; } /** diff --git a/readme.txt b/readme.txt index b6c8345..d9133b7 100644 --- a/readme.txt +++ b/readme.txt @@ -7,7 +7,7 @@ Network: true Requires at least: 6.0 Requires PHP: 5.6 Tested up to: 6.2 -Stable tag: 1.7.9 +Stable tag: 1.8.0 ## Description @@ -20,7 +20,7 @@ Please open issues at [WordPress/wp-plugin-dependencies issues](https://github.c My solution to [#22316](https://core.trac.wordpress.org/ticket/22316). Feature plugin version of [PR #3032](https://github.com/WordPress/wordpress-develop/pull/3032) * Parses the **Requires Plugins** header that defines plugin dependencies using a comma separated list of wp.org slugs. To test, you will need to add the header and content to a plugin. -* Adds a new view/tab to plugins install page ( **Plugins > Add New** ) titled **Dependencies** that contains plugin cards for all plugin dependencies. +* Plugins not in dot org may use the format `|` in the **Requires Plugins** header. `URI` should return a JSON compatible with the `plugins_api()` response.* Adds a new view/tab to plugins install page ( **Plugins > Add New** ) titled **Dependencies** that contains plugin cards for all plugin dependencies. * This view also lists which plugins require which plugin dependencies in the plugin card. 😅 * In the plugins page, a dependent plugin is unable to be deleted or deactivated if the requiring plugin is active. * Plugin dependencies can be deactivated or deleted if the requiring plugin is not active. @@ -45,6 +45,11 @@ PRs should be made against the `develop` branch. ## Changelog +#### 1.8.0 / 2023-04-07 +* update to work natively with `|` format in `Requires Plugins` header +* split PD and PDv2 into different classes +* add more tests + #### 1.7.9 / 2023-04-05 * update action link to keep `Cannot Activate | Manage Dependencies` together * fix for multisite plugin card diff --git a/test-plugins/test-dependencies1.php b/test-plugins/test-dependencies1.php index 949fe04..cd82d0e 100644 --- a/test-plugins/test-dependencies1.php +++ b/test-plugins/test-dependencies1.php @@ -8,5 +8,5 @@ * Author: WordPress Core Contributors * Version: 0.1 * Description: Testing inclusion of dot org plugins in the Dependencies tab. - * Requires Plugins: wp-plugin-dependencies + * Requires Plugins: hello-dolly */ diff --git a/test-plugins/test-dependencies2.php b/test-plugins/test-dependencies2.php index a32cc8b..71233c9 100644 --- a/test-plugins/test-dependencies2.php +++ b/test-plugins/test-dependencies2.php @@ -8,5 +8,5 @@ * Author: WordPress Core Contributors * Version: 0.1 * Description: Testing inclusion of non-dot org plugins in the Dependencies tab. - * Requires Plugins: gravityforms, git-updater + * Requires Plugins: gravityforms|https://pub.thefragens.com/gravityforms.json, git-updater|https://git-updater.com/wp-json/git-updater/v1/plugins-api/?slug=git-updater */ diff --git a/test-plugins/test-dependencies3.php b/test-plugins/test-dependencies3.php index 14748b8..444688c 100644 --- a/test-plugins/test-dependencies3.php +++ b/test-plugins/test-dependencies3.php @@ -8,5 +8,5 @@ * Author: WordPress Core Contributors * Version: 0.1 * Description: Testing inclusion of dot org plugins in the Dependencies tab. - * Requires Plugins: gutenberg, wp-plugin-dependencies, akismet + * Requires Plugins: gutenberg, akismet */ diff --git a/tests/phpunit/tests/admin/wpPluginDependencies.php b/tests/phpunit/tests/admin/wpPluginDependencies.php index 436d35e..5b29042 100644 --- a/tests/phpunit/tests/admin/wpPluginDependencies.php +++ b/tests/phpunit/tests/admin/wpPluginDependencies.php @@ -363,7 +363,7 @@ public function data_slug_sanitization() { ), 'a dependency with an underscore' => array( 'requires_plugins' => 'hello_dolly', - 'expected' => array(), + 'expected' => array( 'hello_dolly' ), ), 'a dependency with a space' => array( 'requires_plugins' => 'hello dolly', @@ -391,7 +391,7 @@ public function data_slug_sanitization() { ), 'symbol dependencies' => array( 'requires_plugins' => '★-wpsymbols-★', - 'expected' => array( '★-wpsymbols-★' ), + 'expected' => array(), ), ); } @@ -544,4 +544,72 @@ public function test_get_dependency_filepaths_with_unmatched_dirnames_and_dirnam $this->assertSame( $expected, $get_filepaths->invoke( $dependencies ) ); } + + /** + * Tests that dependency filepaths are retrieved correctly. + * + * @covers WP_Plugin_Dependencies_2::split_slug + * + * @dataProvider data_split_slug + * + * @param string $slug A slug string. + * @param array $expected A string of expected slug results. + */ + public function test_split_slug( $slug, $expected ) { + $dependencies2 = new WP_Plugin_Dependencies_2(); + $split_slug = $this->make_method_accessible( $dependencies2, 'split_slug' ); + + $actual = $split_slug->invoke( $dependencies2, trim( $slug ) ); + $this->assertSame( $expected, $actual ); + } + + /** + * Data provider for test_split_slug(). + * + * @return array + */ + public function data_split_slug() { + return array( + 'no_spaces_pipe_at_end' => array( + 'slug' => 'slug|', + 'expected' => 'slug|', + ), + 'no_spaces_pipe_at_front' => array( + 'slug' => '|endpoint', + 'expected' => '|endpoint', + ), + 'double_pipe_in_middle' => array( + 'slug' => 'slug||endpoint', + 'expected' => 'slug||endpoint', + ), + 'pipes_front_middle_end' => array( + 'slug' => '|slug||endpoint|', + 'expected' => '|slug||endpoint|', + ), + 'single_pipe_in_middle' => array( + 'slug' => 'slug|endpoint', + 'expected' => 'slug', + ), + 'single_pipe_in_middle_pipe_at_end' => array( + 'slug' => 'slug|endpoint|', + 'expected' => 'slug|endpoint|', + ), + 'spaces_and_pipe_in_middle' => array( + 'slug' => 'slug |endpoint', + 'expected' => 'slug', + ), + 'pipe_and_spaces_in_middle' => array( + 'slug' => 'slug| endpoint', + 'expected' => 'slug', + ), + 'pipe_in_middle_pipe_spaces_at_end' => array( + 'slug' => 'slug|endpoint| ', + 'expected' => 'slug|endpoint|', + ), + 'spaces_pipe_at_front_pipe_in_middle' => array( + 'slug' => ' |slug|endpoint', + 'expected' => '|slug|endpoint', + ), + ); + } } diff --git a/vendor/afragen/add-plugin-dependency-api/LICENSE b/vendor/afragen/add-plugin-dependency-api/LICENSE deleted file mode 100644 index 62b149a..0000000 --- a/vendor/afragen/add-plugin-dependency-api/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ -MIT License - -Copyright (c) 2022 Andy Fragen - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. diff --git a/vendor/afragen/add-plugin-dependency-api/README.md b/vendor/afragen/add-plugin-dependency-api/README.md deleted file mode 100644 index a0593c8..0000000 --- a/vendor/afragen/add-plugin-dependency-api/README.md +++ /dev/null @@ -1,46 +0,0 @@ -# Add Plugin Dependency API - -* Contributors: [Andy Fragen](https://github.com/afragen), [contributors](https://github.com/afragen/add-plugin-dependency-api/graphs/contributors) -* Tags: plugin dependency -* Requires at least: 6.0 -* Requires PHP: 5.6 -* Stable tag: main -* Donate link: -* License: MIT - -Composer library for adding a plugin dependency response based upon use with Git Updater v12 or greater. - -## Description - -This is an example to developers of non dot-org plugins that wish to take advantage of the Plugin Dependencies feature from the `Requires Plugins` header. - -You can use **composer** to install this package within your WordPress plugin / theme. - -**Please ensure you are using the latest version of this framework in your `composer.json`** - -1. Within your plugin or theme root folder, run the following command: - -```shell -composer require afragen/add-plugin-dependency-api -``` - -2. Add a filter to your plugin that requires a dependency that returns an array or JSON response containing a REST endpoint that returns a valid `plugins_api()` response. - -A query arg of the plugin slug, `?slug=my-plugin-dependency`, will be passed to the endpoint returned from the filter. The slug originates from the `Require Plugins` header. - -```php -// Add the sites with REST enpoints that return plugins_api() data when passed `slug` query arg. -// You can also return URL to a JSON file containing the appropriate data. -add_filter( - 'plugin_dependency_endpoints', - function () { - return [ 'https://git-updater.com/wp-json/git-updater/v1/plugins-api/' ]; - } -); -``` - -To see an example REST endpoint return view in the browser. - -## Development - -PRs are welcome against the `develop` branch. diff --git a/vendor/afragen/add-plugin-dependency-api/add-plugin-dependency-api.php b/vendor/afragen/add-plugin-dependency-api/add-plugin-dependency-api.php deleted file mode 100644 index 7e70822..0000000 --- a/vendor/afragen/add-plugin-dependency-api/add-plugin-dependency-api.php +++ /dev/null @@ -1,129 +0,0 @@ -slug ) - ) { - continue; - } - - $url = add_query_arg( 'slug', $args->slug, untrailingslashit( $endpoint ) ); - $response = wp_remote_get( $url ); - - // Convert response to associative array. - $response = json_decode( wp_remote_retrieve_body( $response ), true ); - if ( null === $response || isset( $response['error'] ) || isset( $response['code'] ) ) { - $message = isset( $response['error'] ) ? $response['error'] : ''; - $response = new WP_Error( 'error', 'Error retrieving plugin data.', $message ); - } - if ( ! is_wp_error( $response ) ) { - break; - } - } - - // Add slug to hook_extra. - add_filter( - 'upgrader_package_options', - function ( $options ) use ( $args ) { - $options['hook_extra']['slug'] = $args->slug; - - return $options; - }, - 10, - 1 - ); - } - - return (object) $response; - } - - /** - * Filter `upgrader_post_install` for plugin dependencies. - * - * For correct renaming of downloaded plugin directory, - * some downloads may not be formatted correctly. - * - * @param bool $true Default is true. - * @param array $hook_extra Array of data from hook. - * @param array $result Array of data for installation. - * - * @return bool - */ - public function upgrader_post_install( $true, $hook_extra, $result ) { - global $wp_filesystem; - - if ( ! isset( $hook_extra['slug'] ) ) { - return $true; - } - - $from = untrailingslashit( $result['destination'] ); - $to = trailingslashit( $result['local_destination'] ) . $hook_extra['slug']; - - if ( trailingslashit( strtolower( $from ) ) !== trailingslashit( strtolower( $to ) ) ) { - if ( function_exists( 'move_dir' ) ) { - $true = move_dir( $from, $to, true ); - } elseif ( ! rename( $from, $to ) ) { - $wp_filesystem->mkdir( $to ); - $true = copy_dir( $from, $to, [ basename( $to ) ] ); - $wp_filesystem->delete( $from, true ); - } - } - - return $true; - } - } -} - -( new Plugin_Dependency_API() )->load_hooks(); diff --git a/vendor/afragen/add-plugin-dependency-api/composer.json b/vendor/afragen/add-plugin-dependency-api/composer.json deleted file mode 100644 index dda0a9a..0000000 --- a/vendor/afragen/add-plugin-dependency-api/composer.json +++ /dev/null @@ -1,28 +0,0 @@ -{ - "name": "afragen/add-plugin-dependency-api", - "description": "Library that helps WordPress plugin dependency management.", - "version": "0.4.8", - "type": "library", - "license": "MIT", - "authors": [ - { - "name": "Andy Fragen", - "email": "andy@thefragens.com", - "homepage": "https://thefragens.com", - "role": "Developer" - } - ], - "prefer-stable": true, - "require": { - "php": ">=5.6" - }, - "support": { - "issues": "https://github.com/afragen/add-plugin-dependency-api/issues", - "source": "https://github.com/afragen/add-plugin-dependency-api" - }, - "autoload": { - "files": [ - "add-plugin-dependency-api.php" - ] - } -} diff --git a/vendor/autoload.php b/vendor/autoload.php deleted file mode 100644 index d38337f..0000000 --- a/vendor/autoload.php +++ /dev/null @@ -1,25 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer\Autoload; - -/** - * ClassLoader implements a PSR-0, PSR-4 and classmap class loader. - * - * $loader = new \Composer\Autoload\ClassLoader(); - * - * // register classes with namespaces - * $loader->add('Symfony\Component', __DIR__.'/component'); - * $loader->add('Symfony', __DIR__.'/framework'); - * - * // activate the autoloader - * $loader->register(); - * - * // to enable searching the include path (eg. for PEAR packages) - * $loader->setUseIncludePath(true); - * - * In this example, if you try to use a class in the Symfony\Component - * namespace or one of its children (Symfony\Component\Console for instance), - * the autoloader will first look for the class under the component/ - * directory, and it will then fallback to the framework/ directory if not - * found before giving up. - * - * This class is loosely based on the Symfony UniversalClassLoader. - * - * @author Fabien Potencier - * @author Jordi Boggiano - * @see https://www.php-fig.org/psr/psr-0/ - * @see https://www.php-fig.org/psr/psr-4/ - */ -class ClassLoader -{ - /** @var \Closure(string):void */ - private static $includeFile; - - /** @var ?string */ - private $vendorDir; - - // PSR-4 - /** - * @var array[] - * @psalm-var array> - */ - private $prefixLengthsPsr4 = array(); - /** - * @var array[] - * @psalm-var array> - */ - private $prefixDirsPsr4 = array(); - /** - * @var array[] - * @psalm-var array - */ - private $fallbackDirsPsr4 = array(); - - // PSR-0 - /** - * @var array[] - * @psalm-var array> - */ - private $prefixesPsr0 = array(); - /** - * @var array[] - * @psalm-var array - */ - private $fallbackDirsPsr0 = array(); - - /** @var bool */ - private $useIncludePath = false; - - /** - * @var string[] - * @psalm-var array - */ - private $classMap = array(); - - /** @var bool */ - private $classMapAuthoritative = false; - - /** - * @var bool[] - * @psalm-var array - */ - private $missingClasses = array(); - - /** @var ?string */ - private $apcuPrefix; - - /** - * @var self[] - */ - private static $registeredLoaders = array(); - - /** - * @param ?string $vendorDir - */ - public function __construct($vendorDir = null) - { - $this->vendorDir = $vendorDir; - self::initializeIncludeClosure(); - } - - /** - * @return string[] - */ - public function getPrefixes() - { - if (!empty($this->prefixesPsr0)) { - return call_user_func_array('array_merge', array_values($this->prefixesPsr0)); - } - - return array(); - } - - /** - * @return array[] - * @psalm-return array> - */ - public function getPrefixesPsr4() - { - return $this->prefixDirsPsr4; - } - - /** - * @return array[] - * @psalm-return array - */ - public function getFallbackDirs() - { - return $this->fallbackDirsPsr0; - } - - /** - * @return array[] - * @psalm-return array - */ - public function getFallbackDirsPsr4() - { - return $this->fallbackDirsPsr4; - } - - /** - * @return string[] Array of classname => path - * @psalm-return array - */ - public function getClassMap() - { - return $this->classMap; - } - - /** - * @param string[] $classMap Class to filename map - * @psalm-param array $classMap - * - * @return void - */ - public function addClassMap(array $classMap) - { - if ($this->classMap) { - $this->classMap = array_merge($this->classMap, $classMap); - } else { - $this->classMap = $classMap; - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, either - * appending or prepending to the ones previously set for this prefix. - * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 root directories - * @param bool $prepend Whether to prepend the directories - * - * @return void - */ - public function add($prefix, $paths, $prepend = false) - { - if (!$prefix) { - if ($prepend) { - $this->fallbackDirsPsr0 = array_merge( - (array) $paths, - $this->fallbackDirsPsr0 - ); - } else { - $this->fallbackDirsPsr0 = array_merge( - $this->fallbackDirsPsr0, - (array) $paths - ); - } - - return; - } - - $first = $prefix[0]; - if (!isset($this->prefixesPsr0[$first][$prefix])) { - $this->prefixesPsr0[$first][$prefix] = (array) $paths; - - return; - } - if ($prepend) { - $this->prefixesPsr0[$first][$prefix] = array_merge( - (array) $paths, - $this->prefixesPsr0[$first][$prefix] - ); - } else { - $this->prefixesPsr0[$first][$prefix] = array_merge( - $this->prefixesPsr0[$first][$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, either - * appending or prepending to the ones previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories - * @param bool $prepend Whether to prepend the directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function addPsr4($prefix, $paths, $prepend = false) - { - if (!$prefix) { - // Register directories for the root namespace. - if ($prepend) { - $this->fallbackDirsPsr4 = array_merge( - (array) $paths, - $this->fallbackDirsPsr4 - ); - } else { - $this->fallbackDirsPsr4 = array_merge( - $this->fallbackDirsPsr4, - (array) $paths - ); - } - } elseif (!isset($this->prefixDirsPsr4[$prefix])) { - // Register directories for a new namespace. - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } elseif ($prepend) { - // Prepend directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - (array) $paths, - $this->prefixDirsPsr4[$prefix] - ); - } else { - // Append directories for an already registered namespace. - $this->prefixDirsPsr4[$prefix] = array_merge( - $this->prefixDirsPsr4[$prefix], - (array) $paths - ); - } - } - - /** - * Registers a set of PSR-0 directories for a given prefix, - * replacing any others previously set for this prefix. - * - * @param string $prefix The prefix - * @param string[]|string $paths The PSR-0 base directories - * - * @return void - */ - public function set($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr0 = (array) $paths; - } else { - $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths; - } - } - - /** - * Registers a set of PSR-4 directories for a given namespace, - * replacing any others previously set for this namespace. - * - * @param string $prefix The prefix/namespace, with trailing '\\' - * @param string[]|string $paths The PSR-4 base directories - * - * @throws \InvalidArgumentException - * - * @return void - */ - public function setPsr4($prefix, $paths) - { - if (!$prefix) { - $this->fallbackDirsPsr4 = (array) $paths; - } else { - $length = strlen($prefix); - if ('\\' !== $prefix[$length - 1]) { - throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator."); - } - $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length; - $this->prefixDirsPsr4[$prefix] = (array) $paths; - } - } - - /** - * Turns on searching the include path for class files. - * - * @param bool $useIncludePath - * - * @return void - */ - public function setUseIncludePath($useIncludePath) - { - $this->useIncludePath = $useIncludePath; - } - - /** - * Can be used to check if the autoloader uses the include path to check - * for classes. - * - * @return bool - */ - public function getUseIncludePath() - { - return $this->useIncludePath; - } - - /** - * Turns off searching the prefix and fallback directories for classes - * that have not been registered with the class map. - * - * @param bool $classMapAuthoritative - * - * @return void - */ - public function setClassMapAuthoritative($classMapAuthoritative) - { - $this->classMapAuthoritative = $classMapAuthoritative; - } - - /** - * Should class lookup fail if not found in the current class map? - * - * @return bool - */ - public function isClassMapAuthoritative() - { - return $this->classMapAuthoritative; - } - - /** - * APCu prefix to use to cache found/not-found classes, if the extension is enabled. - * - * @param string|null $apcuPrefix - * - * @return void - */ - public function setApcuPrefix($apcuPrefix) - { - $this->apcuPrefix = function_exists('apcu_fetch') && filter_var(ini_get('apc.enabled'), FILTER_VALIDATE_BOOLEAN) ? $apcuPrefix : null; - } - - /** - * The APCu prefix in use, or null if APCu caching is not enabled. - * - * @return string|null - */ - public function getApcuPrefix() - { - return $this->apcuPrefix; - } - - /** - * Registers this instance as an autoloader. - * - * @param bool $prepend Whether to prepend the autoloader or not - * - * @return void - */ - public function register($prepend = false) - { - spl_autoload_register(array($this, 'loadClass'), true, $prepend); - - if (null === $this->vendorDir) { - return; - } - - if ($prepend) { - self::$registeredLoaders = array($this->vendorDir => $this) + self::$registeredLoaders; - } else { - unset(self::$registeredLoaders[$this->vendorDir]); - self::$registeredLoaders[$this->vendorDir] = $this; - } - } - - /** - * Unregisters this instance as an autoloader. - * - * @return void - */ - public function unregister() - { - spl_autoload_unregister(array($this, 'loadClass')); - - if (null !== $this->vendorDir) { - unset(self::$registeredLoaders[$this->vendorDir]); - } - } - - /** - * Loads the given class or interface. - * - * @param string $class The name of the class - * @return true|null True if loaded, null otherwise - */ - public function loadClass($class) - { - if ($file = $this->findFile($class)) { - $includeFile = self::$includeFile; - $includeFile($file); - - return true; - } - - return null; - } - - /** - * Finds the path to the file where the class is defined. - * - * @param string $class The name of the class - * - * @return string|false The path if found, false otherwise - */ - public function findFile($class) - { - // class map lookup - if (isset($this->classMap[$class])) { - return $this->classMap[$class]; - } - if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) { - return false; - } - if (null !== $this->apcuPrefix) { - $file = apcu_fetch($this->apcuPrefix.$class, $hit); - if ($hit) { - return $file; - } - } - - $file = $this->findFileWithExtension($class, '.php'); - - // Search for Hack files if we are running on HHVM - if (false === $file && defined('HHVM_VERSION')) { - $file = $this->findFileWithExtension($class, '.hh'); - } - - if (null !== $this->apcuPrefix) { - apcu_add($this->apcuPrefix.$class, $file); - } - - if (false === $file) { - // Remember that this class does not exist. - $this->missingClasses[$class] = true; - } - - return $file; - } - - /** - * Returns the currently registered loaders indexed by their corresponding vendor directories. - * - * @return self[] - */ - public static function getRegisteredLoaders() - { - return self::$registeredLoaders; - } - - /** - * @param string $class - * @param string $ext - * @return string|false - */ - private function findFileWithExtension($class, $ext) - { - // PSR-4 lookup - $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext; - - $first = $class[0]; - if (isset($this->prefixLengthsPsr4[$first])) { - $subPath = $class; - while (false !== $lastPos = strrpos($subPath, '\\')) { - $subPath = substr($subPath, 0, $lastPos); - $search = $subPath . '\\'; - if (isset($this->prefixDirsPsr4[$search])) { - $pathEnd = DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $lastPos + 1); - foreach ($this->prefixDirsPsr4[$search] as $dir) { - if (file_exists($file = $dir . $pathEnd)) { - return $file; - } - } - } - } - } - - // PSR-4 fallback dirs - foreach ($this->fallbackDirsPsr4 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) { - return $file; - } - } - - // PSR-0 lookup - if (false !== $pos = strrpos($class, '\\')) { - // namespaced class name - $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1) - . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR); - } else { - // PEAR-like class name - $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext; - } - - if (isset($this->prefixesPsr0[$first])) { - foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) { - if (0 === strpos($class, $prefix)) { - foreach ($dirs as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - } - } - } - - // PSR-0 fallback dirs - foreach ($this->fallbackDirsPsr0 as $dir) { - if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) { - return $file; - } - } - - // PSR-0 include paths. - if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) { - return $file; - } - - return false; - } - - /** - * @return void - */ - private static function initializeIncludeClosure() - { - if (self::$includeFile !== null) { - return; - } - - /** - * Scope isolated include. - * - * Prevents access to $this/self from included files. - * - * @param string $file - * @return void - */ - self::$includeFile = \Closure::bind(static function($file) { - include $file; - }, null, null); - } -} diff --git a/vendor/composer/InstalledVersions.php b/vendor/composer/InstalledVersions.php deleted file mode 100644 index 51e734a..0000000 --- a/vendor/composer/InstalledVersions.php +++ /dev/null @@ -1,359 +0,0 @@ - - * Jordi Boggiano - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - -namespace Composer; - -use Composer\Autoload\ClassLoader; -use Composer\Semver\VersionParser; - -/** - * This class is copied in every Composer installed project and available to all - * - * See also https://getcomposer.org/doc/07-runtime.md#installed-versions - * - * To require its presence, you can require `composer-runtime-api ^2.0` - * - * @final - */ -class InstalledVersions -{ - /** - * @var mixed[]|null - * @psalm-var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array}|array{}|null - */ - private static $installed; - - /** - * @var bool|null - */ - private static $canGetVendors; - - /** - * @var array[] - * @psalm-var array}> - */ - private static $installedByVendor = array(); - - /** - * Returns a list of all package names which are present, either by being installed, replaced or provided - * - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackages() - { - $packages = array(); - foreach (self::getInstalled() as $installed) { - $packages[] = array_keys($installed['versions']); - } - - if (1 === \count($packages)) { - return $packages[0]; - } - - return array_keys(array_flip(\call_user_func_array('array_merge', $packages))); - } - - /** - * Returns a list of all package names with a specific type e.g. 'library' - * - * @param string $type - * @return string[] - * @psalm-return list - */ - public static function getInstalledPackagesByType($type) - { - $packagesByType = array(); - - foreach (self::getInstalled() as $installed) { - foreach ($installed['versions'] as $name => $package) { - if (isset($package['type']) && $package['type'] === $type) { - $packagesByType[] = $name; - } - } - } - - return $packagesByType; - } - - /** - * Checks whether the given package is installed - * - * This also returns true if the package name is provided or replaced by another package - * - * @param string $packageName - * @param bool $includeDevRequirements - * @return bool - */ - public static function isInstalled($packageName, $includeDevRequirements = true) - { - foreach (self::getInstalled() as $installed) { - if (isset($installed['versions'][$packageName])) { - return $includeDevRequirements || !isset($installed['versions'][$packageName]['dev_requirement']) || $installed['versions'][$packageName]['dev_requirement'] === false; - } - } - - return false; - } - - /** - * Checks whether the given package satisfies a version constraint - * - * e.g. If you want to know whether version 2.3+ of package foo/bar is installed, you would call: - * - * Composer\InstalledVersions::satisfies(new VersionParser, 'foo/bar', '^2.3') - * - * @param VersionParser $parser Install composer/semver to have access to this class and functionality - * @param string $packageName - * @param string|null $constraint A version constraint to check for, if you pass one you have to make sure composer/semver is required by your package - * @return bool - */ - public static function satisfies(VersionParser $parser, $packageName, $constraint) - { - $constraint = $parser->parseConstraints((string) $constraint); - $provided = $parser->parseConstraints(self::getVersionRanges($packageName)); - - return $provided->matches($constraint); - } - - /** - * Returns a version constraint representing all the range(s) which are installed for a given package - * - * It is easier to use this via isInstalled() with the $constraint argument if you need to check - * whether a given version of a package is installed, and not just whether it exists - * - * @param string $packageName - * @return string Version constraint usable with composer/semver - */ - public static function getVersionRanges($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - $ranges = array(); - if (isset($installed['versions'][$packageName]['pretty_version'])) { - $ranges[] = $installed['versions'][$packageName]['pretty_version']; - } - if (array_key_exists('aliases', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['aliases']); - } - if (array_key_exists('replaced', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['replaced']); - } - if (array_key_exists('provided', $installed['versions'][$packageName])) { - $ranges = array_merge($ranges, $installed['versions'][$packageName]['provided']); - } - - return implode(' || ', $ranges); - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['version'])) { - return null; - } - - return $installed['versions'][$packageName]['version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as version, use satisfies or getVersionRanges if you need to know if a given version is present - */ - public static function getPrettyVersion($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['pretty_version'])) { - return null; - } - - return $installed['versions'][$packageName]['pretty_version']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as reference - */ - public static function getReference($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - if (!isset($installed['versions'][$packageName]['reference'])) { - return null; - } - - return $installed['versions'][$packageName]['reference']; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @param string $packageName - * @return string|null If the package is being replaced or provided but is not really installed, null will be returned as install path. Packages of type metapackages also have a null install path. - */ - public static function getInstallPath($packageName) - { - foreach (self::getInstalled() as $installed) { - if (!isset($installed['versions'][$packageName])) { - continue; - } - - return isset($installed['versions'][$packageName]['install_path']) ? $installed['versions'][$packageName]['install_path'] : null; - } - - throw new \OutOfBoundsException('Package "' . $packageName . '" is not installed'); - } - - /** - * @return array - * @psalm-return array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool} - */ - public static function getRootPackage() - { - $installed = self::getInstalled(); - - return $installed[0]['root']; - } - - /** - * Returns the raw installed.php data for custom implementations - * - * @deprecated Use getAllRawData() instead which returns all datasets for all autoloaders present in the process. getRawData only returns the first dataset loaded, which may not be what you expect. - * @return array[] - * @psalm-return array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} - */ - public static function getRawData() - { - @trigger_error('getRawData only returns the first dataset loaded, which may not be what you expect. Use getAllRawData() instead which returns all datasets for all autoloaders present in the process.', E_USER_DEPRECATED); - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - self::$installed = include __DIR__ . '/installed.php'; - } else { - self::$installed = array(); - } - } - - return self::$installed; - } - - /** - * Returns the raw data of all installed.php which are currently loaded for custom implementations - * - * @return array[] - * @psalm-return list}> - */ - public static function getAllRawData() - { - return self::getInstalled(); - } - - /** - * Lets you reload the static array from another file - * - * This is only useful for complex integrations in which a project needs to use - * this class but then also needs to execute another project's autoloader in process, - * and wants to ensure both projects have access to their version of installed.php. - * - * A typical case would be PHPUnit, where it would need to make sure it reads all - * the data it needs from this class, then call reload() with - * `require $CWD/vendor/composer/installed.php` (or similar) as input to make sure - * the project in which it runs can then also use this class safely, without - * interference between PHPUnit's dependencies and the project's dependencies. - * - * @param array[] $data A vendor/composer/installed.php data set - * @return void - * - * @psalm-param array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $data - */ - public static function reload($data) - { - self::$installed = $data; - self::$installedByVendor = array(); - } - - /** - * @return array[] - * @psalm-return list}> - */ - private static function getInstalled() - { - if (null === self::$canGetVendors) { - self::$canGetVendors = method_exists('Composer\Autoload\ClassLoader', 'getRegisteredLoaders'); - } - - $installed = array(); - - if (self::$canGetVendors) { - foreach (ClassLoader::getRegisteredLoaders() as $vendorDir => $loader) { - if (isset(self::$installedByVendor[$vendorDir])) { - $installed[] = self::$installedByVendor[$vendorDir]; - } elseif (is_file($vendorDir.'/composer/installed.php')) { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require $vendorDir.'/composer/installed.php'; - $installed[] = self::$installedByVendor[$vendorDir] = $required; - if (null === self::$installed && strtr($vendorDir.'/composer', '\\', '/') === strtr(__DIR__, '\\', '/')) { - self::$installed = $installed[count($installed) - 1]; - } - } - } - } - - if (null === self::$installed) { - // only require the installed.php file if this file is loaded from its dumped location, - // and not from its source location in the composer/composer package, see https://github.com/composer/composer/issues/9937 - if (substr(__DIR__, -8, 1) !== 'C') { - /** @var array{root: array{name: string, pretty_version: string, version: string, reference: string|null, type: string, install_path: string, aliases: string[], dev: bool}, versions: array} $required */ - $required = require __DIR__ . '/installed.php'; - self::$installed = $required; - } else { - self::$installed = array(); - } - } - - if (self::$installed !== array()) { - $installed[] = self::$installed; - } - - return $installed; - } -} diff --git a/vendor/composer/LICENSE b/vendor/composer/LICENSE deleted file mode 100644 index f27399a..0000000 --- a/vendor/composer/LICENSE +++ /dev/null @@ -1,21 +0,0 @@ - -Copyright (c) Nils Adermann, Jordi Boggiano - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is furnished -to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - diff --git a/vendor/composer/autoload_classmap.php b/vendor/composer/autoload_classmap.php deleted file mode 100644 index 0fb0a2c..0000000 --- a/vendor/composer/autoload_classmap.php +++ /dev/null @@ -1,10 +0,0 @@ - $vendorDir . '/composer/InstalledVersions.php', -); diff --git a/vendor/composer/autoload_files.php b/vendor/composer/autoload_files.php deleted file mode 100644 index fddc19b..0000000 --- a/vendor/composer/autoload_files.php +++ /dev/null @@ -1,10 +0,0 @@ - $vendorDir . '/afragen/add-plugin-dependency-api/add-plugin-dependency-api.php', -); diff --git a/vendor/composer/autoload_namespaces.php b/vendor/composer/autoload_namespaces.php deleted file mode 100644 index 15a2ff3..0000000 --- a/vendor/composer/autoload_namespaces.php +++ /dev/null @@ -1,9 +0,0 @@ - array($vendorDir . '/dealerdirect/phpcodesniffer-composer-installer/src'), -); diff --git a/vendor/composer/autoload_real.php b/vendor/composer/autoload_real.php deleted file mode 100644 index a2deb38..0000000 --- a/vendor/composer/autoload_real.php +++ /dev/null @@ -1,50 +0,0 @@ -register(true); - - $filesToLoad = \Composer\Autoload\ComposerStaticInit11e935e055e997f4ded389e93d4aaba5::$files; - $requireFile = \Closure::bind(static function ($fileIdentifier, $file) { - if (empty($GLOBALS['__composer_autoload_files'][$fileIdentifier])) { - $GLOBALS['__composer_autoload_files'][$fileIdentifier] = true; - - require $file; - } - }, null, null); - foreach ($filesToLoad as $fileIdentifier => $file) { - $requireFile($fileIdentifier, $file); - } - - return $loader; - } -} diff --git a/vendor/composer/autoload_static.php b/vendor/composer/autoload_static.php deleted file mode 100644 index a1d75e4..0000000 --- a/vendor/composer/autoload_static.php +++ /dev/null @@ -1,40 +0,0 @@ - __DIR__ . '/..' . '/afragen/add-plugin-dependency-api/add-plugin-dependency-api.php', - ); - - public static $prefixLengthsPsr4 = array ( - 'D' => - array ( - 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => 55, - ), - ); - - public static $prefixDirsPsr4 = array ( - 'Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\' => - array ( - 0 => __DIR__ . '/..' . '/dealerdirect/phpcodesniffer-composer-installer/src', - ), - ); - - public static $classMap = array ( - 'Composer\\InstalledVersions' => __DIR__ . '/..' . '/composer/InstalledVersions.php', - ); - - public static function getInitializer(ClassLoader $loader) - { - return \Closure::bind(function () use ($loader) { - $loader->prefixLengthsPsr4 = ComposerStaticInit11e935e055e997f4ded389e93d4aaba5::$prefixLengthsPsr4; - $loader->prefixDirsPsr4 = ComposerStaticInit11e935e055e997f4ded389e93d4aaba5::$prefixDirsPsr4; - $loader->classMap = ComposerStaticInit11e935e055e997f4ded389e93d4aaba5::$classMap; - - }, null, ClassLoader::class); - } -} diff --git a/vendor/composer/installed.json b/vendor/composer/installed.json deleted file mode 100644 index 701d0a7..0000000 --- a/vendor/composer/installed.json +++ /dev/null @@ -1,252 +0,0 @@ -{ - "packages": [ - { - "name": "afragen/add-plugin-dependency-api", - "version": "0.4.8", - "version_normalized": "0.4.8.0", - "source": { - "type": "git", - "url": "https://github.com/afragen/add-plugin-dependency-api.git", - "reference": "f88b8161528e7893a9de305077a52403a4c37e4d" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/afragen/add-plugin-dependency-api/zipball/f88b8161528e7893a9de305077a52403a4c37e4d", - "reference": "f88b8161528e7893a9de305077a52403a4c37e4d", - "shasum": "" - }, - "require": { - "php": ">=5.6" - }, - "time": "2023-03-18T20:03:48+00:00", - "type": "library", - "installation-source": "dist", - "autoload": { - "files": [ - "add-plugin-dependency-api.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Andy Fragen", - "email": "andy@thefragens.com", - "homepage": "https://thefragens.com", - "role": "Developer" - } - ], - "description": "Library that helps WordPress plugin dependency management.", - "support": { - "issues": "https://github.com/afragen/add-plugin-dependency-api/issues", - "source": "https://github.com/afragen/add-plugin-dependency-api" - }, - "funding": [ - { - "url": "https://github.com/afragen", - "type": "github" - } - ], - "install-path": "../afragen/add-plugin-dependency-api" - }, - { - "name": "dealerdirect/phpcodesniffer-composer-installer", - "version": "v0.7.2", - "version_normalized": "0.7.2.0", - "source": { - "type": "git", - "url": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer.git", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/Dealerdirect/phpcodesniffer-composer-installer/zipball/1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "reference": "1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db", - "shasum": "" - }, - "require": { - "composer-plugin-api": "^1.0 || ^2.0", - "php": ">=5.3", - "squizlabs/php_codesniffer": "^2.0 || ^3.1.0 || ^4.0" - }, - "require-dev": { - "composer/composer": "*", - "php-parallel-lint/php-parallel-lint": "^1.3.1", - "phpcompatibility/php-compatibility": "^9.0" - }, - "time": "2022-02-04T12:51:07+00:00", - "type": "composer-plugin", - "extra": { - "class": "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin" - }, - "installation-source": "dist", - "autoload": { - "psr-4": { - "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Franck Nijhof", - "email": "franck.nijhof@dealerdirect.com", - "homepage": "http://www.frenck.nl", - "role": "Developer / IT Manager" - }, - { - "name": "Contributors", - "homepage": "https://github.com/Dealerdirect/phpcodesniffer-composer-installer/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer Standards Composer Installer Plugin", - "homepage": "http://www.dealerdirect.com", - "keywords": [ - "PHPCodeSniffer", - "PHP_CodeSniffer", - "code quality", - "codesniffer", - "composer", - "installer", - "phpcbf", - "phpcs", - "plugin", - "qa", - "quality", - "standard", - "standards", - "style guide", - "stylecheck", - "tests" - ], - "support": { - "issues": "https://github.com/dealerdirect/phpcodesniffer-composer-installer/issues", - "source": "https://github.com/dealerdirect/phpcodesniffer-composer-installer" - }, - "install-path": "../dealerdirect/phpcodesniffer-composer-installer" - }, - { - "name": "squizlabs/php_codesniffer", - "version": "3.6.0", - "version_normalized": "3.6.0.0", - "source": { - "type": "git", - "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/ffced0d2c8fa8e6cdc4d695a743271fab6c38625", - "reference": "ffced0d2c8fa8e6cdc4d695a743271fab6c38625", - "shasum": "" - }, - "require": { - "ext-simplexml": "*", - "ext-tokenizer": "*", - "ext-xmlwriter": "*", - "php": ">=5.4.0" - }, - "require-dev": { - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "time": "2021-04-09T00:54:41+00:00", - "bin": [ - "bin/phpcs", - "bin/phpcbf" - ], - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "3.x-dev" - } - }, - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "BSD-3-Clause" - ], - "authors": [ - { - "name": "Greg Sherwood", - "role": "lead" - } - ], - "description": "PHP_CodeSniffer tokenizes PHP, JavaScript and CSS files and detects violations of a defined set of coding standards.", - "homepage": "https://github.com/squizlabs/PHP_CodeSniffer", - "keywords": [ - "phpcs", - "standards" - ], - "support": { - "issues": "https://github.com/squizlabs/PHP_CodeSniffer/issues", - "source": "https://github.com/squizlabs/PHP_CodeSniffer", - "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" - }, - "install-path": "../squizlabs/php_codesniffer" - }, - { - "name": "wp-coding-standards/wpcs", - "version": "2.3.0", - "version_normalized": "2.3.0.0", - "source": { - "type": "git", - "url": "https://github.com/WordPress/WordPress-Coding-Standards.git", - "reference": "7da1894633f168fe244afc6de00d141f27517b62" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/WordPress/WordPress-Coding-Standards/zipball/7da1894633f168fe244afc6de00d141f27517b62", - "reference": "7da1894633f168fe244afc6de00d141f27517b62", - "shasum": "" - }, - "require": { - "php": ">=5.4", - "squizlabs/php_codesniffer": "^3.3.1" - }, - "require-dev": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.5 || ^0.6", - "phpcompatibility/php-compatibility": "^9.0", - "phpcsstandards/phpcsdevtools": "^1.0", - "phpunit/phpunit": "^4.0 || ^5.0 || ^6.0 || ^7.0" - }, - "suggest": { - "dealerdirect/phpcodesniffer-composer-installer": "^0.6 || This Composer plugin will sort out the PHPCS 'installed_paths' automatically." - }, - "time": "2020-05-13T23:57:56+00:00", - "type": "phpcodesniffer-standard", - "installation-source": "dist", - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Contributors", - "homepage": "https://github.com/WordPress/WordPress-Coding-Standards/graphs/contributors" - } - ], - "description": "PHP_CodeSniffer rules (sniffs) to enforce WordPress coding conventions", - "keywords": [ - "phpcs", - "standards", - "wordpress" - ], - "support": { - "issues": "https://github.com/WordPress/WordPress-Coding-Standards/issues", - "source": "https://github.com/WordPress/WordPress-Coding-Standards", - "wiki": "https://github.com/WordPress/WordPress-Coding-Standards/wiki" - }, - "install-path": "../wp-coding-standards/wpcs" - } - ], - "dev": true, - "dev-package-names": [ - "dealerdirect/phpcodesniffer-composer-installer", - "squizlabs/php_codesniffer", - "wp-coding-standards/wpcs" - ] -} diff --git a/vendor/composer/installed.php b/vendor/composer/installed.php deleted file mode 100644 index 08f969e..0000000 --- a/vendor/composer/installed.php +++ /dev/null @@ -1,59 +0,0 @@ - array( - 'name' => 'wordpress/wp-plugin-dependencies', - 'pretty_version' => 'dev-trunk', - 'version' => 'dev-trunk', - 'reference' => '517f9879483452e4843cb53bb551f840b7bd7e96', - 'type' => 'wordpress-plugin', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev' => true, - ), - 'versions' => array( - 'afragen/add-plugin-dependency-api' => array( - 'pretty_version' => '0.4.8', - 'version' => '0.4.8.0', - 'reference' => 'f88b8161528e7893a9de305077a52403a4c37e4d', - 'type' => 'library', - 'install_path' => __DIR__ . '/../afragen/add-plugin-dependency-api', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'dealerdirect/phpcodesniffer-composer-installer' => array( - 'pretty_version' => 'v0.7.2', - 'version' => '0.7.2.0', - 'reference' => '1c968e542d8843d7cd71de3c5c9c3ff3ad71a1db', - 'type' => 'composer-plugin', - 'install_path' => __DIR__ . '/../dealerdirect/phpcodesniffer-composer-installer', - 'aliases' => array(), - 'dev_requirement' => true, - ), - 'squizlabs/php_codesniffer' => array( - 'pretty_version' => '3.6.0', - 'version' => '3.6.0.0', - 'reference' => 'ffced0d2c8fa8e6cdc4d695a743271fab6c38625', - 'type' => 'library', - 'install_path' => __DIR__ . '/../squizlabs/php_codesniffer', - 'aliases' => array(), - 'dev_requirement' => true, - ), - 'wordpress/wp-plugin-dependencies' => array( - 'pretty_version' => 'dev-trunk', - 'version' => 'dev-trunk', - 'reference' => '517f9879483452e4843cb53bb551f840b7bd7e96', - 'type' => 'wordpress-plugin', - 'install_path' => __DIR__ . '/../../', - 'aliases' => array(), - 'dev_requirement' => false, - ), - 'wp-coding-standards/wpcs' => array( - 'pretty_version' => '2.3.0', - 'version' => '2.3.0.0', - 'reference' => '7da1894633f168fe244afc6de00d141f27517b62', - 'type' => 'phpcodesniffer-standard', - 'install_path' => __DIR__ . '/../wp-coding-standards/wpcs', - 'aliases' => array(), - 'dev_requirement' => true, - ), - ), -); diff --git a/vendor/composer/platform_check.php b/vendor/composer/platform_check.php deleted file mode 100644 index 8b379f4..0000000 --- a/vendor/composer/platform_check.php +++ /dev/null @@ -1,26 +0,0 @@ -= 50600)) { - $issues[] = 'Your Composer dependencies require a PHP version ">= 5.6.0". You are running ' . PHP_VERSION . '.'; -} - -if ($issues) { - if (!headers_sent()) { - header('HTTP/1.1 500 Internal Server Error'); - } - if (!ini_get('display_errors')) { - if (PHP_SAPI === 'cli' || PHP_SAPI === 'phpdbg') { - fwrite(STDERR, 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . implode(PHP_EOL, $issues) . PHP_EOL.PHP_EOL); - } elseif (!headers_sent()) { - echo 'Composer detected issues in your platform:' . PHP_EOL.PHP_EOL . str_replace('You are running '.PHP_VERSION.'.', '', implode(PHP_EOL, $issues)) . PHP_EOL.PHP_EOL; - } - } - trigger_error( - 'Composer detected issues in your platform: ' . implode(' ', $issues), - E_USER_ERROR - ); -} diff --git a/wp-admin/includes/class-wp-plugin-dependencies-2.php b/wp-admin/includes/class-wp-plugin-dependencies-2.php new file mode 100644 index 0000000..3324595 --- /dev/null +++ b/wp-admin/includes/class-wp-plugin-dependencies-2.php @@ -0,0 +1,168 @@ +api_endpoints[ $slug ] ) ) { + $this->api_endpoints[ $slug ] = $endpoint; + } + + return $slug; + } + + /** + * Filter `plugins_api_result` for adding plugin dependencies. + * + * @param stdClass $response Response from `plugins_api()`. + * @param string $action Action type. + * @param stdClass $args Array of data from hook. + * + * @return void|WP_Error + */ + public function add_plugin_card_dependencies( $response, $action, $args ) { + $rest_endpoints = $this->api_endpoints; + $this->args = $args; + + if ( is_wp_error( $response ) + || ( property_exists( $args, 'slug' ) && array_key_exists( $args->slug, $this->api_endpoints ) ) + ) { + /** + * Filter the REST enpoints used for lookup of plugins API data. + * + * @param array + */ + $rest_endpoints = array_merge( $rest_endpoints, apply_filters( 'plugin_dependency_endpoints', $rest_endpoints ) ); + + foreach ( $rest_endpoints as $endpoint ) { + // Endpoint must contain correct slug somewhere in URI. + if ( ! str_contains( $endpoint, $args->slug ) ) { + continue; + } + + $response = wp_remote_get( $endpoint ); + + // Convert response to associative array. + $response = json_decode( wp_remote_retrieve_body( $response ), true ); + if ( null === $response || isset( $response['error'] ) || isset( $response['code'] ) ) { + $message = isset( $response['error'] ) ? $response['error'] : ''; + $response = new WP_Error( 'error', 'Error retrieving plugin data.', $message ); + } + if ( ! is_wp_error( $response ) ) { + break; + } + } + + // Add slug to hook_extra. + add_filter( 'upgrader_package_options', array( $this, 'upgrader_package_options' ), 10, 1 ); + } + + return (object) $response; + } + + /** + * Add slug to hook_extra. + * + * @see WP_Upgrader::run() for $options details. + * + * @param array $options Array of options. + * + * @return array + */ + public function upgrader_package_options( $options ) { + $options['hook_extra']['slug'] = $this->args->slug; + remove_filter( 'upgrader_package_options', array( $this, 'upgrader_package_options' ), 10 ); + + return $options; + } + + /** + * Filter `upgrader_post_install` for plugin dependencies. + * + * For correct renaming of downloaded plugin directory, + * some downloads may not be formatted correctly. + * + * @param bool $true Default is true. + * @param array $hook_extra Array of data from hook. + * @param array $result Array of data for installation. + * + * @return bool + */ + public function fix_plugin_containing_directory( $true, $hook_extra, $result ) { + if ( ! isset( $hook_extra['slug'] ) ) { + return $true; + } + + $from = untrailingslashit( $result['destination'] ); + $to = trailingslashit( $result['local_destination'] ) . $hook_extra['slug']; + + if ( trailingslashit( strtolower( $from ) ) !== trailingslashit( strtolower( $to ) ) ) { + $true = move_dir( $from, $to, true ); + } + + return $true; + } +} + +add_action( 'admin_init', array( new WP_Plugin_Dependencies_2(), 'start' ), 5 ); diff --git a/wp-admin/includes/class-wp-plugin-dependencies.php b/wp-admin/includes/class-wp-plugin-dependencies.php index 5dbd373..25a0c10 100644 --- a/wp-admin/includes/class-wp-plugin-dependencies.php +++ b/wp-admin/includes/class-wp-plugin-dependencies.php @@ -149,20 +149,21 @@ private function sanitize_required_headers( $required_headers ) { foreach ( $exploded as $slug ) { $slug = trim( $slug ); + /** + * Filter $slug to allow for slug switching + * possibly between non-premium and premium plugins. + * + * @param array + */ + $slug = apply_filters( 'wp_plugin_dependencies_slug', $slug ); + // Match to dot org slug format. - if ( preg_match( '/^[a-z0-9\-\p{Cyrillic}\p{Arabic}\p{Han}\p{S}]+$/mu', $slug ) ) { + if ( preg_match( '/^[a-z0-9_\-\p{Cyrillic}\p{Arabic}\p{Han}]+$/mu', $slug ) ) { $sanitized_slugs[] = $slug; } } $sanitized_slugs = array_unique( $sanitized_slugs ); - /** - * Filter slugs to allow for slug switching between non-premium and premium plugins. - * - * @param array - */ - $sanitized_slugs = apply_filters( 'wp_plugin_dependencies_slugs', $sanitized_slugs ); - $this->plugins[ $key ]['RequiresPlugins'] = $sanitized_slugs; $all_slugs = array_merge( $all_slugs, $sanitized_slugs ); }