mirror of
https://ghproxy.net/https://github.com/wp-cli/extension-command.git
synced 2025-10-04 06:06:59 +08:00
Merge pull request #453 from wp-cli/add/phpstan
This commit is contained in:
commit
fa25c5525a
11 changed files with 275 additions and 89 deletions
|
@ -18,14 +18,14 @@
|
||||||
],
|
],
|
||||||
"require": {
|
"require": {
|
||||||
"composer/semver": "^1.4 || ^2 || ^3",
|
"composer/semver": "^1.4 || ^2 || ^3",
|
||||||
"wp-cli/wp-cli": "^2.12"
|
"wp-cli/wp-cli": "^2.13"
|
||||||
},
|
},
|
||||||
"require-dev": {
|
"require-dev": {
|
||||||
"wp-cli/cache-command": "^2.0",
|
"wp-cli/cache-command": "^2.0",
|
||||||
"wp-cli/entity-command": "^1.3 || ^2",
|
"wp-cli/entity-command": "^1.3 || ^2",
|
||||||
"wp-cli/language-command": "^2.0",
|
"wp-cli/language-command": "^2.0",
|
||||||
"wp-cli/scaffold-command": "^1.2 || ^2",
|
"wp-cli/scaffold-command": "^1.2 || ^2",
|
||||||
"wp-cli/wp-cli-tests": "^5.0.1"
|
"wp-cli/wp-cli-tests": "^5"
|
||||||
},
|
},
|
||||||
"config": {
|
"config": {
|
||||||
"process-timeout": 7200,
|
"process-timeout": 7200,
|
||||||
|
|
15
phpstan.neon.dist
Normal file
15
phpstan.neon.dist
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
parameters:
|
||||||
|
level: 9
|
||||||
|
paths:
|
||||||
|
- src
|
||||||
|
- extension-command.php
|
||||||
|
scanDirectories:
|
||||||
|
- vendor/wp-cli/wp-cli/php
|
||||||
|
scanFiles:
|
||||||
|
- vendor/php-stubs/wordpress-stubs/wordpress-stubs.php
|
||||||
|
treatPhpDocTypesAsCertain: false
|
||||||
|
ignoreErrors:
|
||||||
|
- identifier: missingType.iterableValue
|
||||||
|
- identifier: missingType.property
|
||||||
|
- identifier: missingType.parameter
|
||||||
|
- identifier: missingType.return
|
|
@ -72,6 +72,9 @@ class Plugin_AutoUpdates_Command {
|
||||||
* $ wp plugin auto-updates enable hello
|
* $ wp plugin auto-updates enable hello
|
||||||
* Plugin auto-updates for 'hello' enabled.
|
* Plugin auto-updates for 'hello' enabled.
|
||||||
* Success: Enabled 1 of 1 plugin auto-updates.
|
* Success: Enabled 1 of 1 plugin auto-updates.
|
||||||
|
*
|
||||||
|
* @param string[] $args Positional arguments.
|
||||||
|
* @param array{all?: bool, 'disabled-only'?: bool} $assoc_args Associative arguments.
|
||||||
*/
|
*/
|
||||||
public function enable( $args, $assoc_args ) {
|
public function enable( $args, $assoc_args ) {
|
||||||
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use WP_CLI\CommandWithUpgrade;
|
||||||
use WP_CLI\ParsePluginNameInput;
|
use WP_CLI\ParsePluginNameInput;
|
||||||
use WP_CLI\Utils;
|
use WP_CLI\Utils;
|
||||||
use WP_CLI\WpOrgApi;
|
use WP_CLI\WpOrgApi;
|
||||||
|
@ -41,9 +42,11 @@ use function WP_CLI\Utils\normalize_path;
|
||||||
* Success: Installed 1 of 1 plugins.
|
* Success: Installed 1 of 1 plugins.
|
||||||
*
|
*
|
||||||
* @package wp-cli
|
* @package wp-cli
|
||||||
|
*
|
||||||
|
* @phpstan-type PluginInformation object{name: string, slug: non-empty-string, version: string, new_version: string, download_link: string, requires_php?: string, requires?: string, package: string}&\stdClass
|
||||||
|
* @extends CommandWithUpgrade<string,>
|
||||||
*/
|
*/
|
||||||
class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
class Plugin_Command extends CommandWithUpgrade {
|
||||||
|
|
||||||
use ParsePluginNameInput;
|
use ParsePluginNameInput;
|
||||||
|
|
||||||
protected $item_type = 'plugin';
|
protected $item_type = 'plugin';
|
||||||
|
@ -66,13 +69,6 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
'auto_update',
|
'auto_update',
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
|
||||||
* Plugin fetcher instance.
|
|
||||||
*
|
|
||||||
* @var \WP_CLI\Fetchers\Plugin
|
|
||||||
*/
|
|
||||||
protected $fetcher;
|
|
||||||
|
|
||||||
public function __construct() {
|
public function __construct() {
|
||||||
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
require_once ABSPATH . 'wp-admin/includes/plugin.php';
|
||||||
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
require_once ABSPATH . 'wp-admin/includes/plugin-install.php';
|
||||||
|
@ -209,6 +205,9 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function status_single( $args ) {
|
protected function status_single( $args ) {
|
||||||
|
/**
|
||||||
|
* @var object{name: string, file: string} $plugin
|
||||||
|
*/
|
||||||
$plugin = $this->fetcher->get_check( $args[0] );
|
$plugin = $this->fetcher->get_check( $args[0] );
|
||||||
$file = $plugin->file;
|
$file = $plugin->file;
|
||||||
|
|
||||||
|
@ -345,11 +344,18 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
* Plugin 'bbpress' network activated.
|
* Plugin 'bbpress' network activated.
|
||||||
* Plugin 'buddypress' network activated.
|
* Plugin 'buddypress' network activated.
|
||||||
* Success: Activated 2 of 2 plugins.
|
* Success: Activated 2 of 2 plugins.
|
||||||
|
*
|
||||||
|
* @param array $args
|
||||||
|
* @param array $assoc_args
|
||||||
*/
|
*/
|
||||||
public function activate( $args, $assoc_args = array() ) {
|
public function activate( $args, $assoc_args = [] ) {
|
||||||
$network_wide = Utils\get_flag_value( $assoc_args, 'network', false );
|
$network_wide = Utils\get_flag_value( $assoc_args, 'network', false );
|
||||||
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
||||||
$all_exclude = Utils\get_flag_value( $assoc_args, 'exclude' );
|
$all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', '' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string $all_exclude
|
||||||
|
*/
|
||||||
|
|
||||||
$args = $this->check_optional_args_and_all( $args, $all, 'activate', $all_exclude );
|
$args = $this->check_optional_args_and_all( $args, $all, 'activate', $all_exclude );
|
||||||
if ( ! $args ) {
|
if ( ! $args ) {
|
||||||
|
@ -358,6 +364,10 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
|
|
||||||
$successes = 0;
|
$successes = 0;
|
||||||
$errors = 0;
|
$errors = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<object{name: string, file: string}> $plugins
|
||||||
|
*/
|
||||||
$plugins = $this->fetcher->get_many( $args );
|
$plugins = $this->fetcher->get_many( $args );
|
||||||
if ( count( $plugins ) < count( $args ) ) {
|
if ( count( $plugins ) < count( $args ) ) {
|
||||||
$errors = count( $args ) - count( $plugins );
|
$errors = count( $args ) - count( $plugins );
|
||||||
|
@ -387,7 +397,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
|
|
||||||
if ( is_wp_error( $result ) ) {
|
if ( is_wp_error( $result ) ) {
|
||||||
$message = $result->get_error_message();
|
$message = $result->get_error_message();
|
||||||
$message = preg_replace( '/<a\s[^>]+>.*<\/a>/im', '', $message );
|
$message = (string) preg_replace( '/<a\s[^>]+>.*<\/a>/im', '', $message );
|
||||||
$message = wp_strip_all_tags( $message );
|
$message = wp_strip_all_tags( $message );
|
||||||
$message = str_replace( 'Error: ', '', $message );
|
$message = str_replace( 'Error: ', '', $message );
|
||||||
WP_CLI::warning( "Failed to activate plugin. {$message}" );
|
WP_CLI::warning( "Failed to activate plugin. {$message}" );
|
||||||
|
@ -437,10 +447,14 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
* Plugin 'ninja-forms' deactivated.
|
* Plugin 'ninja-forms' deactivated.
|
||||||
* Success: Deactivated 2 of 2 plugins.
|
* Success: Deactivated 2 of 2 plugins.
|
||||||
*/
|
*/
|
||||||
public function deactivate( $args, $assoc_args = array() ) {
|
public function deactivate( $args, $assoc_args = [] ) {
|
||||||
$network_wide = Utils\get_flag_value( $assoc_args, 'network' );
|
$network_wide = Utils\get_flag_value( $assoc_args, 'network' );
|
||||||
$disable_all = Utils\get_flag_value( $assoc_args, 'all' );
|
$disable_all = Utils\get_flag_value( $assoc_args, 'all' );
|
||||||
$disable_all_exclude = Utils\get_flag_value( $assoc_args, 'exclude' );
|
$disable_all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', '' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string $disable_all_exclude
|
||||||
|
*/
|
||||||
|
|
||||||
$args = $this->check_optional_args_and_all( $args, $disable_all, 'deactivate', $disable_all_exclude );
|
$args = $this->check_optional_args_and_all( $args, $disable_all, 'deactivate', $disable_all_exclude );
|
||||||
if ( ! $args ) {
|
if ( ! $args ) {
|
||||||
|
@ -530,7 +544,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
* Plugin 'akismet' activated.
|
* Plugin 'akismet' activated.
|
||||||
* Success: Toggled 1 of 1 plugins.
|
* Success: Toggled 1 of 1 plugins.
|
||||||
*/
|
*/
|
||||||
public function toggle( $args, $assoc_args = array() ) {
|
public function toggle( $args, $assoc_args ) {
|
||||||
$network_wide = Utils\get_flag_value( $assoc_args, 'network' );
|
$network_wide = Utils\get_flag_value( $assoc_args, 'network' );
|
||||||
|
|
||||||
$successes = 0;
|
$successes = 0;
|
||||||
|
@ -574,6 +588,9 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
$path = untrailingslashit( WP_PLUGIN_DIR );
|
$path = untrailingslashit( WP_PLUGIN_DIR );
|
||||||
|
|
||||||
if ( ! empty( $args ) ) {
|
if ( ! empty( $args ) ) {
|
||||||
|
/**
|
||||||
|
* @var object{name: string, file: string} $plugin
|
||||||
|
*/
|
||||||
$plugin = $this->fetcher->get_check( $args[0] );
|
$plugin = $this->fetcher->get_check( $args[0] );
|
||||||
$path .= '/' . $plugin->file;
|
$path .= '/' . $plugin->file;
|
||||||
|
|
||||||
|
@ -591,6 +608,9 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
list($wp_core_version) = explode( '-', $wp_version );
|
list($wp_core_version) = explode( '-', $wp_version );
|
||||||
$wp_core_version = implode( '.', array_slice( explode( '.', $wp_core_version ), 0, 2 ) );
|
$wp_core_version = implode( '.', array_slice( explode( '.', $wp_core_version ), 0, 2 ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \WP_Error|PluginInformation $api
|
||||||
|
*/
|
||||||
$api = plugins_api( 'plugin_information', array( 'slug' => $slug ) );
|
$api = plugins_api( 'plugin_information', array( 'slug' => $slug ) );
|
||||||
|
|
||||||
if ( is_wp_error( $api ) ) {
|
if ( is_wp_error( $api ) ) {
|
||||||
|
@ -755,6 +775,9 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
$auto_updates = [];
|
$auto_updates = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string[] $recently_active
|
||||||
|
*/
|
||||||
$recently_active = is_network_admin() ? get_site_option( 'recently_activated' ) : get_option( 'recently_activated' );
|
$recently_active = is_network_admin() ? get_site_option( 'recently_activated' ) : get_option( 'recently_activated' );
|
||||||
|
|
||||||
if ( false === $recently_active ) {
|
if ( false === $recently_active ) {
|
||||||
|
@ -763,6 +786,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
|
|
||||||
foreach ( $this->get_all_plugins() as $file => $details ) {
|
foreach ( $this->get_all_plugins() as $file => $details ) {
|
||||||
$all_update_info = $this->get_update_info();
|
$all_update_info = $this->get_update_info();
|
||||||
|
// @phpstan-ignore notIdentical.alwaysTrue
|
||||||
$update_info = ( isset( $all_update_info->response[ $file ] ) && null !== $all_update_info->response[ $file ] ) ? (array) $all_update_info->response[ $file ] : null;
|
$update_info = ( isset( $all_update_info->response[ $file ] ) && null !== $all_update_info->response[ $file ] ) ? (array) $all_update_info->response[ $file ] : null;
|
||||||
$name = Utils\get_plugin_name( $file );
|
$name = Utils\get_plugin_name( $file );
|
||||||
$wporg_info = $this->get_wporg_data( $name );
|
$wporg_info = $this->get_wporg_data( $name );
|
||||||
|
@ -875,7 +899,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
|
|
||||||
if ( isset( $plugin_update_info->requires ) && version_compare( $wp_version, $requires, '>=' ) ) {
|
if ( isset( $plugin_update_info->requires ) && version_compare( $wp_version, $requires, '>=' ) ) {
|
||||||
$reason = "This update requires WordPress version $plugin_update_info->requires, but the version installed is $wp_version.";
|
$reason = "This update requires WordPress version $plugin_update_info->requires, but the version installed is $wp_version.";
|
||||||
} elseif ( ! isset( $update_info['package'] ) ) {
|
} elseif ( ! isset( $plugin_update_info->package ) ) {
|
||||||
$reason = 'Update file not provided. Contact author for more details';
|
$reason = 'Update file not provided. Contact author for more details';
|
||||||
} else {
|
} else {
|
||||||
$reason = 'Update not available';
|
$reason = 'Update not available';
|
||||||
|
@ -904,7 +928,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
*
|
*
|
||||||
* @param string $plugin_name The plugin slug.
|
* @param string $plugin_name The plugin slug.
|
||||||
*
|
*
|
||||||
* @return string The status of the plugin, includes the last update date.
|
* @return array{status: string, last_updated: string|false, status?: string, last_updated?: string} The status of the plugin, includes the last update date.
|
||||||
*/
|
*/
|
||||||
protected function get_wporg_data( $plugin_name ) {
|
protected function get_wporg_data( $plugin_name ) {
|
||||||
$data = [
|
$data = [
|
||||||
|
@ -948,9 +972,11 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
if ( strpos( $r_body, 'pubDate' ) !== false ) {
|
if ( strpos( $r_body, 'pubDate' ) !== false ) {
|
||||||
// Very raw check, not validating the format or anything else.
|
// Very raw check, not validating the format or anything else.
|
||||||
$xml = simplexml_load_string( $r_body );
|
$xml = simplexml_load_string( $r_body );
|
||||||
|
if ( false !== $xml ) {
|
||||||
$xml_pub_date = $xml->xpath( '//pubDate' );
|
$xml_pub_date = $xml->xpath( '//pubDate' );
|
||||||
if ( $xml_pub_date ) {
|
if ( $xml_pub_date ) {
|
||||||
$data['last_updated'] = wp_date( 'Y-m-d', (string) strtotime( $xml_pub_date[0] ) );
|
$data['last_updated'] = wp_date( 'Y-m-d', strtotime( $xml_pub_date[0] ) ?: null );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1115,6 +1141,9 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
'status',
|
'status',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var object{name: string, file: string} $plugin
|
||||||
|
*/
|
||||||
$plugin = $this->fetcher->get_check( $args[0] );
|
$plugin = $this->fetcher->get_check( $args[0] );
|
||||||
$file = $plugin->file;
|
$file = $plugin->file;
|
||||||
|
|
||||||
|
@ -1173,11 +1202,14 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
* Uninstalled and deleted 'tinymce-templates' plugin.
|
* Uninstalled and deleted 'tinymce-templates' plugin.
|
||||||
* Success: Uninstalled 2 of 2 plugins.
|
* Success: Uninstalled 2 of 2 plugins.
|
||||||
*/
|
*/
|
||||||
public function uninstall( $args, $assoc_args = array() ) {
|
public function uninstall( $args, $assoc_args = [] ) {
|
||||||
|
|
||||||
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
||||||
$all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', false );
|
$all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', false );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string $all_exclude
|
||||||
|
*/
|
||||||
|
|
||||||
// Check if plugin names or --all is passed.
|
// Check if plugin names or --all is passed.
|
||||||
$args = $this->check_optional_args_and_all( $args, $all, 'uninstall', $all_exclude );
|
$args = $this->check_optional_args_and_all( $args, $all, 'uninstall', $all_exclude );
|
||||||
if ( ! $args ) {
|
if ( ! $args ) {
|
||||||
|
@ -1222,6 +1254,9 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
if ( '.' !== $plugin_slug && ! empty( $plugin_translations[ $plugin_slug ] ) ) {
|
if ( '.' !== $plugin_slug && ! empty( $plugin_translations[ $plugin_slug ] ) ) {
|
||||||
$translations = $plugin_translations[ $plugin_slug ];
|
$translations = $plugin_translations[ $plugin_slug ];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \WP_Filesystem_Base $wp_filesystem
|
||||||
|
*/
|
||||||
global $wp_filesystem;
|
global $wp_filesystem;
|
||||||
require_once ABSPATH . '/wp-admin/includes/file.php';
|
require_once ABSPATH . '/wp-admin/includes/file.php';
|
||||||
WP_Filesystem();
|
WP_Filesystem();
|
||||||
|
@ -1233,7 +1268,11 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
|
|
||||||
$json_translation_files = glob( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '-*.json' );
|
$json_translation_files = glob( WP_LANG_DIR . '/plugins/' . $plugin_slug . '-' . $translation . '-*.json' );
|
||||||
if ( $json_translation_files ) {
|
if ( $json_translation_files ) {
|
||||||
array_map( array( $wp_filesystem, 'delete' ), $json_translation_files );
|
/**
|
||||||
|
* @var callable $callback
|
||||||
|
*/
|
||||||
|
$callback = [ $wp_filesystem, 'delete' ];
|
||||||
|
array_map( $callback, $json_translation_files );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1257,6 +1296,10 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
// Remove deleted plugins from the plugin updates list.
|
// Remove deleted plugins from the plugin updates list.
|
||||||
$current = get_site_transient( $this->upgrade_transient );
|
$current = get_site_transient( $this->upgrade_transient );
|
||||||
if ( $current ) {
|
if ( $current ) {
|
||||||
|
/**
|
||||||
|
* @var object{response: array<string, mixed>, checked: array<string, mixed>}&\stdClass $current
|
||||||
|
*/
|
||||||
|
|
||||||
// Don't remove the plugins that weren't deleted.
|
// Don't remove the plugins that weren't deleted.
|
||||||
$deleted = array_diff( $deleted_plugin_files, $delete_errors );
|
$deleted = array_diff( $deleted_plugin_files, $delete_errors );
|
||||||
|
|
||||||
|
@ -1292,7 +1335,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
*
|
*
|
||||||
* @subcommand is-installed
|
* @subcommand is-installed
|
||||||
*/
|
*/
|
||||||
public function is_installed( $args, $assoc_args = array() ) {
|
public function is_installed( $args, $assoc_args ) {
|
||||||
if ( $this->fetcher->get( $args[0] ) ) {
|
if ( $this->fetcher->get( $args[0] ) ) {
|
||||||
WP_CLI::halt( 0 );
|
WP_CLI::halt( 0 );
|
||||||
} else {
|
} else {
|
||||||
|
@ -1322,7 +1365,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
*
|
*
|
||||||
* @subcommand is-active
|
* @subcommand is-active
|
||||||
*/
|
*/
|
||||||
public function is_active( $args, $assoc_args = array() ) {
|
public function is_active( $args, $assoc_args ) {
|
||||||
$network_wide = Utils\get_flag_value( $assoc_args, 'network' );
|
$network_wide = Utils\get_flag_value( $assoc_args, 'network' );
|
||||||
|
|
||||||
$plugin = $this->fetcher->get( $args[0] );
|
$plugin = $this->fetcher->get( $args[0] );
|
||||||
|
@ -1366,10 +1409,14 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
* Deleted 'tinymce-templates' plugin.
|
* Deleted 'tinymce-templates' plugin.
|
||||||
* Success: Deleted 2 of 2 plugins.
|
* Success: Deleted 2 of 2 plugins.
|
||||||
*/
|
*/
|
||||||
public function delete( $args, $assoc_args = array() ) {
|
public function delete( $args, $assoc_args ) {
|
||||||
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
$all = Utils\get_flag_value( $assoc_args, 'all', false );
|
||||||
$all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', false );
|
$all_exclude = Utils\get_flag_value( $assoc_args, 'exclude', false );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string $all_exclude
|
||||||
|
*/
|
||||||
|
|
||||||
// Check if plugin names or --all is passed.
|
// Check if plugin names or --all is passed.
|
||||||
$args = $this->check_optional_args_and_all( $args, $all, 'delete', $all_exclude );
|
$args = $this->check_optional_args_and_all( $args, $all, 'delete', $all_exclude );
|
||||||
if ( ! $args ) {
|
if ( ! $args ) {
|
||||||
|
@ -1505,7 +1552,11 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
* @subcommand list
|
* @subcommand list
|
||||||
*/
|
*/
|
||||||
public function list_( $_, $assoc_args ) {
|
public function list_( $_, $assoc_args ) {
|
||||||
|
/**
|
||||||
|
* @var string $fields
|
||||||
|
*/
|
||||||
$fields = Utils\get_flag_value( $assoc_args, 'fields' );
|
$fields = Utils\get_flag_value( $assoc_args, 'fields' );
|
||||||
|
|
||||||
if ( ! empty( $fields ) ) {
|
if ( ! empty( $fields ) ) {
|
||||||
$fields = explode( ',', $fields );
|
$fields = explode( ',', $fields );
|
||||||
$this->check_wporg['status'] = in_array( 'wporg_status', $fields, true );
|
$this->check_wporg['status'] = in_array( 'wporg_status', $fields, true );
|
||||||
|
@ -1578,7 +1629,7 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
/**
|
/**
|
||||||
* Gets the details of a plugin.
|
* Gets the details of a plugin.
|
||||||
*
|
*
|
||||||
* @param object
|
* @param string $file Plugin file name.
|
||||||
* @return array
|
* @return array
|
||||||
*/
|
*/
|
||||||
private function get_details( $file ) {
|
private function get_details( $file ) {
|
||||||
|
@ -1591,8 +1642,8 @@ class Plugin_Command extends \WP_CLI\CommandWithUpgrade {
|
||||||
/**
|
/**
|
||||||
* Performs deletion of plugin files
|
* Performs deletion of plugin files
|
||||||
*
|
*
|
||||||
* @param $plugin - Plugin fetcher object (name, file)
|
* @param $plugin Plugin fetcher object (name, file)
|
||||||
* @return bool - If plugin was deleted
|
* @return bool Whether plugin was deleted
|
||||||
*/
|
*/
|
||||||
private function delete_plugin( $plugin ) {
|
private function delete_plugin( $plugin ) {
|
||||||
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound
|
||||||
|
|
|
@ -28,6 +28,9 @@ use WP_CLI\Utils;
|
||||||
*/
|
*/
|
||||||
class Theme_AutoUpdates_Command {
|
class Theme_AutoUpdates_Command {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @use ParseThemeNameInput<\WP_Theme>
|
||||||
|
*/
|
||||||
use ParseThemeNameInput;
|
use ParseThemeNameInput;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -41,9 +41,15 @@ use WP_CLI\Utils;
|
||||||
* Author: the WordPress team
|
* Author: the WordPress team
|
||||||
*
|
*
|
||||||
* @package wp-cli
|
* @package wp-cli
|
||||||
|
*
|
||||||
|
* @phpstan-type ThemeInformation object{name: string, slug: non-empty-string, version: string, new_version: string, download_link: string, requires_php?: string, requires?: string}&\stdClass
|
||||||
|
* @extends CommandWithUpgrade<\WP_Theme>
|
||||||
*/
|
*/
|
||||||
class Theme_Command extends CommandWithUpgrade {
|
class Theme_Command extends CommandWithUpgrade {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @use ParseThemeNameInput<\WP_Theme>
|
||||||
|
*/
|
||||||
use ParseThemeNameInput;
|
use ParseThemeNameInput;
|
||||||
|
|
||||||
protected $item_type = 'theme';
|
protected $item_type = 'theme';
|
||||||
|
@ -211,8 +217,11 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
*
|
*
|
||||||
* $ wp theme activate twentysixteen
|
* $ wp theme activate twentysixteen
|
||||||
* Success: Switched to 'Twenty Sixteen' theme.
|
* Success: Switched to 'Twenty Sixteen' theme.
|
||||||
|
*
|
||||||
|
* @param string[] $args Positional arguments.
|
||||||
|
* @param array $assoc_args Associative arguments. Unused.
|
||||||
*/
|
*/
|
||||||
public function activate( $args = array() ) {
|
public function activate( $args, $assoc_args = [] ) {
|
||||||
$theme = $this->fetcher->get_check( $args[0] );
|
$theme = $this->fetcher->get_check( $args[0] );
|
||||||
|
|
||||||
$errors = $theme->errors();
|
$errors = $theme->errors();
|
||||||
|
@ -232,7 +241,7 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
WP_CLI::error( "The '{$theme->get_stylesheet()}' theme cannot be activated without its parent, '{$theme->get_template()}'." );
|
WP_CLI::error( "The '{$theme->get_stylesheet()}' theme cannot be activated without its parent, '{$theme->get_template()}'." );
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_theme( $theme->get_template(), $theme->get_stylesheet() );
|
switch_theme( $theme->get_stylesheet() );
|
||||||
|
|
||||||
if ( $this->is_active_theme( $theme ) ) {
|
if ( $this->is_active_theme( $theme ) ) {
|
||||||
WP_CLI::success( "Switched to '$name' theme." );
|
WP_CLI::success( "Switched to '$name' theme." );
|
||||||
|
@ -279,6 +288,9 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
WP_CLI::error( 'This is not a multisite installation.' );
|
WP_CLI::error( 'This is not a multisite installation.' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \WP_Theme $theme
|
||||||
|
*/
|
||||||
$theme = $this->fetcher->get_check( $args[0] );
|
$theme = $this->fetcher->get_check( $args[0] );
|
||||||
$name = $theme->get( 'Name' );
|
$name = $theme->get( 'Name' );
|
||||||
|
|
||||||
|
@ -290,6 +302,11 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
if ( empty( $allowed_themes ) ) {
|
if ( empty( $allowed_themes ) ) {
|
||||||
$allowed_themes = array();
|
$allowed_themes = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, bool> $allowed_themes
|
||||||
|
*/
|
||||||
|
|
||||||
$allowed_themes[ $theme->get_stylesheet() ] = true;
|
$allowed_themes[ $theme->get_stylesheet() ] = true;
|
||||||
call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes );
|
call_user_func( "update{$_site}_option", 'allowedthemes', $allowed_themes );
|
||||||
|
|
||||||
|
@ -344,6 +361,11 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
|
|
||||||
# Add the current theme to the allowed themes option or site option
|
# Add the current theme to the allowed themes option or site option
|
||||||
$allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' );
|
$allowed_themes = call_user_func( "get{$_site}_option", 'allowedthemes' );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, bool> $allowed_themes
|
||||||
|
*/
|
||||||
|
|
||||||
if ( ! empty( $allowed_themes[ $theme->get_stylesheet() ] ) ) {
|
if ( ! empty( $allowed_themes[ $theme->get_stylesheet() ] ) ) {
|
||||||
unset( $allowed_themes[ $theme->get_stylesheet() ] );
|
unset( $allowed_themes[ $theme->get_stylesheet() ] );
|
||||||
}
|
}
|
||||||
|
@ -400,6 +422,9 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
list($wp_core_version) = explode( '-', $wp_version );
|
list($wp_core_version) = explode( '-', $wp_version );
|
||||||
$wp_core_version = implode( '.', array_slice( explode( '.', $wp_core_version ), 0, 2 ) );
|
$wp_core_version = implode( '.', array_slice( explode( '.', $wp_core_version ), 0, 2 ) );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \WP_Error|ThemeInformation $api
|
||||||
|
*/
|
||||||
$api = themes_api( 'theme_information', array( 'slug' => $slug ) );
|
$api = themes_api( 'theme_information', array( 'slug' => $slug ) );
|
||||||
|
|
||||||
if ( is_wp_error( $api ) ) {
|
if ( is_wp_error( $api ) ) {
|
||||||
|
@ -732,7 +757,7 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
*
|
*
|
||||||
* @subcommand is-installed
|
* @subcommand is-installed
|
||||||
*/
|
*/
|
||||||
public function is_installed( $args, $assoc_args = array() ) {
|
public function is_installed( $args, $assoc_args ) {
|
||||||
$theme = wp_get_theme( $args[0] );
|
$theme = wp_get_theme( $args[0] );
|
||||||
|
|
||||||
if ( $theme->exists() ) {
|
if ( $theme->exists() ) {
|
||||||
|
@ -761,7 +786,7 @@ class Theme_Command extends CommandWithUpgrade {
|
||||||
*
|
*
|
||||||
* @subcommand is-active
|
* @subcommand is-active
|
||||||
*/
|
*/
|
||||||
public function is_active( $args, $assoc_args = array() ) {
|
public function is_active( $args, $assoc_args ) {
|
||||||
$theme = wp_get_theme( $args[0] );
|
$theme = wp_get_theme( $args[0] );
|
||||||
|
|
||||||
if ( ! $theme->exists() ) {
|
if ( ! $theme->exists() ) {
|
||||||
|
|
|
@ -74,8 +74,11 @@ class Theme_Mod_Command extends WP_CLI_Command {
|
||||||
* | background_color | dd3333 |
|
* | background_color | dd3333 |
|
||||||
* | header_textcolor | |
|
* | header_textcolor | |
|
||||||
* +------------------+--------+
|
* +------------------+--------+
|
||||||
|
*
|
||||||
|
* @param string[] $args Positional arguments.
|
||||||
|
* @param array{field?: string, all?: bool, format: string} $assoc_args Associative arguments.
|
||||||
*/
|
*/
|
||||||
public function get( $args = array(), $assoc_args = array() ) {
|
public function get( $args, $assoc_args ) {
|
||||||
|
|
||||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
||||||
WP_CLI::error( 'You must specify at least one mod or use --all.' );
|
WP_CLI::error( 'You must specify at least one mod or use --all.' );
|
||||||
|
@ -162,10 +165,13 @@ class Theme_Mod_Command extends WP_CLI_Command {
|
||||||
* +------------------+---------+
|
* +------------------+---------+
|
||||||
*
|
*
|
||||||
* @subcommand list
|
* @subcommand list
|
||||||
|
*
|
||||||
|
* @param string[] $args Positional arguments. Unused.
|
||||||
|
* @param array{field?: string, format: string} $assoc_args Associative arguments.
|
||||||
*/
|
*/
|
||||||
public function list_( $args = array(), $assoc_args = array() ) {
|
public function list_( $args, $assoc_args ) {
|
||||||
|
|
||||||
$assoc_args['all'] = 1;
|
$assoc_args['all'] = true;
|
||||||
|
|
||||||
$this->get( $args, $assoc_args );
|
$this->get( $args, $assoc_args );
|
||||||
}
|
}
|
||||||
|
@ -194,8 +200,11 @@ class Theme_Mod_Command extends WP_CLI_Command {
|
||||||
* # Remove multiple theme mods.
|
* # Remove multiple theme mods.
|
||||||
* $ wp theme mod remove background_color header_textcolor
|
* $ wp theme mod remove background_color header_textcolor
|
||||||
* Success: 2 mods removed.
|
* Success: 2 mods removed.
|
||||||
|
*
|
||||||
|
* @param string[] $args Positional arguments.
|
||||||
|
* @param array{all?: bool} $assoc_args Associative arguments.
|
||||||
*/
|
*/
|
||||||
public function remove( $args = array(), $assoc_args = array() ) {
|
public function remove( $args, $assoc_args ) {
|
||||||
|
|
||||||
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
if ( ! \WP_CLI\Utils\get_flag_value( $assoc_args, 'all' ) && empty( $args ) ) {
|
||||||
WP_CLI::error( 'You must specify at least one mod or use --all.' );
|
WP_CLI::error( 'You must specify at least one mod or use --all.' );
|
||||||
|
@ -232,8 +241,11 @@ class Theme_Mod_Command extends WP_CLI_Command {
|
||||||
* # Set theme mod
|
* # Set theme mod
|
||||||
* $ wp theme mod set background_color 000000
|
* $ wp theme mod set background_color 000000
|
||||||
* Success: Theme mod background_color set to 000000.
|
* Success: Theme mod background_color set to 000000.
|
||||||
|
*
|
||||||
|
* @param array{0: string, 1: string} $args Positional arguments.
|
||||||
|
* @param array $assoc_args Associative arguments. Unused.
|
||||||
*/
|
*/
|
||||||
public function set( $args = array(), $assoc_args = array() ) {
|
public function set( $args, $assoc_args ) {
|
||||||
list( $mod, $value ) = $args;
|
list( $mod, $value ) = $args;
|
||||||
|
|
||||||
set_theme_mod( $mod, $value );
|
set_theme_mod( $mod, $value );
|
||||||
|
|
|
@ -11,6 +11,12 @@ use WP_CLI\Loggers;
|
||||||
use WP_CLI\Utils;
|
use WP_CLI\Utils;
|
||||||
use WP_Error;
|
use WP_Error;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @phpstan-import-type ThemeInformation from \Theme_Command
|
||||||
|
* @phpstan-import-type PluginInformation from \Plugin_Command
|
||||||
|
*
|
||||||
|
* @template T
|
||||||
|
*/
|
||||||
abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
|
|
||||||
protected $fetcher;
|
protected $fetcher;
|
||||||
|
@ -61,25 +67,43 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
$this->fetcher = new Fetchers\Plugin();
|
$this->fetcher = new Fetchers\Plugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return class-string<\WP_Upgrader>
|
||||||
|
*/
|
||||||
abstract protected function get_upgrader_class( $force );
|
abstract protected function get_upgrader_class( $force );
|
||||||
|
|
||||||
abstract protected function get_item_list();
|
abstract protected function get_item_list();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param array List of update candidates
|
* @param array $items List of update candidates
|
||||||
* @param array List of item names
|
* @param array $args List of item names
|
||||||
* @return array List of update candidates
|
* @return array List of update candidates
|
||||||
*/
|
*/
|
||||||
abstract protected function filter_item_list( $items, $args );
|
abstract protected function filter_item_list( $items, $args );
|
||||||
|
|
||||||
abstract protected function get_all_items();
|
abstract protected function get_all_items();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the status for a given extension.
|
||||||
|
*
|
||||||
|
* @param T $file Extension to get the status for.
|
||||||
|
*
|
||||||
|
* @return string Status of the extension.
|
||||||
|
*/
|
||||||
abstract protected function get_status( $file );
|
abstract protected function get_status( $file );
|
||||||
|
|
||||||
abstract protected function status_single( $args );
|
abstract protected function status_single( $args );
|
||||||
|
|
||||||
abstract protected function install_from_repo( $slug, $assoc_args );
|
abstract protected function install_from_repo( $slug, $assoc_args );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates an extension.
|
||||||
|
*
|
||||||
|
* @param string[] $args Positional arguments.
|
||||||
|
* @param array $assoc_args Associative arguments.
|
||||||
|
*/
|
||||||
|
abstract public function activate( $args, $assoc_args = [] );
|
||||||
|
|
||||||
public function status( $args ) {
|
public function status( $args ) {
|
||||||
// Force WordPress to check for updates.
|
// Force WordPress to check for updates.
|
||||||
call_user_func( $this->upgrade_refresh );
|
call_user_func( $this->upgrade_refresh );
|
||||||
|
@ -197,13 +221,16 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
|
|
||||||
$filter = false;
|
$filter = false;
|
||||||
// If a GitHub URL, do some guessing as to the correct plugin/theme directory.
|
// If a GitHub URL, do some guessing as to the correct plugin/theme directory.
|
||||||
if ( $is_remote && 'github.com' === $this->parse_url_host_component( $slug, PHP_URL_HOST )
|
if ( $is_remote && 'github.com' === Utils\parse_url( $slug, PHP_URL_HOST )
|
||||||
// Don't attempt to rename ZIPs uploaded to the releases page or coming from a raw source.
|
// Don't attempt to rename ZIPs uploaded to the releases page or coming from a raw source.
|
||||||
&& ! preg_match( '#github\.com/[^/]+/[^/]+/(?:releases/download|raw)/#', $slug ) ) {
|
&& ! preg_match( '#github\.com/[^/]+/[^/]+/(?:releases/download|raw)/#', $slug ) ) {
|
||||||
|
|
||||||
$filter = function ( $source ) use ( $slug ) {
|
$filter = function ( $source ) use ( $slug ) {
|
||||||
|
/**
|
||||||
$slug_dir = Utils\basename( $this->parse_url_host_component( $slug, PHP_URL_PATH ), '.zip' );
|
* @var string $path
|
||||||
|
*/
|
||||||
|
$path = Utils\parse_url( $slug, PHP_URL_PATH );
|
||||||
|
$slug_dir = Utils\basename( $path, '.zip' );
|
||||||
|
|
||||||
// Don't use the zip name if archive attached to release, as name likely to contain version tag/branch.
|
// Don't use the zip name if archive attached to release, as name likely to contain version tag/branch.
|
||||||
if ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/#', $slug, $matches ) ) {
|
if ( preg_match( '#github\.com/[^/]+/([^/]+)/archive/#', $slug, $matches ) ) {
|
||||||
|
@ -215,7 +242,7 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
if ( $source_dir === $slug_dir ) {
|
if ( $source_dir === $slug_dir ) {
|
||||||
return $source;
|
return $source;
|
||||||
}
|
}
|
||||||
$new_path = substr_replace( $source, $slug_dir, strrpos( $source, $source_dir ), strlen( $source_dir ) );
|
$new_path = substr_replace( $source, $slug_dir, (int) strrpos( $source, $source_dir ), strlen( $source_dir ) );
|
||||||
|
|
||||||
if ( $GLOBALS['wp_filesystem']->move( $source, $new_path ) ) {
|
if ( $GLOBALS['wp_filesystem']->move( $source, $new_path ) ) {
|
||||||
WP_CLI::log( sprintf( "Renamed Github-based project from '%s' to '%s'.", $source_dir, $slug_dir ) );
|
WP_CLI::log( sprintf( "Renamed Github-based project from '%s' to '%s'.", $source_dir, $slug_dir ) );
|
||||||
|
@ -294,8 +321,10 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
/**
|
/**
|
||||||
* Prepare an API response for downloading a particular version of an item.
|
* Prepare an API response for downloading a particular version of an item.
|
||||||
*
|
*
|
||||||
* @param object $response wordpress.org API response
|
* @param object $response Wordpress.org API response.
|
||||||
* @param string $version The desired version of the package
|
* @param string $version The desired version of the package.
|
||||||
|
*
|
||||||
|
* @phpstan-param PluginInformation|ThemeInformation $response
|
||||||
*/
|
*/
|
||||||
protected static function alter_api_response( $response, $version ) {
|
protected static function alter_api_response( $response, $version ) {
|
||||||
if ( $response->version === $version ) {
|
if ( $response->version === $version ) {
|
||||||
|
@ -346,8 +375,8 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected function get_upgrader( $assoc_args ) {
|
protected function get_upgrader( $assoc_args ) {
|
||||||
$force = (bool) Utils\get_flag_value( $assoc_args, 'force', false );
|
$force = Utils\get_flag_value( $assoc_args, 'force', false );
|
||||||
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );
|
$insecure = Utils\get_flag_value( $assoc_args, 'insecure', false );
|
||||||
$upgrader_class = $this->get_upgrader_class( $force );
|
$upgrader_class = $this->get_upgrader_class( $force );
|
||||||
return Utils\get_upgrader( $upgrader_class, $insecure );
|
return Utils\get_upgrader( $upgrader_class, $insecure );
|
||||||
}
|
}
|
||||||
|
@ -384,19 +413,22 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
$minor = (bool) Utils\get_flag_value( $assoc_args, 'minor', false );
|
$minor = Utils\get_flag_value( $assoc_args, 'minor', false );
|
||||||
$patch = (bool) Utils\get_flag_value( $assoc_args, 'patch', false );
|
$patch = Utils\get_flag_value( $assoc_args, 'patch', false );
|
||||||
|
|
||||||
if (
|
if (
|
||||||
in_array( $this->item_type, [ 'plugin', 'theme' ], true ) &&
|
in_array( $this->item_type, [ 'plugin', 'theme' ], true ) &&
|
||||||
( $minor || $patch )
|
( $minor || $patch )
|
||||||
) {
|
) {
|
||||||
$type = $minor ? 'minor' : 'patch';
|
$type = $minor ? 'minor' : 'patch';
|
||||||
$insecure = (bool) Utils\get_flag_value( $assoc_args, 'insecure', false );
|
$insecure = Utils\get_flag_value( $assoc_args, 'insecure', false );
|
||||||
|
|
||||||
$items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type, $insecure, true, $this->item_type );
|
$items_to_update = self::get_minor_or_patch_updates( $items_to_update, $type, $insecure, true, $this->item_type );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string|null $exclude
|
||||||
|
*/
|
||||||
$exclude = Utils\get_flag_value( $assoc_args, 'exclude' );
|
$exclude = Utils\get_flag_value( $assoc_args, 'exclude' );
|
||||||
if ( isset( $exclude ) ) {
|
if ( isset( $exclude ) ) {
|
||||||
$exclude_items = explode( ',', trim( $assoc_args['exclude'], ',' ) );
|
$exclude_items = explode( ',', trim( $assoc_args['exclude'], ',' ) );
|
||||||
|
@ -475,6 +507,9 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
foreach ( $items_to_update as $name => $item_data ) {
|
foreach ( $items_to_update as $name => $item_data ) {
|
||||||
if ( isset( $transient->response[ $name ] ) ) {
|
if ( isset( $transient->response[ $name ] ) ) {
|
||||||
if ( is_object( $transient->response[ $name ] ) ) {
|
if ( is_object( $transient->response[ $name ] ) ) {
|
||||||
|
/**
|
||||||
|
* @var object{response: array<string, ThemeInformation|PluginInformation>} $transient
|
||||||
|
*/
|
||||||
$transient->response[ $name ]->new_version = $item_data['update_version'];
|
$transient->response[ $name ]->new_version = $item_data['update_version'];
|
||||||
$transient->response[ $name ]->package = $item_data['update_package'];
|
$transient->response[ $name ]->package = $item_data['update_package'];
|
||||||
} else {
|
} else {
|
||||||
|
@ -490,6 +525,10 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
remove_filter( 'site_transient_' . $this->upgrade_transient, $transient_filter, 999 );
|
remove_filter( 'site_transient_' . $this->upgrade_transient, $transient_filter, 999 );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array $items_to_update
|
||||||
|
*/
|
||||||
|
|
||||||
// Let the user know the results.
|
// Let the user know the results.
|
||||||
$num_to_update = count( $items_to_update );
|
$num_to_update = count( $items_to_update );
|
||||||
$num_updated = count(
|
$num_updated = count(
|
||||||
|
@ -545,14 +584,14 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
protected function _list( $_, $assoc_args ) {
|
protected function _list( $_, $assoc_args ) {
|
||||||
|
|
||||||
// Force WordPress to check for updates if `--skip-update-check` is not passed.
|
// Force WordPress to check for updates if `--skip-update-check` is not passed.
|
||||||
if ( false === (bool) Utils\get_flag_value( $assoc_args, 'skip-update-check', false ) ) {
|
if ( false === Utils\get_flag_value( $assoc_args, 'skip-update-check', false ) ) {
|
||||||
delete_site_transient( $this->upgrade_transient );
|
delete_site_transient( $this->upgrade_transient );
|
||||||
call_user_func( $this->upgrade_refresh );
|
call_user_func( $this->upgrade_refresh );
|
||||||
}
|
}
|
||||||
|
|
||||||
$all_items = $this->get_all_items();
|
$all_items = $this->get_all_items();
|
||||||
|
|
||||||
if ( false !== (bool) Utils\get_flag_value( $assoc_args, 'recently-active', false ) ) {
|
if ( false !== Utils\get_flag_value( $assoc_args, 'recently-active', false ) ) {
|
||||||
$all_items = array_filter(
|
$all_items = array_filter(
|
||||||
$all_items,
|
$all_items,
|
||||||
function ( $value ) {
|
function ( $value ) {
|
||||||
|
@ -624,6 +663,9 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
protected function has_update( $slug ) {
|
protected function has_update( $slug ) {
|
||||||
|
/**
|
||||||
|
* @var object{checked: array<string, string>, response: array<string, string>, no_update: array<string, object{new_version: string, package: string, requires: string}&\stdClass>} $update_list
|
||||||
|
*/
|
||||||
$update_list = get_site_transient( $this->upgrade_transient );
|
$update_list = get_site_transient( $this->upgrade_transient );
|
||||||
|
|
||||||
return isset( $update_list->response[ $slug ] );
|
return isset( $update_list->response[ $slug ] );
|
||||||
|
@ -632,10 +674,15 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
/**
|
/**
|
||||||
* Get the available update info
|
* Get the available update info
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return object{checked: array<string, string>, response: array<string, array<string, string|null>>, no_update: array<string, object{new_version: string, package: string, requires: string}&\stdClass>} $update_list
|
||||||
*/
|
*/
|
||||||
protected function get_update_info() {
|
protected function get_update_info() {
|
||||||
return get_site_transient( $this->upgrade_transient );
|
/**
|
||||||
|
* @var object{checked: array<string, string>, response: array<string, array<string, string|null>>, no_update: array<string, object{new_version: string, package: string, requires: string}&\stdClass>} $update_list
|
||||||
|
*/
|
||||||
|
$update_list = get_site_transient( $this->upgrade_transient );
|
||||||
|
|
||||||
|
return $update_list;
|
||||||
}
|
}
|
||||||
|
|
||||||
private $map = [
|
private $map = [
|
||||||
|
@ -688,8 +735,12 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
$wp_org_api = new WpOrgApi( [ 'insecure' => $insecure ] );
|
$wp_org_api = new WpOrgApi( [ 'insecure' => $insecure ] );
|
||||||
foreach ( $items as $i => $item ) {
|
foreach ( $items as $i => $item ) {
|
||||||
try {
|
try {
|
||||||
|
/**
|
||||||
|
* @var callable $callback
|
||||||
|
*/
|
||||||
|
$callback = [ $wp_org_api, "get_{$item_type}_info" ];
|
||||||
$data = call_user_func(
|
$data = call_user_func(
|
||||||
[ $wp_org_api, "get_{$item_type}_info" ],
|
$callback,
|
||||||
$item['name'],
|
$item['name'],
|
||||||
// The default.
|
// The default.
|
||||||
'en_US',
|
'en_US',
|
||||||
|
@ -780,9 +831,15 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
if ( 'plugin' === $this->item_type ) {
|
if ( 'plugin' === $this->item_type ) {
|
||||||
$api = plugins_api( 'query_plugins', $api_args );
|
$api = plugins_api( 'query_plugins', $api_args );
|
||||||
} else {
|
} else {
|
||||||
|
// fields[screenshot_count] could be an int, not a bool.
|
||||||
|
// @phpstan-ignore argument.type
|
||||||
$api = themes_api( 'query_themes', $api_args );
|
$api = themes_api( 'query_themes', $api_args );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var \WP_Error|object{info: object{page: int, pages: int, results: int}} $api
|
||||||
|
*/
|
||||||
|
|
||||||
if ( is_wp_error( $api ) ) {
|
if ( is_wp_error( $api ) ) {
|
||||||
WP_CLI::error( $api->get_error_message() . __( ' Try again' ) );
|
WP_CLI::error( $api->get_error_message() . __( ' Try again' ) );
|
||||||
}
|
}
|
||||||
|
@ -803,7 +860,10 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 'table' === $format ) {
|
if ( 'table' === $format ) {
|
||||||
$count = Utils\get_flag_value( $api->info, 'results', 'unknown' );
|
/**
|
||||||
|
* @var string $count
|
||||||
|
*/
|
||||||
|
$count = Utils\get_flag_value( (array) $api->info, 'results', 'unknown' );
|
||||||
WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) );
|
WP_CLI::success( sprintf( 'Showing %s of %s %s.', count( $items ), $count, $plural ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,18 +892,6 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Retrieves PHP_URL_HOST component from URL.
|
|
||||||
*
|
|
||||||
* @param int $component The component to retrieve.
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function parse_url_host_component( $url, $component ) {
|
|
||||||
// phpcs:ignore WordPress.WP.AlternativeFunctions.parse_url_parse_url -- parse_url will only be used in absence of wp_parse_url.
|
|
||||||
return function_exists( 'wp_parse_url' ) ? wp_parse_url( $url, $component ) : parse_url( $url, $component );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add versioned GitHub URLs to cache allowlist.
|
* Add versioned GitHub URLs to cache allowlist.
|
||||||
*
|
*
|
||||||
|
@ -895,6 +943,9 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( 404 === wp_remote_retrieve_response_code( $response ) ) {
|
if ( 404 === wp_remote_retrieve_response_code( $response ) ) {
|
||||||
|
/**
|
||||||
|
* @var object{status: string, message: string} $decoded_body
|
||||||
|
*/
|
||||||
return new \WP_Error(
|
return new \WP_Error(
|
||||||
$decoded_body->status,
|
$decoded_body->status,
|
||||||
$decoded_body->message
|
$decoded_body->message
|
||||||
|
@ -905,6 +956,10 @@ abstract class CommandWithUpgrade extends \WP_CLI_Command {
|
||||||
return new \WP_Error( 500, 'Empty response received from GitHub.com API' );
|
return new \WP_Error( 500, 'Empty response received from GitHub.com API' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<int, object{name: string}> $decoded_body
|
||||||
|
*/
|
||||||
|
|
||||||
if ( ! isset( $decoded_body[0] ) ) {
|
if ( ! isset( $decoded_body[0] ) ) {
|
||||||
return new \WP_Error( '400', 'The given Github repository does not have any releases' );
|
return new \WP_Error( '400', 'The given Github repository does not have any releases' );
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@ namespace WP_CLI\Fetchers;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a WordPress plugin based on one of its attributes.
|
* Fetch a WordPress plugin based on one of its attributes.
|
||||||
|
*
|
||||||
|
* @extends Base<object{name: string, file: string}>
|
||||||
*/
|
*/
|
||||||
class Plugin extends Base {
|
class Plugin extends Base {
|
||||||
|
|
||||||
|
@ -15,10 +17,12 @@ class Plugin extends Base {
|
||||||
/**
|
/**
|
||||||
* Get a plugin object by name
|
* Get a plugin object by name
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string|int $name Plugin name.
|
||||||
* @return object|false
|
* @return object{name: string, file: string}|false
|
||||||
*/
|
*/
|
||||||
public function get( $name ) {
|
public function get( $name ) {
|
||||||
|
$name = (string) $name;
|
||||||
|
|
||||||
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Calling native WordPress hook.
|
// phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Calling native WordPress hook.
|
||||||
foreach ( apply_filters( 'all_plugins', get_plugins() ) as $file => $_ ) {
|
foreach ( apply_filters( 'all_plugins', get_plugins() ) as $file => $_ ) {
|
||||||
if ( "$name.php" === $file ||
|
if ( "$name.php" === $file ||
|
||||||
|
|
|
@ -6,6 +6,8 @@ use WP_CLI\Utils;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetch a WordPress theme based on one of its attributes.
|
* Fetch a WordPress theme based on one of its attributes.
|
||||||
|
*
|
||||||
|
* @extends Base<\WP_Theme>
|
||||||
*/
|
*/
|
||||||
class Theme extends Base {
|
class Theme extends Base {
|
||||||
|
|
||||||
|
@ -17,8 +19,8 @@ class Theme extends Base {
|
||||||
/**
|
/**
|
||||||
* Get a theme object by name
|
* Get a theme object by name
|
||||||
*
|
*
|
||||||
* @param string $name
|
* @param string|int $name
|
||||||
* @return object|false
|
* @return \WP_Theme|false
|
||||||
*/
|
*/
|
||||||
public function get( $name ) {
|
public function get( $name ) {
|
||||||
// Workaround to equalize folder naming conventions across Win/Mac/Linux.
|
// Workaround to equalize folder naming conventions across Win/Mac/Linux.
|
||||||
|
@ -26,7 +28,7 @@ class Theme extends Base {
|
||||||
$existing_themes = wp_get_themes( array( 'errors' => null ) );
|
$existing_themes = wp_get_themes( array( 'errors' => null ) );
|
||||||
$existing_stylesheets = array_keys( $existing_themes );
|
$existing_stylesheets = array_keys( $existing_themes );
|
||||||
if ( ! in_array( $name, $existing_stylesheets, true ) ) {
|
if ( ! in_array( $name, $existing_stylesheets, true ) ) {
|
||||||
$inexact_match = $this->find_inexact_match( $name, $existing_themes );
|
$inexact_match = $this->find_inexact_match( (string) $name, $existing_themes );
|
||||||
if ( false !== $inexact_match ) {
|
if ( false !== $inexact_match ) {
|
||||||
$this->msg .= sprintf( " Did you mean '%s'?", $inexact_match );
|
$this->msg .= sprintf( " Did you mean '%s'?", $inexact_match );
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,9 @@ namespace WP_CLI;
|
||||||
use WP_CLI;
|
use WP_CLI;
|
||||||
use Theme_AutoUpdates_Command;
|
use Theme_AutoUpdates_Command;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @template T of \WP_Theme
|
||||||
|
*/
|
||||||
trait ParseThemeNameInput {
|
trait ParseThemeNameInput {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,11 +57,17 @@ trait ParseThemeNameInput {
|
||||||
$theme_version_info = array();
|
$theme_version_info = array();
|
||||||
|
|
||||||
if ( is_multisite() ) {
|
if ( is_multisite() ) {
|
||||||
|
/**
|
||||||
|
* @var array<string, array{enabled: string}>} $site_enabled
|
||||||
|
*/
|
||||||
$site_enabled = get_option( 'allowedthemes' );
|
$site_enabled = get_option( 'allowedthemes' );
|
||||||
if ( empty( $site_enabled ) ) {
|
if ( empty( $site_enabled ) ) {
|
||||||
$site_enabled = array();
|
$site_enabled = array();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array<string, array{enabled: string}>} $network_enabled
|
||||||
|
*/
|
||||||
$network_enabled = get_site_option( 'allowedthemes' );
|
$network_enabled = get_site_option( 'allowedthemes' );
|
||||||
if ( empty( $network_enabled ) ) {
|
if ( empty( $network_enabled ) ) {
|
||||||
$network_enabled = array();
|
$network_enabled = array();
|
||||||
|
@ -169,7 +178,9 @@ trait ParseThemeNameInput {
|
||||||
* @return bool|string
|
* @return bool|string
|
||||||
*/
|
*/
|
||||||
protected function is_theme_version_valid( $slug, $version ) {
|
protected function is_theme_version_valid( $slug, $version ) {
|
||||||
// Get Theme Info.
|
/**
|
||||||
|
* @var \WP_Error|object{name: string, slug: string, version: string, download_link: string} $theme_info
|
||||||
|
*/
|
||||||
$theme_info = themes_api( 'theme_information', array( 'slug' => $slug ) );
|
$theme_info = themes_api( 'theme_information', array( 'slug' => $slug ) );
|
||||||
|
|
||||||
// Return empty string for themes not on WP.org.
|
// Return empty string for themes not on WP.org.
|
||||||
|
@ -184,7 +195,7 @@ trait ParseThemeNameInput {
|
||||||
/**
|
/**
|
||||||
* Get the status for a given theme.
|
* Get the status for a given theme.
|
||||||
*
|
*
|
||||||
* @param WP_Theme $theme Theme to get the status for.
|
* @param T $theme Theme to get the status for.
|
||||||
*
|
*
|
||||||
* @return string Status of the theme.
|
* @return string Status of the theme.
|
||||||
*/
|
*/
|
||||||
|
@ -203,7 +214,7 @@ trait ParseThemeNameInput {
|
||||||
/**
|
/**
|
||||||
* Check whether a given theme is the active theme.
|
* Check whether a given theme is the active theme.
|
||||||
*
|
*
|
||||||
* @param WP_Theme $theme Theme to check.
|
* @param \WP_Theme $theme Theme to check.
|
||||||
*
|
*
|
||||||
* @return bool Whether the provided theme is the active theme.
|
* @return bool Whether the provided theme is the active theme.
|
||||||
*/
|
*/
|
||||||
|
@ -214,7 +225,7 @@ trait ParseThemeNameInput {
|
||||||
/**
|
/**
|
||||||
* Check whether a given theme is the active theme parent.
|
* Check whether a given theme is the active theme parent.
|
||||||
*
|
*
|
||||||
* @param WP_Theme $theme Theme to check.
|
* @param \WP_Theme $theme Theme to check.
|
||||||
*
|
*
|
||||||
* @return bool Whether the provided theme is the active theme.
|
* @return bool Whether the provided theme is the active theme.
|
||||||
*/
|
*/
|
||||||
|
@ -225,9 +236,14 @@ trait ParseThemeNameInput {
|
||||||
/**
|
/**
|
||||||
* Get the available update info.
|
* Get the available update info.
|
||||||
*
|
*
|
||||||
* @return mixed Available update info.
|
* @return object{checked: array<string, string>, response: array<string, array<string, string|null>>, no_update: array<string, object{new_version: string, package: string, requires: string}&\stdClass>} Available update info.
|
||||||
*/
|
*/
|
||||||
protected function get_update_info() {
|
protected function get_update_info() {
|
||||||
return get_site_transient( 'update_themes' );
|
/**
|
||||||
|
* @var object{checked: array<string, string>, response: array<string, array<string, string|null>>, no_update: array<string, object{new_version: string, package: string, requires: string}&\stdClass>} $result
|
||||||
|
*/
|
||||||
|
$result = get_site_transient( 'update_themes' );
|
||||||
|
|
||||||
|
return $result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue